[U-Boot] [PATCH V2 0/5] add i.MX8 container loading support

The V1 version: https://patchwork.ozlabs.org/cover/1096334/
This patchset is to support i.MX8 container loading from SPL, i.MX8 AHAB secure boot not support FIT image, so we need to use container image.
Currently still use a fixed offset for the 2nd container(u-boot.cnt), future patches will drop this fixed offset and use dynamaic offset according to the size of 1st container for spl. Only MMC is supported now, future patches will also support SPI/NOR/NAND following similar style as mmc part, if the mmc part is ok.
Based on the comments in https://patchwork.ozlabs.org/patch/1096336/ So I think we have agreed the approach, the only comments that not addressed from Lukasz is add doc for the container format. The detailed format could be found in RM https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf Chapter 5.9.4 High Level Container Format
CI: https://travis-ci.org/MrVan/u-boot/builds/547161366
V2: Drop cleanup Makefile since V1, that patch is not correct. Rebased on master
Peng Fan (5): spl: Add function to get u-boot raw sector imx8: support parsing i.MX8 Container file spl: mmc: support loading i.MX container format file imx: add container target imx8qxp_mek: switch to use container image
Makefile | 8 ++ arch/arm/include/asm/arch-imx8/image.h | 56 +++++++++++ arch/arm/mach-imx/Makefile | 14 ++- arch/arm/mach-imx/imx8/Kconfig | 13 +++ arch/arm/mach-imx/imx8/Makefile | 4 + arch/arm/mach-imx/imx8/parse-container.c | 120 ++++++++++++++++++++++++ board/freescale/imx8qxp_mek/README | 4 +- board/freescale/imx8qxp_mek/uboot-container.cfg | 13 +++ common/spl/spl_mmc.c | 21 ++++- configs/imx8qxp_mek_defconfig | 5 +- include/spl.h | 12 +++ 11 files changed, 260 insertions(+), 10 deletions(-) create mode 100644 arch/arm/include/asm/arch-imx8/image.h create mode 100644 arch/arm/mach-imx/imx8/parse-container.c create mode 100644 board/freescale/imx8qxp_mek/uboot-container.cfg

Add a weak function spl_mmc_get_uboot_raw_sector to get u-boot raw sector. At default it returns CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR. Users can overwrite it to return customized offset.
This is to support i.MX8 specific image type container image type.
Cc: Tien Fong Chee tien.fong.chee@intel.com Cc: Peng Fan peng.fan@nxp.com Cc: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com Cc: York Sun york.sun@nxp.com Cc: Marek Vasut marex@denx.de Cc: Alex Kiernan alex.kiernan@gmail.com Signed-off-by: Peng Fan peng.fan@nxp.com --- common/spl/spl_mmc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 324d91c884..bf53a1dadf 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -149,6 +149,13 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) return 0; }
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR +unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc) +{ + return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR; +} +#endif + #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, struct mmc *mmc, int partition) @@ -181,7 +188,7 @@ static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR return mmc_load_image_raw_sector(spl_image, mmc, - info.start + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); + info.start + spl_mmc_get_uboot_raw_sector(mmc)); #else return mmc_load_image_raw_sector(spl_image, mmc, info.start); #endif @@ -366,7 +373,7 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, #endif #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR err = mmc_load_image_raw_sector(spl_image, mmc, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); + spl_mmc_get_uboot_raw_sector(mmc)); if (!err) return err; #endif

