diff --git a/board/common/Config.in b/board/common/Config.in index 68e5628e..9131fab8 100644 --- a/board/common/Config.in +++ b/board/common/Config.in @@ -1,3 +1,23 @@ +comment "Image Signing" + +choice + prompt "Signing key source" + default SIGN_SRC_DIR + +config SIGN_SRC_DIR + bool "Directory" + +config SIGN_SRC_PKCS11 + bool "PKCS#11 URL" + +endchoice + +config SIGN_KEY + string "Signing key" + default "$(BR2_EXTERNAL_INFIX_PATH)/board/common/dev-key" if SIGN_SRC_DIR + +comment "Development Images" + menuconfig FIT_IMAGE bool "Build FIT image" diff --git a/board/common/common.mk b/board/common/common.mk new file mode 100644 index 00000000..7086e663 --- /dev/null +++ b/board/common/common.mk @@ -0,0 +1 @@ +include $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/uboot.mk diff --git a/board/common/uboot/env.dtsi b/board/common/uboot/env.dtsi new file mode 100644 index 00000000..200c2695 --- /dev/null +++ b/board/common/uboot/env.dtsi @@ -0,0 +1,18 @@ +/ { + config { + env: environment { + }; + }; +}; + +&env { + vendor = "infix"; + bootdelay = "-2"; + bootcmd = "run ixboot"; + + ixboot = /incbin/("scripts/ixboot.sh"); + prepare_aux = /incbin/("scripts/prepare_aux_mmc.sh"); + prepare_primary = /incbin/("scripts/prepare_mmc.sh"); + prepare_secondary = /incbin/("scripts/prepare_mmc.sh"); + prepare_net = /incbin/("scripts/prepare_net.sh"); +}; diff --git a/board/common/uboot/key-dummy.its b/board/common/uboot/key-dummy.its new file mode 100644 index 00000000..69d45653 --- /dev/null +++ b/board/common/uboot/key-dummy.its @@ -0,0 +1,24 @@ +/dts-v1/; + +/ { + description = "dummy to convert keys in PEM format for inclusion in U-Boot's control DT"; + creator = "infix"; + #address-cells = <0x1>; + + images { + ramdisk { + description = "null"; + type = "ramdisk"; + os = "linux"; + compression = "none"; + data = /incbin/("/dev/null"); + + signature-1 { + algo = "sha256,rsa4096"; + key-name-hint = "infix"; + }; + }; + }; + + configurations {}; +}; diff --git a/board/common/uboot/scripts/ixboot.sh b/board/common/uboot/scripts/ixboot.sh new file mode 100644 index 00000000..9c8adc6b --- /dev/null +++ b/board/common/uboot/scripts/ixboot.sh @@ -0,0 +1,43 @@ +run prepare_aux +test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "primary secondary net" +echo "Boot order: ${BOOT_ORDER}" + +if test -n "${DEBUG}"; then + setenv bootargs_log "debug" +else + setenv bootargs_log "loglevel=4" +fi + +for s in "${BOOT_ORDER}"; do + setenv slot "${s}" + + echo "${slot}: Preparing..." + setenv prepared + + if test "${slot}" = "primary"; then + run prepare_primary + elif test "${slot}" = "secondary"; then + run prepare_secondary + elif test "${slot}" = "net"; then + run prepare_net + fi + + if test "${prepared}" = "ok"; then + echo "${slot}: Validating..." + if iminfo ${ramdisk_addr_r}; then + echo "${slot}: Booting..." + setenv bootargs_rauc "rauc.slot=${slot}" + blkmap create boot + blkmap map boot 0 ${sqblkcnt} mem ${sqaddr} + source ${ramdisk_addr_r}:boot-script + blkmap destroy boot + echo "${slot}: ERROR: Boot failed" + else + echo "${slot}: ERROR: Validation failed" + fi + else + echo "${slot}: ERROR: Unable to use slot" + fi +done + +reset diff --git a/board/common/uboot/scripts/ixload.sh b/board/common/uboot/scripts/ixload.sh new file mode 100644 index 00000000..ea15f530 --- /dev/null +++ b/board/common/uboot/scripts/ixload.sh @@ -0,0 +1,14 @@ +${devtype} dev ${devnum} +${devtype} read ${ramdisk_addr_r} ${devoffs} 0x10 + +fdt addr ${ramdisk_addr_r} +fdt get value squashaddr /images/ramdisk data-position +fdt get value squashsize /images/ramdisk data-size + +setexpr blkcnt ${squashaddr} + ${squashsize} +setexpr blkcnt ${blkcnt} + 0x1ff +setexpr blkcnt ${blkcnt} / 0x200 + +${devtype} read ${ramdisk_addr_r} ${devoffs} ${blkcnt} + + diff --git a/board/common/uboot/scripts/prepare_aux_mmc.sh b/board/common/uboot/scripts/prepare_aux_mmc.sh new file mode 100644 index 00000000..4fcbc38d --- /dev/null +++ b/board/common/uboot/scripts/prepare_aux_mmc.sh @@ -0,0 +1,5 @@ +if part number mmc 0 aux auxpart; then + if load mmc 0:${auxpart} ${loadaddr} /uboot.env; then + env import -b ${loadaddr} ${filesize} BOOT_ORDER DEBUG + fi +fi diff --git a/board/common/uboot/scripts/prepare_mmc.sh b/board/common/uboot/scripts/prepare_mmc.sh new file mode 100644 index 00000000..f6929a89 --- /dev/null +++ b/board/common/uboot/scripts/prepare_mmc.sh @@ -0,0 +1,28 @@ +setenv devtype mmc +setenv devnum 0 +part start ${devtype} ${devnum} ${slot} devoffs + +${devtype} dev ${devnum} +${devtype} read ${ramdisk_addr_r} ${devoffs} 0x10 + +setenv bootargs_root "root=/dev/dm-0 dm-mod.create=\"rootfs,,0,ro,0" + +setenv old_fdt_addr ${fdt_addr} +if fdt addr ${ramdisk_addr_r}; then + fdt get value sqoffs /images/rootfs data-position + fdt get value sqsize /images/rootfs data-size + fdt addr ${old_fdt_addr} + + setexpr sqaddr ${ramdisk_addr_r} + ${sqoffs} + setexpr sqblknr ${sqoffs} / 0x200 + setexpr sqblkcnt ${sqsize} / 0x200 + setexpr fitblkcnt ${sqblknr} + ${sqblkcnt} + + if ${devtype} read ${ramdisk_addr_r} ${devoffs} ${fitblkcnt}; then + setexpr decsqblkcnt fmt %u ${sqblkcnt} + setexpr decsqblknr fmt %u ${sqblknr} + setenv bootargs_root "${bootargs_root} ${decsqblkcnt} linear PARTLABEL=${slot} ${decsqblknr}\"" + setenv ramdisk "-" + setenv prepared ok + fi +fi diff --git a/board/common/uboot/scripts/prepare_net.sh b/board/common/uboot/scripts/prepare_net.sh new file mode 100644 index 00000000..51025ed8 --- /dev/null +++ b/board/common/uboot/scripts/prepare_net.sh @@ -0,0 +1,20 @@ +if dhcp ${ramdisk_addr_r}; then + + setexpr rdsize ${filesize} + 0x3ff + + setenv old_fdt_addr ${fdt_addr} + if fdt addr ${ramdisk_addr_r}; then + fdt get value sqoffs /images/rootfs data-position + fdt get value sqsize /images/rootfs data-size + fdt addr ${old_fdt_addr} + + setexpr sqaddr ${ramdisk_addr_r} + ${sqoffs} + setexpr sqblknr ${sqoffs} / 0x200 + setexpr sqblkcnt ${sqsize} / 0x200 + setexpr rdsize ${sqsize} / 0x400 + + setenv bootargs_root "root=/dev/ram0 ramdisk_size=0x${rdsize}" + setenv ramdisk "${sqaddr}:${sqsize}" + setenv prepared ok + fi +fi diff --git a/board/common/uboot/uboot.mk b/board/common/uboot/uboot.mk new file mode 100644 index 00000000..35adf6bb --- /dev/null +++ b/board/common/uboot/uboot.mk @@ -0,0 +1,38 @@ +# This is a bit awkward. If you know about a more straight forward way +# of doing this, please simplify. +# +# U-Boot needs the public part of the signing key to be preprocessed +# and then inserted into its control DT. mkimage(1) can perform this +# conversion, but only as a side-effect of building/signing an FIT +# image. Since we might not always be doing that, e.g. when only +# building a hardware specific bootloader, we build a dummy FIT just +# to get the key information into a DTB, which we then convert back to +# a .dtsi and install in the U-Boot build tree. This will then be +# built in to the final U-Boot image's control DT via the +# CONFIG_DEVICE_TREE_INCLUDES option (see extras.config). +define UBOOT_PRE_BUILD_INSTALL_KEY + @echo "Installing Infix signing key ($(SIGN_KEY))" + $(HOST_DIR)/bin/dtc <(echo '/dts-v1/; / { signature {}; };') >$(@D)/infix-key.dtb + $(HOST_DIR)/bin/mkimage \ + -k $(SIGN_KEY) \ + -f $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/key-dummy.its \ + -K $(@D)/infix-key.dtb \ + $(if $(SIGN_SRC_PKCS11),-N pkcs11) \ + -r \ + $(@D)/key-dummy.itb + rm $(@D)/key-dummy.itb + $(HOST_DIR)/bin/dtc -I dtb -O dts \ + <$(@D)/infix-key.dtb \ + | sed -e 's:/dts-v[0-9]\+/;::' >$(@D)/arch/$(UBOOT_ARCH)/dts/infix-key.dtsi + rm $(@D)/infix-key.dtb +endef +UBOOT_PRE_BUILD_HOOKS += UBOOT_PRE_BUILD_INSTALL_KEY + +define UBOOT_PRE_BUILD_INSTALL_ENV + @echo "Installing Infix environment extensions" + cp -f $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/env.dtsi \ + $(@D)/arch/$(UBOOT_ARCH)/dts/infix-env.dtsi + cp -af $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/scripts \ + $(@D)/arch/$(UBOOT_ARCH)/dts/ +endef +UBOOT_PRE_BUILD_HOOKS += UBOOT_PRE_BUILD_INSTALL_ENV diff --git a/external.mk b/external.mk index 37bb26f2..b9a7cd5d 100644 --- a/external.mk +++ b/external.mk @@ -1,4 +1,5 @@ include $(sort $(wildcard $(BR2_EXTERNAL_INFIX_PATH)/package/*/*.mk)) +include $(BR2_EXTERNAL_INFIX_PATH)/board/common/common.mk -include $(BR2_EXTERNAL_INFIX_PATH)/board/$(patsubst "%",%,$(BR2_ARCH))/board.mk .PHONY: local.mk