imx6ull启动——SD卡启动
boot ROM 程序
boot rom主要的功能:
初始化时钟、外部DDR3
从外部存储介质加载代码
这段boot ROM程序在片内ROM中,厂商在出厂时已经固化的程序,我们无法更改。
镜像文件的组成
offset | IVT偏移量,和启动设备有关,当从SD卡启动,offset为1024 |
---|---|
Image Vector Table | 简称IVT表,用于记录boot data地址和DCD地址信息 |
Boot Data | 记录着镜像加载到DDR的地址、大小,包含偏移 |
Device Configuration Data | 简称DCD,关键外设的寄存器配置信息(时钟、DDR相关) |
.bin文件 | 这个就是我们编写代码生成的文件 |
IVT表
IVT是也是一个表或者说是一个数据结构,它保存有DCD数据的地址、程序的入口等等信息。 启动方式确定后Boot ROM从固定地址读取IVT。如下表所示。
启动设备类型 | IVT偏移地址 | 初始加载区域大小 |
---|---|---|
NOR | 4 Kbyte = 0x1000 bytes | Entire Image Size |
OneNAND | 256 bytes = 0x100 bytes | 1 Kbyte |
SD/MMC/eSD/eMMC/SDXC | 1 Kbyte = 0x400 bytes | 4 Kbyte |
SPI EEPROM | 1 Kbyte = 0x400 bytes | 4 Kbyte |
从上表可知,IVT在存储器中的偏移值是固定的。以SD卡为例,如果从SD卡启动,那么IVT位于SD卡的0x400偏移地址处。
IVT表的成员信息
header:IVT的长度、大小(在IVT表的0-3个字节)
entry:程序运行地址,应该是在内存(DDR3)中运行的地址(在IVT表的4-7个字节)
dcd:内存中DCD数据地址
boot_data:内存中boot_data地址
self:IVT在DDR中的地址
header格式图示
生成镜像文件
生成镜像文件前,先要准备好DCD的文件,主要包含初始化DDR3和时钟的参数。
dcdgen.bin是一个程序,使用下面命令将dcd.config文件转为dcd.bin文件,dcd.config文件的内容是cmd命令,用来设置DDR和时钟的初始化,dcd.bin是头部信息表。
dcdgen.bin dcd.config dcd.bin
还要准备一个led.bin文件,就是我们编写的代码文件,使用arm-gcc工具处理得到的。
接下来使用imgutil.bin程序使用设置的参数,将sdk20-app.img文件打包为镜像文件
./imgutil.bin --combine base_addr=0x80000000 ivt_offset=0x400 app_offset=0x2000 dcd_file=dcd.bin app_file=led.bin ofile=sdk20-app.img image_entry_point=0x80002000
从镜像文件看IVT表
查看sdk20-app.img文件的内容
hexdump -n 50 -C -s 1024 sdk20-app.img
使用上面这条命令,显示偏移量为1024处开始处的50个字节的内容
00000400 d1 00 20 41 00 20 00 80 00 00 00 00 40 04 00 80 |.. A. ......@...| 00000410 20 04 00 80 00 04 00 80 00 00 00 00 00 00 00 00 | ...............| 00000420 00 00 00 80 54 20 00 00 00 00 00 00 00 00 00 00 |....T ..........| * 00000432 |
由于偏移是1024字节所以从地址00000400看输出内容,由于是小端存储,0-3个字节是header为0X412000d1 接下来看4-7个字节为0X80002000 这是bin文件在DDR3中的地址也是程序的入口地址。
从镜像文件分析IVT表信息
https://doc.embedfire.com/lubancat/build_and_deploy/zh/latest/building_image/boot_image_analyse/boot_image_analyse.html
IVT结构 | 数据 | 描述信息 |
---|---|---|
header | 0X412000d1 | 根据header格式,第一个字节Tag是固定值为0Xd1,第二、三个字节是IVT大小为0X0020=32字节,第四个字节是version为0X41 |
entry | 0X80002000 | bin文件的链接地址也是程序的入口地址 |
reserved1 | 0X00000000 | 未使用,保留 |
dcd | 0X80000440 | DCD在DDR中的地址 |
boot data | 0X80000420 | boot data在DDR中的地址 |
self | 0X80000400 | IVT在DDR中的地址 |
csf | 0X00000000 | CSF地址 |
reserved2 | 0X00000000 | 未使用,保留 |
Boot data数据(12B)
烧录镜像文件
使用dd命令,将sdk20-app.img镜像文件烧录到sd卡中,这里我的sd卡是sdb,根据自己的设置。
sudo dd if=sdk20-app.img of=/dev/sdb bs=512 conv=fsync
dd if=sdk20-app.img: if是dd命令的参数,用于指定输入文件的名称和路径。sdk20-app.img 是输入文件。
of=/dev/sdb: of也是dd命令的参数,用于指定输出文件或设备。数据将被写入/dev/sdb设备。
bs=512: bs 参数定义了每次读取和写入操作的块大小,以字节为单位。这里设置为 512 字节,表示每次读取或写入操作将处理 512 字节的数据块。
conv=fsync: conv 参数用于指定转换选项,使用fsync表示在每次写入完成后,刷新缓冲区并等待设备确认数据已写入。
将镜像烧录到SD卡中,在SD内存中的地址如下图: