diff --git a/go.mod b/go.mod index 55232da..419c7eb 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,5 @@ require ( github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e github.com/klauspost/compress v1.13.3 // indirect github.com/klauspost/pgzip v1.2.5 - github.com/pelletier/go-toml/v2 v2.0.0-beta.3 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c ) diff --git a/go.sum b/go.sum index b1b114c..010466a 100644 --- a/go.sum +++ b/go.sum @@ -1,21 +1,9 @@ github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RSSp2Om9lubZpiMgVbvn39bsUmW9U5h0twqc= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/klauspost/compress v1.13.3 h1:BtAvtV1+h0YwSVwWoYXMREPpYu9VzTJ9QDI1TEg/iQQ= github.com/klauspost/compress v1.13.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/pelletier/go-toml/v2 v2.0.0-beta.3 h1:PNCTU4naEJ8mKal97P3A2qDU74QRQGlv4FXiL1XDqi4= -github.com/pelletier/go-toml/v2 v2.0.0-beta.3/go.mod h1:aNseLYu/uKskg0zpr/kbr2z8yGuWtotWf/0BpGIAL2Y= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU= -github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 0251319..484ba50 100644 --- a/main.go +++ b/main.go @@ -29,14 +29,19 @@ func timeFunc(start time.Time, name string) { } func main() { - devinfo, err := deviceinfo.ReadDeviceinfo() - if err != nil { + deviceinfoFile := "/etc/deviceinfo" + if !exists(deviceinfoFile) { log.Print("NOTE: deviceinfo (from device package) not installed yet, " + "not building the initramfs now (it should get built later " + "automatically.)") return } + devinfo, err := deviceinfo.ReadDeviceinfo(deviceinfoFile) + if err != nil { + log.Fatal(err) + } + outDir := flag.String("d", "/boot", "Directory to output initfs(-extra) and other boot files") flag.Parse() diff --git a/pkgs/deviceinfo/deviceinfo.go b/pkgs/deviceinfo/deviceinfo.go index b26c592..3889659 100644 --- a/pkgs/deviceinfo/deviceinfo.go +++ b/pkgs/deviceinfo/deviceinfo.go @@ -4,59 +4,123 @@ package deviceinfo import ( - "errors" - toml "github.com/pelletier/go-toml/v2" + "bufio" + "fmt" + "io" + "log" "os" + "reflect" + "strings" ) -// Note: fields must be exported (start with capital letter) -// https://github.com/BurntSushi/toml/issues/121 type DeviceInfo struct { - AppendDtb string `toml:"deviceinfo_append_dtb"` - Arch string `toml:"deviceinfo_arch"` - BootimgAppendSEAndroidEnforce string `toml:"deviceinfo_bootimg_append_seandroidenforce"` - BootimgBlobpack string `toml:"deviceinfo_bootimg_blobpack"` - BootimgDtbSecond string `toml:"deviceinfo_bootimg_dtb_second"` - BootimgMtkMkimage string `toml:"deviceinfo_bootimg_mtk_mkimage"` - BootimgPxa string `toml:"deviceinfo_bootimg_pxa"` - BootimgQcdt string `toml:"deviceinfo_bootimg_qcdt"` - Dtb string `toml:"deviceinfo_dtb"` - FlashKernelOnUpdate string `toml:"deviceinfo_flash_kernel_on_update"` - FlashOffsetBase string `toml:"deviceinfo_flash_offset_base"` - FlashOffsetKernel string `toml:"deviceinfo_flash_offset_kernel"` - FlashOffsetRamdisk string `toml:"deviceinfo_flash_offset_ramdisk"` - FlashOffsetSecond string `toml:"deviceinfo_flash_offset_second"` - FlashOffsetTags string `toml:"deviceinfo_flash_offset_tags"` - FlashPagesize string `toml:"deviceinfo_flash_pagesize"` - GenerateBootimg string `toml:"deviceinfo_generate_bootimg"` - GenerateLegacyUbootInitfs string `toml:"deviceinfo_generate_legacy_uboot_initfs"` - InitfsCompression string `toml:"deviceinfo_initfs_compression"` - KernelCmdline string `toml:"deviceinfo_kernel_cmdline"` - LegacyUbootLoadAddress string `toml:"deviceinfo_legacy_uboot_load_address"` - MesaDriver string `toml:"deviceinfo_mesa_driver"` - MkinitfsPostprocess string `toml:"deviceinfo_mkinitfs_postprocess"` - ModulesInitfs string `toml:"deviceinfo_modules_initfs"` + AppendDtb string + Arch string + BootimgAppendSEAndroidEnforce string + BootimgBlobpack string + BootimgDtbSecond string + BootimgMtkMkimage string + BootimgPxa string + BootimgQcdt string + Dtb string + FlashKernelOnUpdate string + FlashOffsetBase string + FlashOffsetKernel string + FlashOffsetRamdisk string + FlashOffsetSecond string + FlashOffsetTags string + FlashPagesize string + GenerateBootimg string + GenerateLegacyUbootInitfs string + InitfsCompression string + KernelCmdline string + LegacyUbootLoadAddress string + MesaDriver string + MkinitfsPostprocess string + ModulesInitfs string } -func ReadDeviceinfo() (DeviceInfo, error) { - file := "/etc/deviceinfo" +func ReadDeviceinfo(file string) (DeviceInfo, error) { var deviceinfo DeviceInfo - _, err := os.Stat(file) - if err != nil { - return deviceinfo, errors.New("Unable to find deviceinfo: " + file) - } - fd, err := os.Open(file) if err != nil { return deviceinfo, err } defer fd.Close() - // contents,_ := toml.LoadFile(file) - decoder := toml.NewDecoder(fd) - if err := decoder.Decode(&deviceinfo); err != nil { + + if err := unmarshal(fd, &deviceinfo); err != nil { return deviceinfo, err } return deviceinfo, nil } + +// Unmarshals a deviceinfo into a DeviceInfo struct +func unmarshal(r io.Reader, devinfo *DeviceInfo) error { + s := bufio.NewScanner(r) + for s.Scan() { + line := s.Text() + if strings.HasPrefix(line, "#") { + continue + } + + // line isn't setting anything, so just ignore it + if !strings.Contains(line, "=") { + continue + } + + // sometimes line has a comment at the end after setting an option + line = strings.SplitN(line, "#", 2)[0] + line = strings.TrimSpace(line) + + // must support having '=' in the value (e.g. kernel cmdline) + parts := strings.SplitN(line, "=", 2) + if len(parts) != 2 { + return fmt.Errorf("error parsing deviceinfo line, invalid format: %s", line) + } + + name, val := parts[0], parts[1] + val = strings.ReplaceAll(val, "\"", "") + + if name == "deviceinfo_format_version" && val != "0" { + return fmt.Errorf("deviceinfo format version %q is not supported", val) + } + + fieldName := nameToField(name) + + if fieldName == "" { + return fmt.Errorf("error parsing deviceinfo line, invalid format: %s", line) + } + + field := reflect.ValueOf(devinfo).Elem().FieldByName(fieldName) + if !field.IsValid() { + // an option that meets the deviceinfo "specification", but isn't + // one we care about in this module + continue + } + field.SetString(val) + } + if err := s.Err(); err != nil { + log.Print("unable to parse deviceinfo: ", err) + return err + } + + return nil +} + +// Convert string into the string format used for DeviceInfo fields. +// Note: does not test that the resulting field name is a valid field in the +// DeviceInfo struct! +func nameToField(name string) string { + var field string + parts := strings.Split(name, "_") + for _, p := range parts { + if p == "deviceinfo" { + continue + } + field = field + strings.Title(p) + } + + return field +}