Add parsing i.MX8 Container file support, this is to let SPL could load images in a container file to destination address.
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/include/asm/arch-imx8/image.h | 56 +++++++++++++++ arch/arm/mach-imx/imx8/Kconfig | 6 ++ arch/arm/mach-imx/imx8/Makefile | 4 ++ arch/arm/mach-imx/imx8/parse-container.c | 120 +++++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 arch/arm/include/asm/arch-imx8/image.h create mode 100644 arch/arm/mach-imx/imx8/parse-container.c
diff --git a/arch/arm/include/asm/arch-imx8/image.h b/arch/arm/include/asm/arch-imx8/image.h new file mode 100644 index 0000000000..c1e5700859 --- /dev/null +++ b/arch/arm/include/asm/arch-imx8/image.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018-2019 NXP + */ + +#ifndef __CONTAINER_HEADER_H_ +#define __CONTAINER_HEADER_H_ + +#include <linux/sizes.h> +#include <linux/types.h> + +#define IV_MAX_LEN 32 +#define HASH_MAX_LEN 64 + +#define CONTAINER_HDR_ALIGNMENT 0x400 +#define CONTAINER_HDR_EMMC_OFFSET 0 +#define CONTAINER_HDR_MMCSD_OFFSET SZ_32K +#define CONTAINER_HDR_QSPI_OFFSET SZ_4K +#define CONTAINER_HDR_NAND_OFFSET SZ_128M + +struct container_hdr { + u8 version; + u8 length_lsb; + u8 length_msb; + u8 tag; + u32 flags; + u16 sw_version; + u8 fuse_version; + u8 num_images; + u16 sig_blk_offset; + u16 reserved; +} __packed; + +struct boot_img_t { + u32 offset; + u32 size; + u64 dst; + u64 entry; + u32 hab_flags; + u32 meta; + u8 hash[HASH_MAX_LEN]; + u8 iv[IV_MAX_LEN]; +} __packed; + +struct signature_block_hdr { + u8 version; + u8 length_lsb; + u8 length_msb; + u8 tag; + u16 srk_table_offset; + u16 cert_offset; + u16 blob_offset; + u16 signature_offset; + u32 reserved; +} __packed; +#endif diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index bbe323d5ca..e9496cb611 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -23,6 +23,12 @@ config IMX8QXP config SYS_SOC default "imx8"
+config SPL_LOAD_IMX_CONTAINER + bool "Enable SPL loading U-Boot as a i.MX Container image" + depends on SPL + help + This is to let SPL could load i.MX8 Container image + choice prompt "i.MX8 board select" optional diff --git a/arch/arm/mach-imx/imx8/Makefile b/arch/arm/mach-imx/imx8/Makefile index 31ad169ccf..19690110a5 100644 --- a/arch/arm/mach-imx/imx8/Makefile +++ b/arch/arm/mach-imx/imx8/Makefile @@ -5,3 +5,7 @@ #
obj-y += cpu.o iomux.o + +ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_LOAD_IMX_CONTAINER) += parse-container.o +endif diff --git a/arch/arm/mach-imx/imx8/parse-container.c b/arch/arm/mach-imx/imx8/parse-container.c new file mode 100644 index 0000000000..32f78bdddf --- /dev/null +++ b/arch/arm/mach-imx/imx8/parse-container.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018-2019 NXP + */ + +#include <common.h> +#include <errno.h> +#include <spl.h> +#include <asm/arch/image.h> + +static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, + struct spl_load_info *info, + struct container_hdr *container, + int image_index, + u32 container_sector) +{ + struct boot_img_t *images; + ulong sector; + u32 sectors; + + if (image_index > container->num_images) { + debug("Invalid image number\n"); + return NULL; + } + + images = (struct boot_img_t *)((u8 *)container + + sizeof(struct container_hdr)); + + if (images[image_index].offset % info->bl_len) { + printf("%s: image%d offset not aligned to %u\n", + __func__, image_index, info->bl_len); + return NULL; + } + + sectors = roundup(images[image_index].size, info->bl_len) / + info->bl_len; + sector = images[image_index].offset / info->bl_len + + container_sector; + + debug("%s: container: %p sector: %lu sectors: %u\n", __func__, + container, sector, sectors); + if (info->read(info, sector, sectors, + (void *)images[image_index].entry) != sectors) { + printf("%s wrong\n", __func__); + return NULL; + } + + return &images[image_index]; +} + +static int read_auth_container(struct spl_image_info *spl_image, + struct spl_load_info *info, ulong sector) +{ + struct container_hdr *container = NULL; + u16 length; + u32 sectors; + int i, size; + + size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len); + sectors = size / info->bl_len; + + /* + * It will not override the ATF code, so safe to use it here, + * no need malloc + */ + container = (struct container_hdr *)spl_get_load_buffer(-size, size); + + debug("%s: container: %p sector: %lu sectors: %u\n", __func__, + container, sector, sectors); + if (info->read(info, sector, sectors, container) != sectors) + return -EIO; + + if (container->tag != 0x87 && container->version != 0x0) { + printf("Wrong container header"); + return -ENOENT; + } + + if (!container->num_images) { + printf("Wrong container, no image found"); + return -ENOENT; + } + + length = container->length_lsb + (container->length_msb << 8); + debug("Container length %u\n", length); + + if (length > CONTAINER_HDR_ALIGNMENT) { + size = roundup(length, info->bl_len); + sectors = size / info->bl_len; + + container = (struct container_hdr *)spl_get_load_buffer(-size, size); + + debug("%s: container: %p sector: %lu sectors: %u\n", + __func__, container, sector, sectors); + if (info->read(info, sector, sectors, container) != + sectors) + return -EIO; + } + + for (i = 0; i < container->num_images; i++) { + struct boot_img_t *image = read_auth_image(spl_image, info, + container, i, + sector); + + if (!image) + return -EINVAL; + + if (i == 0) { + spl_image->load_addr = image->dst; + spl_image->entry_point = image->entry; + } + } + + return 0; +} + +int spl_load_imx_container(struct spl_image_info *spl_image, + struct spl_load_info *info, ulong sector) +{ + return read_auth_container(spl_image, info, sector); +}

