看了韦老师的代码,有点蒙圈,查阅资料,大概理解了一下,做个笔记
.text
.global _start
_start:
bl close_watchdog //关看门狗
bl memsetup //设置存储管理器
bl copy_steppingstone_to_sdram//把4K的SRAM复制到SDRAM
ldr pc,=on_sdram //把PC指向SDRAM 进行下面的执行操作
on_sdram:
ldr sp,=0x34000000
bl main
MAIN_LOOP:
b MAIN_LOOP
这里大致的顺序是 1 写的程序烧到Nand flash 2从nand flash 启动,硬件自动将前面4K的nand flash复制到SRAM
3 PC从0X00开始执行(一般PC复位后,都从0地址开始执行),关看门狗,设置存储管理器,将SRAM的程序拷贝到SDRAM
4 把PC指向SDRAM 进行下面的执行操作(这里的为什么是重点,在Makefile里设置 arm-linux-ld -Ttext 0x30000000,将程序的链接地址设置为0x30000000,即SDRAM实际地址的初始位。链接地址也叫运行地址,存储地址也叫加载地址,这里要明确两者之间的区别。我在链接程序时将链接地址设置为0x30000000,将程序烧到板子里运行时,是将程序存储到SRAM的0x00,这里我感觉0x30000000就是链接地址,0x00就是存储地址。
现在开始看具体的程序,前三步都是bl,bl的特点是相对转移,也就是在PC现有值的基础上进行加减,和位置无关。ldr pc,=on_sdram,是将on_sdram的连接地址给PC,on_dram的连接地址是0x30000010,正好对应ldr sp,=0x34000000指令的实际地址,因为此时已经将SRAM的程序拷贝到了SDRAM中。所以我认为这里可以改成 ldr pc,0x30000010
总结一下,就是说开始程序在SRAM中,程序指令的链接地址和存储地址不一致,当拷贝到SDRAM中,两者就一致了,这时利用 ldr pc, =on_dram,把on_dram的连接地址给PC,也就是把on_dram在SDRAM中的存储地址给了PC,就可以直接转到on_dram在SDRAM中的实际地址了。)