对于IMX6ULL,烧写在EMMC、SD/TF卡上的程序,并不能“自己复制自己”。一上电首先运行的是boot ROM上的程序,它从EMMC、SD/TF卡上把程序复制进内存里。
boot ROM程序需要知道从启动设备哪个位置读程序,读多大的程序,复制到哪里去。
启动设备上,不能仅仅烧写bin文件,需要在添加额外的信息。
还有一个问题,IMX6ULL的boot ROM程序可以把程序读到DDR里,那需要先初始化DDR。每种板子接的DDR可能不一样,boot ROM程序需要初始化这些不同的DDR。boot ROM从哪里得到这些不同的参数?
还有,IMX6ULL支持各种启动设备,比如各种Nor Flash。为了通用,boot ROM程序将会使用最保守的参数,也就是最慢的时序来访问Nor Flash。为加快启动程序,boot ROM程序可以根据我们提供的信息初始化硬件,让它以更优的参数运行。
这些参数信息,被称为“Device Configuration Data”,设备配置数据(DCD),这些DCD将会跟bin文件一起打包烧写在启动设备上。boot ROM程序会从启动设备上读出DCD数据,根据DCD来写对应的寄存器以便初始化芯片。DCD中列出的是对某些寄存器的读写操作,我们可以在DCD中设置DDR控制器的寄存器值,可以在DCD中使用更优的参数设置必需的硬件。这样boot ROM程序就会帮我们初始化DDR和其他硬件,然后才可以把bin程序读到DDR中并运行。
总结起来,烧写在EMMC、SD卡或是TF卡上的,除了程序本身,还有位置信息、DCD信息,这些内容合并成一个映像文件,如下图:
这4部分内容合并成为一个映像文件,烧写在EMMC、SD卡或TF卡等启动设备的某个固定地址,boot ROM程序去这个固定地址读出映像文件。启动设备不同,固定地址不同,如下图:
下面的讲解图中,列有C语言格式的结构体,这些结构体来源于U-boot的tools目录下的imximage.h。
(1). Image Vector Table(IVT):
IVT会被放在固定的地址,IVT中是一系列的地址,boot ROM程序会根据这些地址来确定映像文件中其他部分在哪里。
IVT格式如下:
要注意的是上图中这5项:
a. header:
里面有3项:tag、length、version。length表示IVT的大小,它是32字节。要注意是的,它是大字节序的。
b. entry:
用户程序运行时第1条指令的地址,就是程序的链接地址、程序被复制到内存哪里
c. dcd:
映像被复制到内存后,其中的DCD数据的地址。
d. boot data:
映像被复制到内存后,其中的boot data的地址。
e. self:
映像被复制到内存后,IVT自己所在的地址。
(2). Boot data:
映像被复制到内存后,IVT自己所在的地址。
a. start:
这是映像文件在内存中的地址,注意,它不等于IVT在内存中的地址。
什么意思?假设IVT被保存在启动设备TF卡1024偏移地址处,IVT被复制到内存地址0x87000000,那么start=0x87000000-1024。
所以start表示的是启动设备开头的数据,被复制到内存哪里去。
从它的含义也可以推理出:boot ROM程序会把启动设备开头的数据,复制到内存;而不仅仅是从IVT开始复制。
b. length:
保存在启动设备上的整个映像文件的长度,从0地址开始(不是从IVT开始)。
c. plugin:
这是一个标记位,当它为1时表示这个映像文件是“plugin”,即插件。
boot ROM程序可以支持有限的启动设备,如果你想双持更多的启动设备比如网络启动、CDROM启动,就需要提供对应的驱动。
Boot data就是用来表示映像文件应该被复制到哪里去,以前它的大小。boot ROM程序就是根据它来把整个映像文件复制到内存去的。
(3). DCD:
DCD的作用在前面讲解过,简单地说就是设备的配置信息,里面保存有一些寄存器值。
实际上DCD还可以更复杂,它支持多种命令:write data、check data、nop、unlock。我们可以通过write data命令写寄存器,通过check data命令等待寄存器就绪。
DCD格式如下:
DCD以Header开始,里面的TAG为0xD2表示它是DCD,里面还标明了DCD的大小、版本。
接下来就是各个“CMD”,你可以在一个“CMD”里操作多个寄存器,比如在一个“write data command”中,写多个寄存器。
以“write data command”为例简单介绍一下,它的格式为:
上图中,TAG为0xCC表示这是“write data command”;Length表示命令的大小;Parameter的作用稍后再说。
既然是写命令,那自然就有“地址、值”,上图中就是多个“Address、Value/Mask”。为何还有Mask?这要结合Parameter来讲解:
Parameter中b[2:0]用来表示写操作的字节数,是以字节、半字(2 byte),还是字(4 byte)来操作。
而b[4]、b[3]决定了是写值(write value),清位(clear bitmask),还是设位(set bitmask)。
(4). User code and data:
就是用户程序或数据,原原本本地添加到映像文件里就可以。