没找到 rk 官方的说明文档, 以下主要通过分析 u-boot, rkflashtool 以及写有引导的 emmc 得来. 文末提供 rkflash-boot 工具代码, 用于烧写引导, 在 rk3128, rk3288 上验证过.
1. 引导流程:
bootrom (CPU) ->
从 emmc 上加载 idblock0 ->
根据 idblock0 加载 emmc 上的 ddr 初始化代码->
根据 idblock0 加载u-boot代码
2. 存储结构:
idblock0 存储于第 64 个扇区, ddr 初始化代码和 u-boot 的扇区偏移量存储于 idblock0, ddr 初始化代码一般存储于 idblock3 后面. 如图
3. idblock0 定义:
1
2
3
4
5
6
7
8
9
10
11
|
typedef
PACKED1
struct
_Sector0Info {
/* 总共512Bytes */
UINT
fwSig;
UCHAR
reserved[4];
UINT
uiRc4Flag;
/* ddr and loader bin rc4 flaf - 1: no rc4, 0: rc4 */
USHORT
usBootCode1Offset;
USHORT
usBootCode2Offset;
UCHAR
reserved1[490];
USHORT
usFlashDataSize;
/* 扇区为单位 */
USHORT
usFlashBootSize;
UCHAR
reserved2[2];
}PACKED2 Sector0Info;
|
(以上参考 u-boot/board/rockchip/common/rkloader/idblock.h)
其中 fwSig 为签名, 必须为 0x0ff0aa55uiRc4Flag 为 ddr-init 和 u-boot 的加密标志, 一般为 0;
usBootCode1Offset 和 usBootCode2Offset 为 ddr-init 的扇区偏移地址, 一般为 4;
usFlashDataSize 为 ddr-init 占用的扇区数, 必须 4 对齐;
usFlashBootSize 为 ddr-init 和 u-boot 一共占用的扇区数, 必须 4 对齐.
u-boot 的偏移量为 usBootCode1Offset + usFlashDataSize.
idblock0 存储到 emmc/sd 前需要先经 rc4 加密, 密码为 7c4e0304550509072d2c7b38170d1711
可参考 u-boot 函数 P_RC4(), 该函数位于 u-boot/board/rockchip/common/platform/rc4_enc.c
4. 其它 idblock:
其它 idblock 定义可参考 u-boot/board/rockchip/common/rkloader/idblock.h
其中idblock3 存储了设备的序列号和 mac 地址.
其它 idblock 在 u-boot 阶段读取解析, 不需要 rc4 加密, 这些数据不写也可以正常引导至 u-boot.
5. usb 秒写 u-boot.bin:
rkflash-boot 根据 rkflashtool 修改, 用于烧写 u-boot. 可秒写 u-boot.bin , 方便调试.
代码:
https://download.csdn.net/download/mxm12/10415566
用法:
rkflash-boot u-boot.bin [ddrinit] [usbplug]
maskrom 方式时, 需要参数 ddrinit, usbplug 文件路径
loader 方式时, 只需要传 u-boot.bin 路径
为什么 upgrade_tool 下载引导很慢?
因为 upgrade_tool 多写了 4 次引导 , 不只是 64 扇区, 还包括 64 + n* 1024 (n = 1~4) 号扇区.