i.MX8 only support AHAB secure boot with Container format image, we could not use FIT to support secure boot, so introduce container support to let SPL could load container images.
Cc: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com Cc: Tien Fong Chee tien.fong.chee@intel.com Cc: York Sun york.sun@nxp.com Cc: Marek Vasut marex@denx.de Cc: Alex Kiernan alex.kiernan@gmail.com Cc: Simon Glass sjg@chromium.org Cc: Philipp Tomsich philipp.tomsich@theobroma-systems.com Cc: Kever Yang kever.yang@rock-chips.com Cc: Heiko Schocher hs@denx.de Signed-off-by: Peng Fan peng.fan@nxp.com --- common/spl/spl_mmc.c | 10 ++++++++++ include/spl.h | 12 ++++++++++++ 2 files changed, 22 insertions(+)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index bf53a1dadf..6320af055b 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -79,6 +79,16 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, load.bl_len = mmc->read_bl_len; load.read = h_spl_load_read; ret = spl_load_simple_fit(spl_image, &load, sector, header); + } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) { + struct spl_load_info load; + + load.dev = mmc; + load.priv = NULL; + load.filename = NULL; + load.bl_len = mmc->read_bl_len; + load.read = h_spl_load_read; + + ret = spl_load_imx_container(spl_image, &load, sector); } else { ret = mmc_load_legacy(spl_image, mmc, sector, header); } diff --git a/include/spl.h b/include/spl.h index a9aaef345f..e280685b68 100644 --- a/include/spl.h +++ b/include/spl.h @@ -125,6 +125,18 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, #define SPL_COPY_PAYLOAD_ONLY 1 #define SPL_FIT_FOUND 2
+/** + * spl_load_imx_container() - Loads a imx container image from a device. + * @spl_image: Image description to set up + * @info: Structure containing the information required to load data. + * @sector: Sector number where container image is located in the device + * + * Reads the container image @sector in the device. Loads u-boot image to + * specified load address. + */ +int spl_load_imx_container(struct spl_image_info *spl_image, + struct spl_load_info *info, ulong sector); + /* SPL common functions */ void preloader_console_init(void); u32 spl_boot_device(void);

To support SPL loading container file, add a new Makefile target, and introduce a new Kconfig file to source the cfg file which will be parsed by mkimage.
Signed-off-by: Peng Fan peng.fan@nxp.com --- Makefile | 8 ++++++++ arch/arm/mach-imx/Makefile | 14 ++++++++++++-- arch/arm/mach-imx/imx8/Kconfig | 7 +++++++ 3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile index c55ffa265f..09b354bea9 100644 --- a/Makefile +++ b/Makefile @@ -1333,9 +1333,17 @@ SPL: spl/u-boot-spl.bin FORCE $(Q)$(MAKE) $(build)=arch/arm/mach-imx $@
ifeq ($(CONFIG_ARCH_IMX8M)$(CONFIG_ARCH_IMX8), y) +ifeq ($(CONFIG_SPL_LOAD_IMX_CONTAINER), y) +u-boot.cnt: u-boot.bin FORCE + $(Q)$(MAKE) $(build)=arch/arm/mach-imx $@ + +flash.bin: spl/u-boot-spl.bin u-boot.cnt FORCE + $(Q)$(MAKE) $(build)=arch/arm/mach-imx $@ +else flash.bin: spl/u-boot-spl.bin u-boot.itb FORCE $(Q)$(MAKE) $(build)=arch/arm/mach-imx $@ endif +endif
u-boot-with-spl.imx u-boot-with-nand-spl.imx: SPL u-boot.bin FORCE $(Q)$(MAKE) $(build)=arch/arm/mach-imx $@ diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 898478fc4a..6de81408f8 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -89,6 +89,11 @@ IMX_CONFIG = $(CONFIG_IMX_CONFIG:"%"=%) $(Q)mkdir -p $(dir $@) $(call if_changed_dep,cpp_cfg)
+IMX_CONTAINER_CFG = $(CONFIG_IMX_CONTAINER_CFG:"%"=%) +container.cfg: $(IMX_CONTAINER_CFG) FORCE + $(Q)mkdir -p $(dir $@) + $(call if_changed_dep,cpp_cfg) + ifeq ($(CONFIG_ARCH_IMX8), y) CNTR_DEPFILES := $(srctree)/tools/imx_cntr_image.sh IMAGE_TYPE := imx8image @@ -157,10 +162,15 @@ SPL: MKIMAGEFLAGS_flash.bin = -n spl/u-boot-spl.cfgout -T $(IMAGE_TYPE) -e 0x100000 flash.bin: MKIMAGEOUTPUT = flash.log
-flash.bin: spl/u-boot-spl.bin u-boot.itb FORCE -ifeq ($(SPL_DEPFILE_EXISTS),0) +MKIMAGEFLAGS_u-boot.cnt = -n container.cfg -T $(IMAGE_TYPE) -e 0x100000 +u-boot.cnt: MKIMAGEOUTPUT = u-boot.cnt.log + +ifeq ($(CONFIG_SPL_LOAD_IMX_CONTAINER), y) +u-boot.cnt: u-boot.bin container.cfg FORCE $(call if_changed,mkimage) endif +flash.bin: spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) endif
else diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index e9496cb611..d17760e333 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -29,6 +29,13 @@ config SPL_LOAD_IMX_CONTAINER help This is to let SPL could load i.MX8 Container image
+config IMX_CONTAINER_CFG + string "i.MX Container config file" + depends on SPL + help + This is to specific the cfg file for generating container + image which will be loaded by SPL. + choice prompt "i.MX8 board select" optional

