
IMX6ULL中的HAB1. 简介本文介绍了u-boot 移植到签名 u-boot 到最终实现imx6ull的安全启动。本工程已上传到 NXP_u-boot2. 参考资料i.MX 6ULL Applications Processor Reference ManualAN4581 i.MX Secure Boot on HABv4 Supported DevicesAN12263 HABv4 RVT Guidelines and RecommendationsCode-Signing Tool User’s GuideHigh Assurance Boot Version 4 Application Programming Interface Reference Manual3. 构建u-boot3.1 准备工作软件本项目克隆自nxp-qoriq/u-boot分支为if_v2024.04。硬件基于Alientek的ALPHA I.MX开发板。工具链…/toolChain/fsl-imx-x11-glibc-x86_64-meta-toolchain-cortexa7hf-neon-toolchain-4.9.11-1.0.0.sh3.2 构建NXP u-bootsource/opt/fsl-imx-x11/4.9.11-1.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabimakemx6ull_14x14_evk_defconfigmakeu-boot.imx3.3 将NXP u-boot烧录到SD卡更多细节请参考u-boot/doc/imx/mkimage/imximage.txt.sudoddifu-boot.imxof/dev/sdbbs512seek23.4 在u-boot中添加自定义板级支持在本项目中我们使用mx6ull_para_evk_defconfig3.4.1 复制mx6ull_14x14_evk_defconfig为mx6ull_para_evk_defconfigcdconfigs copy mx6ull_14x14_evk_defconfig mx6ull_para_evk_defconfig在mx6ull_para_evk_defconfig中将CONFIG_TARGET_MX6ULL_14x14_EVK改为CONFIG_TARGET_MX6ULL_PARA_EVK将CONFIG_DEFAULT_DEVICE_TREEimx6ull-14x14-evk改为CONFIG_DEFAULT_DEVICE_TREE“imx6ull-para-evk”3.4.2 复制mx6ullevk.h为mx6ull_para_evk.hcdinclude/configs copy mx6ullevk.h mx6ull_para_evk.h3.4.3 创建para开发板cdboard/freescalsecpmx6ullevk/ mx6ull_para_evk/-r修改mx6ull_para_evk/imximage.cfg将board/freescale/mx6ullevk/plugin.bin改为board/freescale/mx6ull_para_evk/plugin.bin修改mx6ull_para_evk/Kconfig、mx6ull_para_evk/MAINTAINERS和mx6ull_para_evk/Makefile将所有mx6ullevk重命名为mx6ull_para_evk将mx6ull_para_evk/mx6ullevk.c重命名为mx6ull_para_evk/mx6ull_para_evk.c修改arch/arm/mach-imx/mx6/Kconfig复制TARGET_MX6ULL_14X14_EVK相关配置并在TARGET_MX6ULL_14X14_EVK下重命名为TARGET_MX6ULL_PARA_EVK在source board/freescale/mx6ullevk/Kconfig下添加source “board/freescale/mx6ull_para_evk/Kconfig”3.4.5 设备树复制arch/arm/dts/imx6ull-14x14-evk-emmc.dts为arch/arm/dts/imx6ull-para-evk.dts修改arch/arm/dts/Makefile为dtb-$(CONFIG_MX6ULL)添加imx6ull-para-evk.dtb 3.4.6 将板名从MX6ULL 14x14 EVK改为MX6ULL para EVK在mx6ull_para_evk/mx6ull_para_evk.c的checkboard()函数中修改puts(“Board: MX6ULL 14x14 EVK\n”);3.5 构建u-boot-dtb.imxsource/opt/fsl-imx-x11/4.9.11-1.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabimakedistcleanmakemx6ull_para_evk_defconfigmakeall-j16makeu-boot.imx-j4if[!-e./tmp];thenmkdirtmpfirm-rftmp/*cpu-boot-dtb.imx tmpcpu-boot-dtb.imx.log tmp4. 分析u-boot-dtb.imx和u-boot-dtb.imx.log从步骤3开始u-boot-dtb.imx和u-boot-dtb.imx.log在根目录中生成。构建脚本会将这两个文件复制到tmp目录。现在让我们分析这两个文件。4.1 分析u-boot-dtb.imx4.1.1 将.imx转换为.hexcdtmp hexdump-Cu-boot-dtb.imxu-boot-dtb.hex4.1.2 IVT这是来自imx6ull参考手册的 IVT 结构基于此映射让我们分析IVTOffsetValueDescription0x000x402000D1IVT Header0x040x87800000IVT Entry0x080x00000000IVT Reserved 10x0C0x877FF42CIVT DCD address0x100x877FF420IVT BOOT DATA address0x140x877FF400IVT Self address0x180x87891000IVT CSF address0x1C0x00000000IVT Reserved 24.1.3 Boot DataBoot数据的地址是0x877FF420。OffsetValueDescription0x000x877ff000Start: Absolute address of the image0x040x094060Length: Size of the program image0x080x00000000Plugin4.1.4 DCDBoot数据的地址是0x877FF42C。头部格式标签设置为0xD2的单字节字段长度大端格式的双字节字段包含DCD的总长度字节包括头部版本设置为0x41的单字节字段TagLengthVersion0xD20x01e80x40Write data command formatTagLengthParameter0xCC0x1e40x04AddressValueRegister0x020c40680xFFFFFFFFCCM……CCM0x020c40680xFFFFFFFFCCM0x020e40be0x000c0000IOMUX GPR……IOMUX GPR0x020e04a40x00000030IOMUX GPR0x020e02440x00000030IOMUX Register……IOMUX Register0x020e02480x00000030IOMUX Register0x021b001c0x00008000MMDC Register……MMDC Register0x021b08b80x00000000MMDC Register4.1.5 CSFBoot数据的地址是0x87891000。CSF偏移 0x87891000 - 0x877FF420 0x00091C00。在签名u-boot-dtb.imx时csf.bin将附加到这里。4.2 分析u-boot-dtb.imx.log4.2.1 镜像类型Freescale IMX启动镜像表示这是Freescale现NXPi.MX系列处理器的启动镜像文件格式这是i.MX芯片专用的镜像格式包含启动所需的所有必要信息4.2.2 镜像版本2兼容i.MX53/6/7镜像版本号为2兼容i.MX53、i.MX6和i.MX7系列处理器不同版本可能支持不同的特性或格式4.2.3 模式DCDDCD设备配置数据模式表示镜像包含DCD数据用于初始化DDR内存等外设这是i.MX芯片启动过程中的重要配置方法4.2.4 数据大小606304字节 592.09 KiB 0.58 MiB镜像数据大小为606,304字节同时提供了KB和MiB单位的换算值这个大小包含了整个镜像的所有内容4.2.5 加载地址877ff420镜像加载到内存的地址这是一个十六进制地址Boot ROM会将镜像数据加载到这个内存位置4.2.6 入口点87800000程序入口点地址加载完成后CPU将从这个地址开始执行这个地址通常位于加载地址之后可能包含代码段4.2.7 HAB块0x877ff400 0x00000000 0x00091c00HAB高保证启动相关信息第一个值(0x877ff400)HAB块的起始地址第二个值(0x00000000)偏移量第三个值(0x00091c00)块大小这些信息用于安全启动验证4.2.8 DCD块0x00910000 0x0000002c 0x000001e8DCD块配置信息第一个值(0x00910000)DCD在镜像中的偏移地址第二个值(0x0000002c)DCD头部的偏移量第三个值(0x000001e8)DCD数据的大小这些数据用于配置DDR控制器等关键外设5. 签名u-boot-dtb.imx5.1 安装CST下载 cst-3.1.0.tgz解压cst-3.1.0.tgz5.2 生成HAB4密钥和证书I.MX 6ULL使用HAB4来签名u-boot-dtb.imx。关于生成HAB4密钥和证书的更多细节请参考Code-Signing Tool User’s Guide中3.2.2 运行hab4_pki_tree脚本示例3.2.3 生成HAB4 SRK表和Efuse哈希或参考introduction_habv4.txt执行上述步骤后HAB4密钥和证书将在keys和crts目录中生成这里需要描述crts中的2个文件SRK_1_2_3_4_fuse.bin将用于熔丝编程SRK_1_2_3_4_table.bin将用于u-boot-dtb.imx签名5.3 签名u-boot-dtb.imx在步骤3中生成了u-boot-dtb.imx。现在让我们签名u-boot-dtb.imx。强烈建议遵循mx6_mx7_secure_boot.txt中的说明。5.4 验证csf签名在步骤4.1.5 CSF中CSF偏移为0x91c00。要验证u-boot-signed.imx中的csf签名我们应该使用以下步骤5.4.1 比较csf签名与csf.bin和u-boot-signed.imx将csf.bin转换为csf_uboot.hexhexdump-C../tmp/csf.bin../tmp/csf_uboot.hex从u-boot-signed.imx复制csf_cat.bin并转换为csf_cat.hex$IMG_SIZE 0x91c00ddif../tmp/u-boot-dtb-new-CSF-signed.imxof../tmp/csf_cat.binbs1skip$IMG_SIZEhexdump-C../tmp/csf_cat.bin../tmp/csf_cat.hex比较csf_cat.hex和csf_uboot.hexcmp-l../tmp/csf_uboot.hex../tmp/csf_cat.hex如果输出为空则表示两个文件相同。5.4.2 使用csf_parser检查u-boot-signed.imx中的csf签名安装CSF解析器参考 hab_csf_parser/README检查csf_uboot.bin中的CSF./csf_parser-d-ccsf_uboot.bin使用csf_parser检查u-boot-signed.imx中的csf签名./csf_parser-d-s../tmp/u-boot-signed.imx5.4.3 分析csf签名CSF签名在文件高保证启动版本4应用程序编程接口参考手册中有描述。您可以分析csf_uboot.hex来理解csf签名。或者csf_parse命令也会生成parsed_output.txt和debug_log.txt来描述u-boot-signed.imx或csf_uboot.bin中的csf签名。5.5 把SRK Table 烧录到熔丝参考mx6_mx7_secure_boot.txt中的1.5 Programming SRK Hash。注意在验证HAB事件之前不要编程SEC_CONFIG[1]熔丝否则设备将无法启动签名镜像。5.7 Verify HAB events with u-boot-signed.imx5.7.1 Program u-boot-signed.imx to sd cardSD card in my Ubuntu system is /dev/sdb.sudoddifu-boot-signed.imxof/dev/sdbbs1kseek1convfsync5.7.2 检查 HAB events上面的图片是通过 SD卡启动 u-boot-signed.imx 的示例。下面分析HAB events具体参照High Assurance Boot Version 4 Application Programming Interface Reference Manual。hab_status Secure boot enabled HAB Configuration: 0xcc, HAB State: 0x99 No HAB Events Found!HAB Configuration: 0xcc,Secuse ICC.我已经烧录了 SEC_CONFIG[1] 默认的配置应该是 0xf0。HAB State: 0x99, Trusted state.至此从移植u-boot 到 签名u-boot 到 imx6ull 板子上安全启动的主要步骤全部完成。如果 hab_status 没有报错下面就可以烧录SEC_CONFIG[1]。参考mx6_mx7_secure_boot.txt中的1.7 Closing the deviceProgram SEC_CONFIG[1] fuse, using i.MX6 series as example: fuse prog 0 6 0x00000002