前言
在上一次分析中,分析到了
HandoffAddress=LoadBootImage();
在分析这个函数之前,在从0地址运行之前,在复位(上电复位)之后会从bootROM这个位置开始执行代码,在bootROM中,程序会将QSPI(如果是从qspi启动的话)的前nK的数据拷贝到OCM中,然后跳转到OCM中执行。把生成的BOOT.bin文件用二进制程序打开,根据数据手册可以分析一下前面的数据含义。
BOOT.bin
在boot.bin中从地址0-0x8BF可以分成17个部分,每个部分都有一定的含义
1. 0x000 中断向量表
2. 0x020 固定值 0xaa995566
3. 0x024 固定值 0x584c4e58 ASCII: XLNX
4. 0x028 如果是0xa5c3c5a3或者0x3a5c3c5a为加密的
5. 0x02C bootrom头版本号,不用管
6. 0x030 从bootrom开始到app地址的总数(bytes)
7. 0x034 从loadimage拷到OCM的长度
8. 0x038 目的地址到哪儿拷贝FSBL
9. 0x03C 开始执行的地址
10. 0x040 同7
11. 0x044 0x01为固定值
12. 0x048 校验和(从0x020-0x047)按32-bit word 相加取反
13. 0x04C bootgen相关
14. 0x098 image头的表指针
15. 0x09C partition头的表指针
16. 0x0A0 寄存器初始化的参数
17. 0x8A0 fsbl user defined
18. 0x8C0 fsbl开始的地方
如果是从qspi加载的话,bootrom会把数据从qspi拷贝到OCM中,在OCM中运行,也就是0地址运行。
LoadBootImage
这里我们认为image也就是boot.bin是存放在QSPI中,并且是从qspi中启动的,这个函数在fsbl的main函数之中,分析一下这个函数
RebootStatusRegister = Xil_In32(REBOOT_STATUS_REG);
这个语句是读取reboot的状态,Silicon_Version不是1的时候不用管这个
/*
* read the multiboot register
*/
MultiBootReg = XDcfg_ReadReg(DcfgInstPtr->Config.BaseAddr,
XDCFG_MULTIBOOT_ADDR_OFFSET);
fsbl_printf(DEBUG_INFO,"Multiboot Register: 0x%08x\r\n",MultiBootReg);
/*
* Compute the image start address
*/
ImageStartAddress = (MultiBootReg & PCAP_MBOOT_REG_REBOOT_OFFSET_MASK)
* GOLDEN_IMAGE_OFFSET;
这段代码的作用是从multiboot寄存器中读取要执行的image的地址,其实如果就一个image的话可以不用管这个,这个算出来的imagestartaddress一定是0
Status = GetPartitionHeaderInfo(ImageStartAddress);
这一段是读取在flash中的每个部分的头文件信息,包括大小起始地址等。也就是在生成BOOT的时候加入的几个文件,比如说先加的是FSBL,然后是BIT,最后是APP,那么着了的部分的数量就是3个。
PartitionNum = 1;
这里跳过了fsbl,直接从第二个partition加载,因为fsbl的东西已经在使用了,第二部分也就是bit文件。
然后会判断是什么类型,比如是bit还是application。
Status = PartitionMove(ImageStartAddress, HeaderPtr);
这句的意思是根据不同的partition的头的信息来将flash中的数据加载到DDR中
FsblHandoffExit(FsblStartAddr);
最后通过这句话跳转到应用中运行。