diff -Nru goget-ubuntu-touch-0.13/debian/changelog goget-ubuntu-touch-0.16/debian/changelog --- goget-ubuntu-touch-0.13/debian/changelog 2015-01-30 13:13:25.000000000 +0000 +++ goget-ubuntu-touch-0.16/debian/changelog 2015-01-30 13:13:25.000000000 +0000 @@ -1,3 +1,28 @@ +goget-ubuntu-touch (0.16-0ubuntu1) vivid; urgency=medium + + * ubuntu-device-flash: oem part to allow for dtb overrides. + * debian/control: dep on fakeroot for ubuntu-device-flash. + + -- Sergio Schvezov Thu, 29 Jan 2015 15:23:27 -0300 + +goget-ubuntu-touch (0.15-0ubuntu1) vivid; urgency=medium + + [ Loïc Minier ] + * ubuntu-device-flash: fixed ftdfile -> fdtfile typo. + + [ Sergio Schvezov ] + * ubuntu-device-flash: + - future proof efi support for grub and provisioning boot partition. + - using test instead of load in snappy-commands.txt + + -- Sergio Schvezov Wed, 28 Jan 2015 19:53:33 -0300 + +goget-ubuntu-touch (0.14-0ubuntu1) vivid; urgency=medium + + * Partition sizing multiplier matters for the emulator disk. (LP: #1412495) + + -- Sergio Schvezov Wed, 21 Jan 2015 20:23:14 -0300 + goget-ubuntu-touch (0.13-0ubuntu1) vivid; urgency=medium * Setting a fixed set of ssh host keys to create. diff -Nru goget-ubuntu-touch-0.13/debian/control goget-ubuntu-touch-0.16/debian/control --- goget-ubuntu-touch-0.13/debian/control 2015-01-30 13:13:25.000000000 +0000 +++ goget-ubuntu-touch-0.16/debian/control 2015-01-30 13:13:25.000000000 +0000 @@ -19,6 +19,7 @@ Architecture: any Depends: android-tools-adb, android-tools-fastboot, + fakeroot, kpartx, qemu-user-static, ${misc:Depends}, diff -Nru goget-ubuntu-touch-0.13/diskimage/common.go goget-ubuntu-touch-0.16/diskimage/common.go --- goget-ubuntu-touch-0.13/diskimage/common.go 2015-01-16 04:09:04.000000000 +0000 +++ goget-ubuntu-touch-0.16/diskimage/common.go 2015-01-29 14:26:00.000000000 +0000 @@ -11,6 +11,7 @@ "fmt" "os" "os/exec" + "path/filepath" "strings" ) @@ -52,7 +53,7 @@ type CoreImage interface { Image SystemImage - SetupBoot() error + SetupBoot(OemDescription) error FlashExtra(string) error } @@ -64,6 +65,18 @@ Bootloader string `yaml:"bootloader"` } +type OemDescription struct { + Name string `yaml:"name"` + Version string `yaml:"version"` + Hardware struct { + Dtb string `yaml:"dtb,omitempty"` + } `yaml:"hardware,omitempty"` +} + +func (o OemDescription) InstallPath() string { + return filepath.Join("/oem", o.Name, o.Version) +} + func sectorSize(dev string) (string, error) { out, err := exec.Command("blockdev", "--getss", dev).CombinedOutput() if err != nil { diff -Nru goget-ubuntu-touch-0.13/diskimage/core_grub.go goget-ubuntu-touch-0.16/diskimage/core_grub.go --- goget-ubuntu-touch-0.13/diskimage/core_grub.go 2015-01-19 21:01:20.000000000 +0000 +++ goget-ubuntu-touch-0.16/diskimage/core_grub.go 2015-01-29 14:26:00.000000000 +0000 @@ -114,7 +114,7 @@ //Partition creates a partitioned image from an img func (img *CoreGrubImage) Partition() error { - if err := sysutils.CreateEmptyFile(img.location, img.size); err != nil { + if err := sysutils.CreateEmptyFile(img.location, img.size, sysutils.GB); err != nil { return err } @@ -247,6 +247,19 @@ return filepath.Join(img.baseMount, string(writableDir)) } +// Boot returns the system-boot path +func (img CoreGrubImage) Boot() string { + if img.parts == nil { + panic("img is not setup with partitions") + } + + if img.baseMount == "" { + panic("img not mounted") + } + + return filepath.Join(img.baseMount, string(bootDir)) +} + //System returns the system path func (img CoreGrubImage) System() string { if img.parts == nil { @@ -268,7 +281,7 @@ return img.baseMount } -func (img *CoreGrubImage) SetupBoot() error { +func (img *CoreGrubImage) SetupBoot(oem OemDescription) error { for _, dev := range []string{"dev", "proc", "sys"} { src := filepath.Join("/", dev) dst := filepath.Join(img.System(), dev) @@ -303,6 +316,30 @@ } defer unmount(rootDevPath) + efiDir := filepath.Join(img.System(), "boot", "efi") + if err := os.MkdirAll(efiDir, 0755); err != nil { + return fmt.Errorf("unable to create %s dir: %s", efiDir, err) + } + + if err := bindMount(img.Boot(), efiDir); err != nil { + return err + } + defer unmount(efiDir) + + // create efi layout + efiGrubDir := filepath.Join(img.System(), "boot", "efi", "EFI", "ubuntu", "grub") + if err := os.MkdirAll(efiGrubDir, 0755); err != nil { + return fmt.Errorf("unable to create %s dir: %s", efiGrubDir, err) + } + + bootGrubDir := filepath.Join(img.System(), "boot", "grub") + + if err := bindMount(efiGrubDir, bootGrubDir); err != nil { + return err + } + defer unmount(bootGrubDir) + + // install grub if out, err := exec.Command("chroot", img.System(), "grub-install", "/root_dev").CombinedOutput(); err != nil { return fmt.Errorf("unable to install grub: %s", out) } diff -Nru goget-ubuntu-touch-0.13/diskimage/core_uboot.go goget-ubuntu-touch-0.16/diskimage/core_uboot.go --- goget-ubuntu-touch-0.13/diskimage/core_uboot.go 2015-01-19 21:01:20.000000000 +0000 +++ goget-ubuntu-touch-0.16/diskimage/core_uboot.go 2015-01-29 14:26:00.000000000 +0000 @@ -55,7 +55,7 @@ loadinitrd=load mmc ${mmcdev}:${mmcpart} ${initrd_addr} ${snappy_ab}/${initrd_file}; setenv initrd_size ${filesize} loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdtaddr} ${snappy_ab}/dtbs/${fdtfile} -# standard kernel and initrd file names; NB: ftdfile is set early from bootcmd +# standard kernel and initrd file names; NB: fdtfile is set early from bootcmd kernel_file=vmlinuz initrd_file=initrd.img {{ . }} @@ -72,7 +72,7 @@ snappy_mode=regular # if we're trying a new version, check if stamp file is already there to revert # to other version -snappy_boot=if test "${snappy_mode}" = "try"; then if load mmc ${bootpart} ${loadaddr} ${snappy_stamp} 0; then if test "${snappy_ab}" = "a"; then setenv snappy_ab "b"; else setenv snappy_ab "a"; fi; else fatwrite mmc ${mmcdev}:${mmcpart} 0x0 ${snappy_stamp} 0; fi; fi; run loadfiles; setenv mmcroot /dev/disk/by-label/system-${snappy_ab} ${snappy_cmdline}; run mmcargs; bootz ${loadaddr} ${initrd_addr}:${initrd_size} ${fdtaddr} +snappy_boot=if test "${snappy_mode}" = "try"; then if test -e mmc ${bootpart} ${snappy_stamp}; then if test "${snappy_ab}" = "a"; then setenv snappy_ab "b"; else setenv snappy_ab "a"; fi; else fatwrite mmc ${mmcdev}:${mmcpart} 0x0 ${snappy_stamp} 0; fi; fi; run loadfiles; setenv mmcroot /dev/disk/by-label/system-${snappy_ab} ${snappy_cmdline}; run mmcargs; bootz ${loadaddr} ${initrd_addr}:${initrd_size} ${fdtaddr} ` type FlashInstructions struct { @@ -138,7 +138,7 @@ //Partition creates a partitioned image from an img func (img *CoreUBootImage) Partition() error { - if err := sysutils.CreateEmptyFile(img.location, img.size); err != nil { + if err := sysutils.CreateEmptyFile(img.location, img.size, sysutils.GB); err != nil { return err } @@ -290,7 +290,7 @@ return img.baseMount } -func (img CoreUBootImage) SetupBoot() error { +func (img CoreUBootImage) SetupBoot(oem OemDescription) error { // destinations bootPath := filepath.Join(img.baseMount, string(bootDir)) bootAPath := filepath.Join(bootPath, "a") @@ -313,19 +313,19 @@ return err } - if err := move(hardwareYamlPath, filepath.Join(bootAPath, "hardware.yaml")); err != nil { + if err := copyFile(hardwareYamlPath, filepath.Join(bootAPath, "hardware.yaml")); err != nil { return err } - if err := move(kernelPath, filepath.Join(bootAPath, filepath.Base(kernelPath))); err != nil { + if err := copyFile(kernelPath, filepath.Join(bootAPath, filepath.Base(kernelPath))); err != nil { return err } - if err := move(initrdPath, filepath.Join(bootAPath, filepath.Base(initrdPath))); err != nil { + if err := copyFile(initrdPath, filepath.Join(bootAPath, filepath.Base(initrdPath))); err != nil { return err } - if err := img.provisionDtbs(bootDtbPath); err != nil { + if err := img.provisionDtbs(oem, bootDtbPath); err != nil { return err } @@ -344,13 +344,13 @@ } defer snappySystemFile.Close() - var ftdfile string + var fdtfile string if img.platform != "" { - ftdfile = fmt.Sprintf("ftdfile=%s.dtb", img.platform) + fdtfile = fmt.Sprintf("fdtfile=%s.dtb", img.platform) } t := template.Must(template.New("snappy-system").Parse(snappySystemTemplate)) - t.Execute(snappySystemFile, ftdfile) + t.Execute(snappySystemFile, fdtfile) return nil } @@ -374,7 +374,7 @@ // if a uEnv.txt is provided in the flashtool-assets, use it if _, err := os.Stat(uEnvPath); err == nil { printOut("Adding uEnv.txt to", bootuEnvPath) - if err := move(uEnvPath, bootuEnvPath); err != nil { + if err := copyFile(uEnvPath, bootuEnvPath); err != nil { return err } } else { @@ -384,7 +384,7 @@ return nil } -func (img CoreUBootImage) provisionDtbs(bootDtbPath string) error { +func (img CoreUBootImage) provisionDtbs(oem OemDescription, bootDtbPath string) error { dtbsPath := filepath.Join(img.baseMount, img.hardware.Dtbs) if _, err := os.Stat(dtbsPath); os.IsNotExist(err) { @@ -401,16 +401,23 @@ dtb := filepath.Join(dtbsPath, fmt.Sprintf("%s.dtb", img.platform)) // if there is a specific dtb for the platform, copy it. - if _, err := os.Stat(dtb); err == nil { + // First look in oem and then in device. + if oem.Hardware.Dtb != "" && img.platform != "" { + oemDtb := filepath.Join(img.System(), oem.InstallPath(), oem.Hardware.Dtb) dst := filepath.Join(bootDtbPath, filepath.Base(dtb)) - if err := move(dtb, dst); err != nil { + if err := copyFile(oemDtb, dst); err != nil { + return err + } + } else if _, err := os.Stat(dtb); err == nil { + dst := filepath.Join(bootDtbPath, filepath.Base(dtb)) + if err := copyFile(dtb, dst); err != nil { return err } } else { for _, dtbFi := range dtbFis { src := filepath.Join(dtbsPath, dtbFi.Name()) dst := filepath.Join(bootDtbPath, dtbFi.Name()) - if err := move(src, dst); err != nil { + if err := copyFile(src, dst); err != nil { return err } } @@ -475,7 +482,7 @@ return nil } -func move(src, dst string) error { +func copyFile(src, dst string) error { dstFile, err := os.Create(dst) if err != nil { return err @@ -486,7 +493,6 @@ if err != nil { return err } - defer os.Remove(src) defer srcFile.Close() reader := bufio.NewReader(srcFile) diff -Nru goget-ubuntu-touch-0.13/diskimage/image.go goget-ubuntu-touch-0.16/diskimage/image.go --- goget-ubuntu-touch-0.13/diskimage/image.go 2015-01-12 21:01:31.000000000 +0000 +++ goget-ubuntu-touch-0.16/diskimage/image.go 2015-01-28 22:44:25.000000000 +0000 @@ -155,7 +155,7 @@ panic("creating ext4 on images with multiple parts not supported") } - if err := sysutils.CreateEmptyFile(img.path, img.size); err != nil { + if err := sysutils.CreateEmptyFile(img.path, img.size, sysutils.GiB); err != nil { return err } @@ -164,7 +164,7 @@ //CreateVFat returns a vfat partition for a given file func (img DiskImage) CreateVFat() error { - if err := sysutils.CreateEmptyFile(img.path, img.size); err != nil { + if err := sysutils.CreateEmptyFile(img.path, img.size, sysutils.GiB); err != nil { return err } return exec.Command("mkfs.vfat", "-n", img.label, img.path).Run() diff -Nru goget-ubuntu-touch-0.13/sysutils/utils.go goget-ubuntu-touch-0.16/sysutils/utils.go --- goget-ubuntu-touch-0.13/sysutils/utils.go 2015-01-16 15:05:30.000000000 +0000 +++ goget-ubuntu-touch-0.16/sysutils/utils.go 2015-01-28 22:44:25.000000000 +0000 @@ -27,7 +27,14 @@ "syscall" ) -func CreateEmptyFile(path string, size int64) (err error) { +type unit int64 + +const ( + GiB unit = 1024 + GB unit = 1000 +) + +func CreateEmptyFile(path string, size int64, u unit) (err error) { file, err := os.Create(path) if err != nil { return err @@ -38,7 +45,16 @@ os.Remove(path) } }() - size = size * 1000 * 1000 * 1000 + + switch u { + case GiB: + size = size * 1024 * 1024 * 1024 + case GB: + size = size * 1000 * 1000 * 1000 + default: + panic("improper sizing unit used") + } + if err := file.Truncate(size); err != nil { return errors.New(fmt.Sprintf("Error creating %s of size %d to stage image onto", path, size)) } diff -Nru goget-ubuntu-touch-0.13/ubuntu-device-flash/core.go goget-ubuntu-touch-0.16/ubuntu-device-flash/core.go --- goget-ubuntu-touch-0.13/ubuntu-device-flash/core.go 2015-01-19 21:22:14.000000000 +0000 +++ goget-ubuntu-touch-0.16/ubuntu-device-flash/core.go 2015-01-29 14:26:00.000000000 +0000 @@ -319,15 +319,21 @@ systemPath := img.System() - if err := img.SetupBoot(); err != nil { + if err := coreCmd.install(systemPath); err != nil { return err } - if err := coreCmd.setupKeyboardLayout(systemPath); err != nil { + // check if we installed an oem snap + oem, err := loadOem(systemPath) + if err != nil { return err } - if err := coreCmd.install(systemPath); err != nil { + if err := img.SetupBoot(oem); err != nil { + return err + } + + if err := coreCmd.setupKeyboardLayout(systemPath); err != nil { return err } @@ -494,6 +500,31 @@ return string(pubKey), err } +func loadOem(systemPath string) (oem diskimage.OemDescription, err error) { + pkgs, err := filepath.Glob(filepath.Join(systemPath, "/oem/*/*/meta/package.yaml")) + if err != nil { + return oem, err + } + + // checking for len(pkgs) > 2 due to the 'current' symlink + if len(pkgs) == 0 { + return oem, nil + } else if len(pkgs) > 2 || err != nil { + return oem, errors.New("too many oem packages installed") + } + + f, err := ioutil.ReadFile(pkgs[0]) + if err != nil { + return oem, errors.New("failed to read oem yaml") + } + + if err := goyaml.Unmarshal([]byte(f), &oem); err != nil { + return oem, errors.New("cannot decode oem yaml") + } + + return oem, nil +} + func extractHWDescription(path string) (hw diskimage.HardwareDescription, err error) { // hack to circumvent https://code.google.com/p/go/issues/detail?id=1435 if syscall.Getuid() == 0 {