分析I.MX6ULL芯片程序烧写和运行的重要细节

仅供参考 更多具体细节参考官方数据手册

IMX6ULL 芯片内部有一个 boot ROM,上电后 boot ROM 上的程序就会运行。它会根据 BOOT_MODE[1:0]的值,
以及 eFUSE 或 GPIO 的值决定后续的启动流程。

boot ROM 上的程序功能强大,可以从 USB 口或串口下载程序并把它烧写到 Flash 等设备上,也可以从 SD 卡
或 EMMC、Flash 等设备上读出程序、运行程序。

BOOT_MODE[1:0]的值确定了 4 种启动

BOOT_MODE[1:0] BOOT 类型
00 从 FUSE 启动
01 串行下载
10 内部 BOOT 模式
11 保留

当 BOOT_MODE 设置为内部 BOOT 模式以后,可以从以下设备中启动:
1、接到 EIM 接口的 CS0 上的 16 位 NOR Flash。
2、接到 EIM 接口的 CS0 上的 OneNAND Flash。
3、接到 GPMI 接口上的 MLC/SLC NAND Flash, NAND Flash 页大小支持 2KByte、 4KByte
和 8KByte,8 位宽。
4、Quad SPI Flash。
5、接到 USDHC 接口上的 SD/MMC/eSD/SDXC/eMMC 等设备。
6、SPI 接口的 EEPROM。

官方的启动流程如下总结起来就是:
a. 检查 CPU ID
b. 检查 Reset Type,冷启动、唤醒的启动过程是不一样的
c. 检查启动模式 BOOT_MODE,检查 eFUSE 或 GPIO
d. 根据上述检查从 USB 口、UART 口或是某个启动设备下载 boot image
e. 认证 image
f. 启动

假设使用 SD/TF 卡启动,卡上的程序有多大?它应该被复制到 DDR 哪里去? 带着这个问题一步步解析

1、Image vector table,简称 IVT,IVT 里面包含了一系列的地址信息,这些地址信息在ROM 中按照固定的地址存放着。
2、Boot data,启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等等。
3、Device configuration data,简称 DCD,设备配置信息,重点是 DDR3 的初始化配置。
4、用户代码可执行文件,比如 led.bin(二进制文件)

最终boot ROM从启动设备 读出 到 I.MX6U 内存中的程序其组成为: IVT + Boot data + DCD + .bin。 .imx 文件是在 bin的程序前面加上 IVT+Boot data+DCD。内部 BootROM 会将 .imx (从启动设备 SD 或 emmc)拷贝到 DDR3 中

总结来说就是 通过交叉编译器编译出来的.bin二进制执行文件之前要  加上头部信息 得到.imx文件   然后把这个文件烧写到SD卡或者emmc等ROM上面距离其 0 地址之后的 1024 字节处(可以往.imx文件填充1k二进制数据(.img),然后不用偏移1k,就可以直接烧写.img文件) ,芯片就可以正常从SD卡类设备启动执行程序了,

编译出.bin   ---->>>>>>>>>>>(加上头部信息)>>>>>>>>>>>>  .imx(最终BOOT ROM读到内存)  ------->>>>>>>>>>>>>>(烧入启动设备偏移1K地址)>>>>>>>>>>>>>>.> .img (.imx偏移1K地址,也是最终烧入SD卡等设备的文件) 

具体实现

编译出在 ARM 开发板上运行的可执行文件
arm-linux-gnueabihf-gcc -g -c 【源文件(汇编或者C文件)名】 -o 【目标文件名】.o
“-g”选项是产生调试信息,GDB 能够使用这些调试信息进行代码调试。
“-c”选项是编译源文件,但是不链接。
“-o”选项是指定编译产生的文件名字

arm-linux-gnueabihf-ld -Ttext [指定链接地址] [.o文件名]-o [目标].elf

上述命令中-Ttext 就是指定链接地址,
“-o”选项指定链接生成的 elf 文件名

要得到.bin 文件,因此还 需要将 .elf 文件转换为.bin 文件

arm-linux-gnueabihf-objcopy 更像一个格式转换工具,我们需要用它将 .elf 文件转换为
.bin 文件,命令如下:
arm-linux-gnueabihf-objcopy -O binary -S -g [源文件名].elf [目标文件名].bin


“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出,
选项“-S”表示不要复制源文件中的重定位信息和符号信息,
“-g”表示不复制源文件中的调试信息

实现上面的步骤得到 了  .bin文件  然后

利用mkimage工具把NXP配的imximage.cfg.cfgtmp配置制作带有头部信息的.imx文件

该工具和imximage.cfg.cfgtmp配置百度网盘下载地址

链接: https://pan.baidu.com/s/1ACV-mHt6Th0ugBb0WVn_Qw  密码: ekq4
--来自百度网盘超级会员V2的分享

sudo mkimage -n ./tools/imximage.cfg.cfgtmp -T imximage -e [指定链接地址]  -d .bin .imx 
PS :-e 链接的地址要和编译时链接的地址要一样  比如 0X88000000

第一种方法 直接偏移下载

//烧写SD卡 seek=2 偏移1k的意思 前提是你的SD卡一个快是512个字节才行。绝大部分都是512个字节
sudo dd iflag=dsync oflag=dsync if= .imx of=/dev/sdb seek=2

第二种方法 做出. img文件

  //凭空造出占用1K空间的二进制文件

dd if=/dev/zero of=1k.bin bs=1024 count=1 

制作出.img文件

cat    1k.bin   .imx  > . img

//烧写SD卡
sudo dd iflag=dsync oflag=dsync if= .img of=/dev/sdb

PS:

关于链接地址 boot ROM 读程序,那么它把程序读到内存执行,内存也是要指定地址的,这个地址称为程序的链接地址,链接地址在编译的时候就需要指定了
一般DDR3 地 址 范 围 是 0X80000000~0XA0000000(512MB) 或 者0X80000000~0X90000000(256MB),不管是 512MB 版本还是 256MB 版本的,其 DDR3 起始地址都是 0X80000000。
由于 Cortex-A7 的堆栈是向下增长的,
 保证程序链接地址和申请的栈地址之间的预留空间足够,程序才能正常运行 ,因此我们的链接地址要注意给程序运行栈空间。

0X80200000-0X80000000=0X200000=2MB,
2MB 的栈空间已经很大了,
做裸机开发足够了,所以我们的链接地址可以设为  0X80200000 以上  就可以正常使用

 

 

 

 

 

 

你可能感兴趣的:(嵌入式,嵌入式)