IMX6ULL中的HAB
1. 简介
本文介绍了u-boot 移植到签名 u-boot 到最终实现imx6ull的安全启动。
本工程已上传到 NXP_u-boot
2. 参考资料
- i.MX 6ULL Applications Processor Reference Manual
- AN4581 i.MX Secure Boot on HABv4 Supported Devices
- AN12263 HABv4 RVT Guidelines and Recommendations
- Code-Signing Tool User’s Guide
- High Assurance Boot Version 4 Application Programming Interface Reference Manual
3. 构建u-boot
3.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.sh
3.2 构建NXP u-boot
source/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.
sudoddif=u-boot.imxof=/dev/sdbbs=512seek=23.4 在u-boot中添加自定义板级支持
在本项目中,我们使用mx6ull_para_evk_defconfig
3.4.1 复制mx6ull_14x14_evk_defconfig为mx6ull_para_evk_defconfig
cdconfigs 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_TREE="imx6ull-14x14-evk"改为CONFIG_DEFAULT_DEVICE_TREE=“imx6ull-para-evk”
3.4.2 复制mx6ullevk.h为mx6ull_para_evk.h
cdinclude/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.imx
source/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.imx
4.1.1 将.imx转换为.hex:
cdtmp hexdump-Cu-boot-dtb.imx>u-boot-dtb.hex4.1.2 IVT
这是来自imx6ull参考手册的 IVT 结构:
基于此映射,让我们分析IVT:
| Offset | Value | Description |
|---|---|---|
| 0x00 | 0x402000D1 | IVT Header |
| 0x04 | 0x87800000 | IVT Entry |
| 0x08 | 0x00000000 | IVT Reserved 1 |
| 0x0C | 0x877FF42C | IVT DCD address |
| 0x10 | 0x877FF420 | IVT BOOT DATA address |
| 0x14 | 0x877FF400 | IVT Self address |
| 0x18 | 0x87891000 | IVT CSF address |
| 0x1C | 0x00000000 | IVT Reserved 2 |
4.1.3 Boot Data
Boot数据的地址是0x877FF420。
| Offset | Value | Description |
|---|---|---|
| 0x00 | 0x877ff000 | Start: Absolute address of the image |
| 0x04 | 0x094060 | Length: Size of the program image |
| 0x08 | 0x00000000 | Plugin |
4.1.4 DCD
Boot数据的地址是0x877FF42C。
- 头部格式:
标签:设置为0xD2的单字节字段
长度:大端格式的双字节字段,包含DCD的总长度(字节),包括头部
版本:设置为0x41的单字节字段
| Tag | Length | Version |
|---|---|---|
| 0xD2 | 0x01e8 | 0x40 |
- Write data command format
| Tag | Length | Parameter |
|---|---|---|
| 0xCC | 0x1e4 | 0x04 |
| Address | Value | Register |
|---|---|---|
| 0x020c4068 | 0xFFFFFFFF | CCM |
| … | … | CCM |
| 0x020c4068 | 0xFFFFFFFF | CCM |
| 0x020e40be | 0x000c0000 | IOMUX GPR |
| … | … | IOMUX GPR |
| 0x020e04a4 | 0x00000030 | IOMUX GPR |
| 0x020e0244 | 0x00000030 | IOMUX Register |
| … | … | IOMUX Register |
| 0x020e0248 | 0x00000030 | IOMUX Register |
| 0x021b001c | 0x00008000 | MMDC Register |
| … | … | MMDC Register |
| 0x021b08b8 | 0x00000000 | MMDC Register |
4.1.5 CSF
- Boot数据的地址是0x87891000。
- CSF偏移 = 0x87891000 - 0x877FF420 = 0x00091C00。
在签名u-boot-dtb.imx时,csf.bin将附加到这里。
4.2 分析u-boot-dtb.imx.log
4.2.1 镜像类型:Freescale IMX启动镜像
- 表示这是Freescale(现NXP)i.MX系列处理器的启动镜像文件格式
- 这是i.MX芯片专用的镜像格式,包含启动所需的所有必要信息
4.2.2 镜像版本:2(兼容i.MX53/6/7)
- 镜像版本号为2
- 兼容i.MX53、i.MX6和i.MX7系列处理器
- 不同版本可能支持不同的特性或格式
4.2.3 模式:DCD
- DCD(设备配置数据)模式
- 表示镜像包含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 0x00091c00
HAB(高保证启动)相关信息
- 第一个值(0x877ff400):HAB块的起始地址
- 第二个值(0x00000000):偏移量
- 第三个值(0x00091c00):块大小
- 这些信息用于安全启动验证
4.2.8 DCD块:0x00910000 0x0000002c 0x000001e8
DCD块配置信息
- 第一个值(0x00910000):DCD在镜像中的偏移地址
- 第二个值(0x0000002c):DCD头部的偏移量
- 第三个值(0x000001e8):DCD数据的大小
- 这些数据用于配置DDR控制器等关键外设
5. 签名u-boot-dtb.imx
5.1 安装CST
- 下载 cst-3.1.0.tgz
- 解压cst-3.1.0.tgz
5.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.hex
hexdump-C../tmp/csf.bin>../tmp/csf_uboot.hex- 从u-boot-signed.imx复制csf_cat.bin并转换为csf_cat.hex
$IMG_SIZE = 0x91c00
ddif=../tmp/u-boot-dtb-new-CSF-signed.imxof=../tmp/csf_cat.binbs=1skip=$IMG_SIZEhexdump-C../tmp/csf_cat.bin>../tmp/csf_cat.hex- 比较csf_cat.hex和csf_uboot.hex
cmp-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.imx
5.7.1 Program u-boot-signed.imx to sd card
SD card in my Ubuntu system is /dev/sdb.
sudoddif=u-boot-signed.imxof=/dev/sdbbs=1kseek=1conv=fsync5.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 device
Program SEC_CONFIG[1] fuse, using i.MX6 series as example:
=> fuse prog 0 6 0x00000002