led.s就是汇编语言写的文件,程序写完后还需要编译,也就是生成执行文件。还不算完,要是烧写在板子上还要生成.bin,我们需要用到Makefile。
字面意思make文件,个人理解他就是把你要make的内容写成文件,实现从编译生成可执行文件、到链接到DDR、到生成.bin的这么一个过程。
led.bin:led.s
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
arm-linux-gnueabihf-objdump -D led.elf > led.dis
clean:
rm -rf *.o led.bin led.elf led.dis
1.目标文件就是led.bin,led.s就是依赖文件集合
2.用.s文件生成.0文件,
3.将.o文件链接到目标地址上,0X87800000 就是DDR上的地址(不是初始地址),因为该板子是从DDR开始运行的,所以就要将.0链接到运行地址上。生成的链接文件就是.elf
但是代码的存储地址可以不在DDR上,可以在SD卡、EMMC、或者NAND上,然后上电后I.MX6U的boot rom程序将存储地址上的可执行文件拷贝到运行地址上。再去运行地址上去运行程序。
4.将.elf文件转换为.bin文件
5.反汇编一下.elf文件,会生成.dis文件,可以看看是否是汇编代码,其中标识了运行地址等等,我将其理解为STM32的.map文件。
6.clean执行时会删除执行文件、链接文件、反汇编文件
I.MX6U只有96K的rom,并且这部分rom不向用户开放,所以和STM32不同。
所以他只能在外部的DDR上运行代码,从SD、EMMC、NAND启动(因为DDR类似SDRAM,掉电不保存的,所以需要在启动时将执行文件.bin从这些掉电保存的存储器移至DDR中去运行)。
在之前做STM32H750的时候也因为flash不够(128KB)而将一部分代码和RO(定义的常量)放在SPI_FLASH中,会用到链接文件的编写,这就是分散加载的意义。不同的是SPI_FLASH是掉点保存的,所以烧录完就完事儿了,而存放在SDRAM中运行就需要每次上电从SD卡中将.bin读到SDRAM,再从SDRAM中运行。
NXP恩智浦对.bin写入SD卡是有规定的,不是直接将.bin放入SD卡中就可以的,那么原子编写了一个在linxu系统下将.bin按照NXP的要求写入SD卡的软件,imxdownload,我们先用着。
这个imxdownload放在工程文件夹下,从windows复制到linxu后,imxdownload是没有可执行权限的,必须给其执行权限 chmod 777 imxdownload
然后,将SD卡接入虚拟机中,通过 ls /dev/sd* 查看
找到SD卡在ubuntu中的文件后,比如路径/dev/sdd
将.bin烧入SD卡的命令./imxdownload led.bin /dev/sdd
成功后会生成一个load.imx 的文件,load.imx 这个文件就是软件 imxdownload 根据 NXP 官方启动方式介绍的内容,在 led.bin 文件前面添加了一些数据头以后生成的。最终烧写到 SD 卡里面的就是这个 load.imx 文件,而非led.bin。
其实启动文件、makefile的一系列操作、可执行文件.o什么的STM32也需要用到,只不过ST都给我们做好了,并且有MDK、IAR等编译工具支持交叉编译和下载。我之前才没有关注到,所以学习I.MX6U其实也把STM32的过程也巩固了一遍。
load.imx 文件具体做了哪些工作?下一章我们来看I.MX6U启动过程