Because FIT could not be used for AHAB secure boot on i.MX8, so switch to use container image that could let SPL verify ATF and U-Boot with AHAB.
Note: The AHAB related code has not been added.
Signed-off-by: Peng Fan peng.fan@nxp.com --- board/freescale/imx8qxp_mek/README | 4 +--- board/freescale/imx8qxp_mek/uboot-container.cfg | 13 +++++++++++++ configs/imx8qxp_mek_defconfig | 5 ++--- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 board/freescale/imx8qxp_mek/uboot-container.cfg
diff --git a/board/freescale/imx8qxp_mek/README b/board/freescale/imx8qxp_mek/README index f32290e3a2..6dc151b166 100644 --- a/board/freescale/imx8qxp_mek/README +++ b/board/freescale/imx8qxp_mek/README @@ -39,11 +39,9 @@ $ cp imx-sc-firmware-0.7/mx8qx-mek-scfw-tcm.bin .
Build U-Boot ============ -$ export ATF_LOAD_ADDR=0x80000000 -$ export BL33_LOAD_ADDR=0x80020000 $ make imx8qxp_mek_defconfig $ make flash.bin -$ dd if=u-boot.itb of=flash.bin bs=512 seek=528 +$ dd if=u-boot.cnt of=flash.bin bs=512 seek=528
Flash the binary into the SD card ================================= diff --git a/board/freescale/imx8qxp_mek/uboot-container.cfg b/board/freescale/imx8qxp_mek/uboot-container.cfg new file mode 100644 index 0000000000..8165811818 --- /dev/null +++ b/board/freescale/imx8qxp_mek/uboot-container.cfg @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 NXP + */ + +#define __ASSEMBLY__ + +/* This file is to create a container image could be loaded by SPL */ +BOOT_FROM SD 0x400 +SOC_TYPE IMX8QX +CONTAINER +IMAGE A35 bl31.bin 0x80000000 +IMAGE A35 u-boot.bin CONFIG_SYS_TEXT_BASE diff --git a/configs/imx8qxp_mek_defconfig b/configs/imx8qxp_mek_defconfig index d735d34b8b..5d6c5f968f 100644 --- a/configs/imx8qxp_mek_defconfig +++ b/configs/imx8qxp_mek_defconfig @@ -7,15 +7,14 @@ CONFIG_SPL_GPIO_SUPPORT=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_SPL_LOAD_IMX_CONTAINER=y +CONFIG_IMX_CONTAINER_CFG="board/freescale/imx8qxp_mek/uboot-container.cfg" CONFIG_TARGET_IMX8QXP_MEK=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_NR_DRAM_BANKS=3 CONFIG_SPL=y -CONFIG_FIT=y -CONFIG_SPL_LOAD_FIT=y -CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh" CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/imx8qxp_mek/imximage.cfg" CONFIG_BOOTDELAY=3 CONFIG_LOG=y
participants (1)
-
Peng Fan