本文章参考ug585和ug821。
一、启动流程
1.1 BOOTROM启动
BOOTROM是固化在SOC内部的一个程序或代码。上电后BOOTROM立刻启动工作。
第一步,初始化QSPI、SD卡等外设;
第二步,从存储介质中读取BOOT.BIN文件,并对BOOT.BIN进行解析;(BOOT.BIN中一般包含FSBL文件、裸机程序(或U-BOOT)、FPGA bit文件);
第三步,从BOOT.BIN中解析出FSBL代码段的地址和大小等信息,将FSBL代码段拷贝到SOC内部SRAM中,启动FSBL运行。
1.2 FSBL启动
FSBL文件,一般包含在BOOT.BIN文件内,主要用于启动U-BOOT(或用户裸机程序)和加载FPGA代码。需要注意的是,FSBL文件可以由用户自定义修改,vitis IDE中提供了源码。
第一步,初始化SD卡和QSPI等外设;
第二步,初始化DDR芯片;
第三步,先加载FPGA bit程序(FPGA工作),再启动用户裸机程序(或启动U-BOOT)。
1.3 U-BOOT启动
U-BOOT一般由U-BOOT官网、SOC厂家或者板卡厂家提供,主要用于linux等系统内核的启动工作。U-BOOT也可以由用户自定义修改移植。
U-BOOT中,包含了SD卡、QSPI等外设的驱动程序,也包含IIC、文件系统、网络相关协议的驱动。
1.4 程序运行
linux内核运行。
二、文件格式解析
使用Vitis IDE软件可以生成BOOT.BIN文件。BOOT.BIN中,包含了FSBL镜像+U-BOOT镜像(或者裸机程序)+bit文件。
BOOTROM程序搜索BOOT.BIN时,按照下图方式进行搜索。首先搜索0x0地址下,是否包含image ID,若没有,则地址累加0x8000继续寻找,地址最大不超过规定地址(比如QSPI,地址偏移不能超过16MB)。
搜索到BOOT.BIN的头后,按照格式进行解析。
2.1 BOOTROM header的格式
解释如下:
偏移起始地址 | 名称 | 字节数目 | 数值 | 说明 |
---|---|---|---|---|
0x000 | 中断向量表 | 32字节 | / | 中断向量表 |
0x020 | 宽度检测 | 4字节 | 0xAA995566 | 用于检测QSPI数据宽度 |
0x024 | 镜像ID | 4字节 | 0x584C4E58 | Image ID,其ASCII码为XLNX |
0x028 | 加密状态 | 4字节 | 0xA5C3C5A3或0x3A5C3C5A | 加密与否. 其余数值:未加密 |
0x02C | FSBL或用户定义 | 4字节 | / | FSBL或用户定义,忽略 |
0x030 | 源偏移 | 4字节 | / | 表示从有效的BOOTROM头开始到FSBL镜像或者用户代码之间的地址偏移量,该数值必须大于等于0x8C0 |
0x034 | 镜像长度 | 4字节 | / | FSBL的长度,指示BOOTROM拷贝FSBL的长度 |
0x038 | FSBL加载地址 | 4字节 | / | 将FSBL拷贝到OCM(片内SRAM)的哪个地址,一般为0x0 |
0x03C | 执行位置 | 4字节 | / | FSBL在OCM中的运行地址,一般为0x0. |
0x040 | 总的镜像长度 | 4字节 | / | FSBL的长度,指示BOOTROM拷贝FSBL的长度。一般与0x34地址的信息保持一致。 |
0x044 | QSPI配置字 | 4字节 | 0x00000001 | 固定字节 |
0x048 | 校验和 | 4字节 | / | 将0x020~0x047地址的数据按照32bits长度相加,再取反即可。若相加后数据超过32bits,取低32bits取反。 |
0x04C~0x097 | FSBL或用户定义 | 84字节 | / | FSBL或用户定义,忽略 |
0x098 | Image header table | 4字节 | / | Image header table的位置,位置偏移量,具体观看ug585 |
0x9C | Partition header table | 4字节 | / | Partition header table的位置,位置偏移量,具体观看ug585 |
0x0A0~0x89F | 寄存器初始化 | 2048字节 | / | 寄存器初始化的参数 |
0x8C0 | / | / | / | FSBL/用户代码必须大于等于此地址 |
2.2 FSBL程序
BOOT.BIN头部中,记录里FSBL代码的位置,大小,以及FSBL在SRAM中中的加载地址、执行地址。
偏移地址0x30,指示了FSBL代码在BOOT.BIN文件中的位置偏移量
偏移地址0x34,指示了FSBL代码的长度。
偏移地址0x38,指示了FSBL代码在SRAM中的加载地址。
BOOTROM代码解析到这些信息之后,就会读取FSBL程序,拷贝到SRAM中,进行启动运行。
2.3 BIT文件和U-BOOT(裸机程序)
BOOTROM启动完FSBL之后,其工作就完成,剩下的工作由FSBL程序完成。FSBL代码运行之后,负责从BOOT.BIN中找到U-BOOT镜像和bit文件,,然后把bit文件加载到PL侧,然后启动U-BOOT。
这里涉及到三个数据表:image header table 、 partition header table以及image header。
Image header table仅有1个。partition header table和image header成对出现,有多少个镜像,就有对少对可以有多个,有多少个镜像,就有多少个(比如bit文件即算一个镜像,u-boot也算一个镜像,裸机程序也算一个镜像)。
参考ug821文档。
2.3.1 image header table
解释如下:
地址偏移 | 名称 | 字节数目 | 数值 | 说明 |
---|---|---|---|---|
0x0 | 版本号 | 4字节 | 0x01020000 | 固定值 |
0x4 | 镜像header的数量 | 4字节 | / | 比如此处为3,即包含fsbl镜像,bit镜像,u-boot镜像 |
0x8 | 第一个partition header table的偏移量 | 4字节 | / | 注意,以word为单位,即4个字节 |
0xC | 第一个image header的偏移量 | 4字节 | / | 注意,以word为单位,即4个字节 |
0x10 | Header authentication的偏移量 | 4字节 | / | 注意,以word为单位,即4个字节 |
0x1C | 填充 | / | / | 使用0xFF填充,使image header table凑足64字节 |
2.3.2 image header
解释如下:
地址偏移 | 名称 | 字节数目 | 数值 | 说明 |
---|---|---|---|---|
0x0 | 下一个image header的偏移 | 4字节 | / | 下一个image header的字偏移,如果此image header是最后一个,则此处应该为0。注意,以word为单位,即4个字节 |
0x4 | 相关联的partition header table的偏移 | 4字节 | / | 注意,以word为单位,即4个字节 |
0x8 | Partition count | 4字节 | 0x0 | 总是0 |
0xC | Image name length | 4字节 | / | 实际分区计数值 |
0x10 | Image name | N字节 | / | image名称,ASCII码,大端模式存储 可能为FSBL/u-boot/bit文件镜像 |
/ | 字符串终止符 | 4字节 | 0x0 | / |
/ | 填充 | / | 0xFF | 使用0xFF填充,使image header 凑足64字节的整数倍 |
2.3.3 partition header table
含有的信息主要有:镜像的大小、镜像的地址,加载到的SRAM地址、运行的SRAM地址等。
解释如下:
地址偏移 | 名称 | 字节数目 | 数值 | 说明 |
---|---|---|---|---|
0x0 | 加密分区的数据长度 | 4字节 | / | 注意,以word为单位,即4个字节 |
0x04 | 未加密分区的数据长度 | 4字节 | / | 注意,以word为单位,即4个字节 例如该分区是u-boot分区,则指示了u-boot的长度。 |
0x08 | 加密+填充+扩展+身份验证的数据总长度 | 4字节 | / | / |
0x0C | 目的加载地址 | 4字节 | / | 该分区加载到SRAM的地址 |
0x10 | 目的运行地址 | 4字节 | / | 加载到SRAM后,该分区的SRAM运行地址 |
0x14 | 镜像偏移地址 | 4字节 | / | 该分区在整个BOOT.BIN文件中的偏移地址,从该地址读取分区程序。 注意,以 |
0x18 | 属性位 | 4字节 | / | / |
0x1C | 分区计数 | 4字节 | / | / |
0x20 | 校验字的偏移地址 | 4字节 | / | / |
0x24 | Partition header tablel对应的image header的地址 | 4字节 | / | 注意,以word为单位,即4个字节 |
0x28 | 加密相关字段 | 4字节 | / | / |
0x2C | 未定义 | 4字节 | 0x00 | / |
0x30 | 未定义 | 4字节 | 0x00 | / |
0x34 | 未定义 | 4字节 | 0x00 | / |
0x38 | 未定义 | 4字节 | 0x00 | / |
0x3C | 校验和 | 4字节 | / | / |