Message ID | 20210117030707.1251501-4-computersforpeace@gmail.com |
---|---|
State | Superseded, archived |
Delegated to: | Paul Spooren |
Headers | show |
Series | Add support for Chromium OS and Google WiFi | expand |
On Sat Jan 16, 2021 at 5:07 PM HST, Brian Norris wrote: > See the previous patches, which implemented the cros-vbutil > verified-boot payload-packing tool, and extended ptgen for the CrOS > kernel partition type. With these, it's now possible to package kernel + > rootfs to make disk images that can boot a Chrome OS-based system (e.g., > Chromebooks, or even a few AP models). > > gen_image_vboot.sh borrows a bit of structure from gen_image_generic.sh, > but I didn't feel it fit well to try and add new flags to the latter, > given the difference in its FAT kernel packaging and our raw kernel > partition packing. > > Signed-off-by: Brian Norris <computersforpeace@gmail.com> > --- > include/image-commands.mk | 18 ++++++++++ > .../base-files/files/lib/upgrade/common.sh | 4 ++- > scripts/gen_image_vboot.sh | 36 +++++++++++++++++++ > 3 files changed, 57 insertions(+), 1 deletion(-) > create mode 100755 scripts/gen_image_vboot.sh > > diff --git a/include/image-commands.mk b/include/image-commands.mk > index 979eafb15734..f02d8e79fce6 100644 > --- a/include/image-commands.mk > +++ b/include/image-commands.mk > @@ -172,6 +172,24 @@ define Build/fit > @mv $@.new $@ > endef > > +define Build/cros-image > + $(SCRIPT_DIR)/gen_image_vboot.sh \ > + $@ \ > + $(CONFIG_TARGET_KERNEL_PARTSIZE) \ You're passing the kernel size twice here which the script expects <size> <image>. Am I missing something? > + $(CONFIG_TARGET_KERNEL_PARTSIZE) $(IMAGE_KERNEL) \ > + $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) > +endef > + > +# NB: Chrome OS bootloaders replace the '%U' in command lines with the > UUID of > +# the kernel partition it chooses to boot from. This gives a flexible > way to > +# consistently build and sign kernels that always use the subsequent > +# (PARTNROFF=1) partition as their rootfs. > +define Build/cros-vboot > + $(STAGING_DIR_HOST)/bin/cros-vbutil \ > + -k $@ -c "root=PARTUUID=%U/PARTNROFF=1" -o $@.new > + @mv $@.new $@ > +endef > + > define Build/gzip > gzip -f -9n -c $@ $(1) > $@.new > @mv $@.new $@ > diff --git a/package/base-files/files/lib/upgrade/common.sh > b/package/base-files/files/lib/upgrade/common.sh > index c28bae48a15c..a2ee8d1675a6 100644 > --- a/package/base-files/files/lib/upgrade/common.sh > +++ b/package/base-files/files/lib/upgrade/common.sh > @@ -178,9 +178,11 @@ export_bootdevice() { > fi > done > ;; > + PARTUUID=????????-????-????-????-??????????01/PARTNROFF=1 | \ > PARTUUID=????????-????-????-????-??????????02) > uuid="${rootpart#PARTUUID=}" > - uuid="${uuid%02}00" > + uuid="${uuid%/PARTNROFF=1}" > + uuid="${uuid%0?}00" > for disk in $(find /dev -type b); do > set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e > '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') > if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then > diff --git a/scripts/gen_image_vboot.sh b/scripts/gen_image_vboot.sh > new file mode 100755 > index 000000000000..ae267ba3fbb9 > --- /dev/null > +++ b/scripts/gen_image_vboot.sh > @@ -0,0 +1,36 @@ > +#!/usr/bin/env bash > +# Copyright (C) 2021 OpenWrt.org > +set -e -x > +[ $# == 6 ] || { > + echo "SYNTAX: $0 <file> <bootpart size> <kernel size> <kernel image> > <rootfs size> <rootfs image>" > + exit 1 > +} > + > +OUTPUT="$1" > +BOOTPARTSIZE="$2" > +KERNELSIZE="$3" > +KERNELIMAGE="$4" > +ROOTFSSIZE="$5" > +ROOTFSIMAGE="$6" > + > +rm -f "${OUTPUT}" > + > +head=16 > +sect=63 > + > +# create partition table > +set $(ptgen -o "${OUTPUT}" -h $head -s $sect -g -p ${BOOTPARTSIZE}m -T > cros_kernel -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m) > + > +BOOTOFFSET="$(($1 / 512))" > +BOOTSIZE="$2" > +KERNELOFFSET="$(($3 / 512))" > +KERNELSIZE="$4" > +ROOTFSOFFSET="$(($5 / 512))" > +ROOTFSSIZE="$(($6 / 512))" > + > +mkfs.fat -n boot -C "${OUTPUT}.boot" -S 512 "$((BOOTSIZE / 1024))" > + > +dd if="${OUTPUT}.boot" of="${OUTPUT}" bs=512 seek="${BOOTOFFSET}" > conv=notrunc > +rm -f "${OUTPUT}.boot" > +dd if="${KERNELIMAGE}" of="${OUTPUT}" bs=512 seek="${KERNELOFFSET}" > conv=notrunc > +dd if="${ROOTFSIMAGE}" of="${OUTPUT}" bs=512 seek="${ROOTFSOFFSET}" > conv=notrunc > -- > 2.29.2 > > > _______________________________________________ > openwrt-devel mailing list > openwrt-devel@lists.openwrt.org > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Hi Paul, On Sun, Jan 17, 2021 at 2:43 AM Paul Spooren <mail@aparcar.org> wrote: > On Sat Jan 16, 2021 at 5:07 PM HST, Brian Norris wrote: > > See the previous patches, which implemented the cros-vbutil > > verified-boot payload-packing tool, and extended ptgen for the CrOS > > kernel partition type. With these, it's now possible to package kernel + > > rootfs to make disk images that can boot a Chrome OS-based system (e.g., > > Chromebooks, or even a few AP models). > > > > gen_image_vboot.sh borrows a bit of structure from gen_image_generic.sh, > > but I didn't feel it fit well to try and add new flags to the latter, > > given the difference in its FAT kernel packaging and our raw kernel > > partition packing. > > > > Signed-off-by: Brian Norris <computersforpeace@gmail.com> > > --- > > include/image-commands.mk | 18 ++++++++++ > > .../base-files/files/lib/upgrade/common.sh | 4 ++- > > scripts/gen_image_vboot.sh | 36 +++++++++++++++++++ > > 3 files changed, 57 insertions(+), 1 deletion(-) > > create mode 100755 scripts/gen_image_vboot.sh > > > > diff --git a/include/image-commands.mk b/include/image-commands.mk > > index 979eafb15734..f02d8e79fce6 100644 > > --- a/include/image-commands.mk > > +++ b/include/image-commands.mk > > @@ -172,6 +172,24 @@ define Build/fit > > @mv $@.new $@ > > endef > > > > +define Build/cros-image > > + $(SCRIPT_DIR)/gen_image_vboot.sh \ > > + $@ \ > > + $(CONFIG_TARGET_KERNEL_PARTSIZE) \ > > You're passing the kernel size twice here which the script expects > <size> <image>. Am I missing something? From the error/help text: echo "SYNTAX: $0 <file> <bootpart size> <kernel size> <kernel image> <rootfs size> <rootfs image>" It's a bit awkward, but for the first partition, it's only asking for a <size>. I haven't fully fleshed it out yet, but this first partition is a spare FAT partition, for use in sysupgrade. I believe other systems reuse the kernel partition (which tends to be either FAT or ext4), but because Chrome OS systems use a signed blob (and not a proper filesystem) for their kernel partitions, I needed to create an extra partition, with no special data in it. Also, I don't really have a separate Kconfig option for defining the FAT partition size -- I just reused the kernel partition size. I'm open to suggestions on this, but the current code is written as intended. I'm not very familiar with OpenWRT image-construction best practices (e.g., adding more Kconfig parameters?). Thanks, Brian
On So, Jan 17, 2021 at 09:20, Brian Norris <computersforpeace@gmail.com> wrote: > Hi Paul, > > On Sun, Jan 17, 2021 at 2:43 AM Paul Spooren <mail@aparcar.org> wrote: >> On Sat Jan 16, 2021 at 5:07 PM HST, Brian Norris wrote: >> > See the previous patches, which implemented the cros-vbutil >> > verified-boot payload-packing tool, and extended ptgen for the >> CrOS >> > kernel partition type. With these, it's now possible to package >> kernel + >> > rootfs to make disk images that can boot a Chrome OS-based system >> (e.g., >> > Chromebooks, or even a few AP models). >> > >> > gen_image_vboot.sh borrows a bit of structure from >> gen_image_generic.sh, >> > but I didn't feel it fit well to try and add new flags to the >> latter, >> > given the difference in its FAT kernel packaging and our raw >> kernel >> > partition packing. >> > >> > Signed-off-by: Brian Norris <computersforpeace@gmail.com> >> > --- >> > include/image-commands.mk | 18 ++++++++++ >> > .../base-files/files/lib/upgrade/common.sh | 4 ++- >> > scripts/gen_image_vboot.sh | 36 +++++++++++++++++++ >> > 3 files changed, 57 insertions(+), 1 deletion(-) >> > create mode 100755 scripts/gen_image_vboot.sh >> > >> > diff --git a/include/image-commands.mk b/include/image-commands.mk >> > index 979eafb15734..f02d8e79fce6 100644 >> > --- a/include/image-commands.mk >> > +++ b/include/image-commands.mk >> > @@ -172,6 +172,24 @@ define Build/fit >> > @mv $@.new $@ >> > endef >> > >> > +define Build/cros-image >> > + $(SCRIPT_DIR)/gen_image_vboot.sh \ >> > + $@ \ >> > + $(CONFIG_TARGET_KERNEL_PARTSIZE) \ >> >> You're passing the kernel size twice here which the script expects >> <size> <image>. Am I missing something? > > From the error/help text: > > echo "SYNTAX: $0 <file> <bootpart size> <kernel size> <kernel > image> <rootfs size> <rootfs image>" > > It's a bit awkward, but for the first partition, it's only asking for > a <size>. I haven't fully fleshed it out yet, but this first partition > is a spare FAT partition, for use in sysupgrade. I believe other > systems reuse the kernel partition (which tends to be either FAT or > ext4), but because Chrome OS systems use a signed blob (and not a > proper filesystem) for their kernel partitions, I needed to create an > extra partition, with no special data in it. > > Also, I don't really have a separate Kconfig option for defining the > FAT partition size -- I just reused the kernel partition size. > > I'm open to suggestions on this, but the current code is written as > intended. I'm not very familiar with OpenWRT image-construction best > practices (e.g., adding more Kconfig parameters?). Sorry for the confusion, within a git rebase the file wasn't updated and lacked that parameter, causing error message on execution. It works fine now. I have no idea for a better name, if you suspect other devices could use this functionality as well that use other sizes we should design it more flexible. > Thanks, > Brian
diff --git a/include/image-commands.mk b/include/image-commands.mk index 979eafb15734..f02d8e79fce6 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -172,6 +172,24 @@ define Build/fit @mv $@.new $@ endef +define Build/cros-image + $(SCRIPT_DIR)/gen_image_vboot.sh \ + $@ \ + $(CONFIG_TARGET_KERNEL_PARTSIZE) \ + $(CONFIG_TARGET_KERNEL_PARTSIZE) $(IMAGE_KERNEL) \ + $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) +endef + +# NB: Chrome OS bootloaders replace the '%U' in command lines with the UUID of +# the kernel partition it chooses to boot from. This gives a flexible way to +# consistently build and sign kernels that always use the subsequent +# (PARTNROFF=1) partition as their rootfs. +define Build/cros-vboot + $(STAGING_DIR_HOST)/bin/cros-vbutil \ + -k $@ -c "root=PARTUUID=%U/PARTNROFF=1" -o $@.new + @mv $@.new $@ +endef + define Build/gzip gzip -f -9n -c $@ $(1) > $@.new @mv $@.new $@ diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index c28bae48a15c..a2ee8d1675a6 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -178,9 +178,11 @@ export_bootdevice() { fi done ;; + PARTUUID=????????-????-????-????-??????????01/PARTNROFF=1 | \ PARTUUID=????????-????-????-????-??????????02) uuid="${rootpart#PARTUUID=}" - uuid="${uuid%02}00" + uuid="${uuid%/PARTNROFF=1}" + uuid="${uuid%0?}00" for disk in $(find /dev -type b); do set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then diff --git a/scripts/gen_image_vboot.sh b/scripts/gen_image_vboot.sh new file mode 100755 index 000000000000..ae267ba3fbb9 --- /dev/null +++ b/scripts/gen_image_vboot.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Copyright (C) 2021 OpenWrt.org +set -e -x +[ $# == 6 ] || { + echo "SYNTAX: $0 <file> <bootpart size> <kernel size> <kernel image> <rootfs size> <rootfs image>" + exit 1 +} + +OUTPUT="$1" +BOOTPARTSIZE="$2" +KERNELSIZE="$3" +KERNELIMAGE="$4" +ROOTFSSIZE="$5" +ROOTFSIMAGE="$6" + +rm -f "${OUTPUT}" + +head=16 +sect=63 + +# create partition table +set $(ptgen -o "${OUTPUT}" -h $head -s $sect -g -p ${BOOTPARTSIZE}m -T cros_kernel -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m) + +BOOTOFFSET="$(($1 / 512))" +BOOTSIZE="$2" +KERNELOFFSET="$(($3 / 512))" +KERNELSIZE="$4" +ROOTFSOFFSET="$(($5 / 512))" +ROOTFSSIZE="$(($6 / 512))" + +mkfs.fat -n boot -C "${OUTPUT}.boot" -S 512 "$((BOOTSIZE / 1024))" + +dd if="${OUTPUT}.boot" of="${OUTPUT}" bs=512 seek="${BOOTOFFSET}" conv=notrunc +rm -f "${OUTPUT}.boot" +dd if="${KERNELIMAGE}" of="${OUTPUT}" bs=512 seek="${KERNELOFFSET}" conv=notrunc +dd if="${ROOTFSIMAGE}" of="${OUTPUT}" bs=512 seek="${ROOTFSOFFSET}" conv=notrunc
See the previous patches, which implemented the cros-vbutil verified-boot payload-packing tool, and extended ptgen for the CrOS kernel partition type. With these, it's now possible to package kernel + rootfs to make disk images that can boot a Chrome OS-based system (e.g., Chromebooks, or even a few AP models). gen_image_vboot.sh borrows a bit of structure from gen_image_generic.sh, but I didn't feel it fit well to try and add new flags to the latter, given the difference in its FAT kernel packaging and our raw kernel partition packing. Signed-off-by: Brian Norris <computersforpeace@gmail.com> --- include/image-commands.mk | 18 ++++++++++ .../base-files/files/lib/upgrade/common.sh | 4 ++- scripts/gen_image_vboot.sh | 36 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100755 scripts/gen_image_vboot.sh