mirror of https://github.com/ericonr/sbctl.git
116 lines
3.3 KiB
Go
116 lines
3.3 KiB
Go
package sbctl
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
type Bundle struct {
|
|
Output string `json:"output"`
|
|
IntelMicrocode string `json:"intel_microcode"`
|
|
AMDMicrocode string `json:"amd_microcode"`
|
|
KernelImage string `json:"kernel_image"`
|
|
Initramfs string `json:"initramfs"`
|
|
Cmdline string `json:"cmdline"`
|
|
Splash string `json:"splash"`
|
|
OSRelease string `json:"os_release"`
|
|
EFIStub string `json:"efi_stub"`
|
|
ESP string `json:"esp"`
|
|
}
|
|
|
|
type Bundles map[string]*Bundle
|
|
|
|
var BundleDBPath = filepath.Join(DatabasePath, "bundles.db")
|
|
|
|
func ReadBundleDatabase(dbpath string) Bundles {
|
|
bundles := make(Bundles)
|
|
os.MkdirAll(DatabasePath, os.ModePerm)
|
|
if _, err := os.Stat(BundleDBPath); os.IsNotExist(err) {
|
|
file, err := os.Create(BundleDBPath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
file.Close()
|
|
}
|
|
f, err := ioutil.ReadFile(dbpath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
json.Unmarshal(f, &bundles)
|
|
return bundles
|
|
}
|
|
|
|
func WriteBundleDatabase(dbpath string, bundles Bundles) {
|
|
data, err := json.MarshalIndent(bundles, "", " ")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
err = ioutil.WriteFile(dbpath, data, 0644)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func NewBundle() *Bundle {
|
|
esp := GetESP()
|
|
return &Bundle{
|
|
Output: "",
|
|
IntelMicrocode: "",
|
|
AMDMicrocode: "",
|
|
KernelImage: filepath.Join(esp, "vmlinuz-linux"),
|
|
Initramfs: filepath.Join(esp, "initramfs-linux.img"),
|
|
Cmdline: "/proc/cmdline",
|
|
Splash: "",
|
|
OSRelease: "/usr/lib/os-release",
|
|
EFIStub: "/usr/lib/systemd/boot/efi/linuxx64.efi.stub",
|
|
ESP: esp,
|
|
}
|
|
}
|
|
|
|
func GenerateBundle(bundle *Bundle) bool {
|
|
args := ""
|
|
args += fmt.Sprintf("--add-section .osrel=%s --change-section-vma .osrel=0x20000 ", bundle.OSRelease)
|
|
args += fmt.Sprintf("--add-section .cmdline=%s --change-section-vma .cmdline=0x30000 ", bundle.Cmdline)
|
|
if bundle.Splash != "" {
|
|
args += fmt.Sprintf("--add-section .splash=%s --change-section-vma .splash=0x40000 ", bundle.Splash)
|
|
}
|
|
args += fmt.Sprintf("--add-section .linux=%s --change-section-vma .linux=0x2000000 ", bundle.KernelImage)
|
|
args += fmt.Sprintf("--add-section .initrd=%s --change-section-vma .initrd=0x3000000 ", bundle.Initramfs)
|
|
args += fmt.Sprintf("%s %s", bundle.EFIStub, bundle.Output)
|
|
cmd := exec.Command("objcopy", strings.Split(args, " ")...)
|
|
cmd.Stdout = os.Stdout
|
|
if err := cmd.Run(); err != nil {
|
|
if exitError, ok := err.(*exec.ExitError); ok {
|
|
return exitError.ExitCode() == 0
|
|
}
|
|
}
|
|
msg.Printf("Wrote EFI bundle %s", bundle.Output)
|
|
return true
|
|
}
|
|
|
|
func FormatBundle(name string, bundle *Bundle) {
|
|
msg.Printf("Bundle: %s", name)
|
|
if bundle.AMDMicrocode != "" {
|
|
msg2.Printf("AMD Microcode: %s", bundle.AMDMicrocode)
|
|
}
|
|
if bundle.IntelMicrocode != "" {
|
|
msg2.Printf("Intel Microcode: %s", bundle.IntelMicrocode)
|
|
}
|
|
msg2.Printf("Kernel Image: %s", bundle.KernelImage)
|
|
msg2.Printf("Initramfs Image: %s", bundle.Initramfs)
|
|
msg2.Printf("Cmdline: %s", bundle.Cmdline)
|
|
msg2.Printf("OS Relase: %s", bundle.OSRelease)
|
|
msg2.Printf("EFI Stub Image: %s", bundle.EFIStub)
|
|
msg2.Printf("ESP Location: %s", bundle.ESP)
|
|
if bundle.Splash != "" {
|
|
msg2.Printf("Splash Image: %s", bundle.Splash)
|
|
}
|
|
msg2.Printf("Output: %s", bundle.Output)
|
|
}
|