uboot移植过程中的运行地址和装载地址的区别
uboot移植涉及到底层硬件的设置,因此需要掌握UART、系统时钟频率、NOR FLASH、NAND FLASH、SDRAM、网卡、存储控制器等硬件的功能及配置,这些都可以参照相应开发板的芯片手册来完成,没有什么大的问题。在移植过程中,一直困扰我的是PIC(代码无关性)问题,即运行地址和加载地址的区别,看过网上很多关于这两者的介绍,感觉懂一点,却一直不知所然。在参考大量的文献下,算是得了一点心得。
首先来了解下运行地址及加载地址的区别
运行地址:也叫链接地址,是程序定位的绝对地址,即在编译连接时确定的地址。如果程序中有位置相关指令,程序在运行时,程序必须在运行地址上。
加载地址:程序放置的位置。
运行地址和加载地址的值有时相等,有时却不相等,所以这给初学者带来很大的困扰。为了弄清楚这个问题,还得从NOR FLASH,NAND FLASH,S3C2440内部4KB RAM的映射说起。
左边表示从NOR FLASH启动时的映射,右边表示从NAND FLASH启动时的映射。
这里只讨论从NOR FLASH启动的情况,从图中可以看出NOR FLASH映射到了0X00000000的起始位置,假如UBOOT的代码存放在NOR FLASH上,即装载地址为0X00000000。再来看看UBOOT的链接地址,代码在board/smdk2410/U-Boot.lds里。
在board/smdk2410/config.mk定义了TEXT_BASE = 0x33F80000(SDRAM),即程序的运行地址
查看u-boot.map文件,代码的连接地址是从0x33F80000开始的。
167 .text 0x33f80000 0x232c8
168 cpu/arm920t/start.o(.text)
169 .text 0x33f80000 0x4a0 cpu/arm920t/start.o
170 0x33f80048 _bss_start
171 0x33f8004c _bss_end
172 0x33f80044 _armboot_start
173 0x33f80000 _start
174 board/samsung/fs2410/lowlevel_init.o(.text)
175 .text 0x33f804a0 0x64 board/samsung/fs2410/lowlevel_init.o
176 0x33f804a4 lowlevel_init
177 board/samsung/fs2410/nand_read.o(.text)
178 .text 0x33f80504 0xe8 board/samsung/fs2410/nand_read.o
179 0x33f80504 wait_idle
180 0x33f80518 nand_read_ll
基于PC偏移量的指令都能正确的执行。所以uboot第一阶段指令都能执行的原因在于此。
但我们回顾一下u-boot的启动过程中的第一阶段有将u-boot代码复制到SDRAM中,并跳到SDRAM中去运行,因为SDRAM映射到了BANK6,其地址为0x30000000,此时uboot代码的地址范围从 TEXT_BASE—-TEXT_BASE+size(u-boot),程序是如何跳转的呢?跳转到SDRAM为何还能运行呢?这里就需要看下cpu/arm920t/start.S中的relocate标号。
relocate: 把norflash中的代码复制到_TEXT_BASE处,在board/smdk2410/config.mk定义了TEXT_BASE = 0x33F80000,这个地址属于BANK6的范围。也就是把代码复制到从_TEXT_BASE地址开始的SDRAM中,当然在复制之前是要初始化SDRAM的,要不然SDRAM没法使用。至此,代码已复制到SDRAM中,那么就要跳到SDRAM中去运行,跳转之前要做stack设置,清BSS,这些就不说了。下面来说如何跳转的,请看下面这条指令。
ldrpc,
_start_armboot
ldr伪指令中目的寄存器如果是pc,则ldr是与位置相关的指令,u-boot.map文件可以看出,_start_armboot=0x33f80044,
即pc=0x33f80004。这样uboot就跳到SDRAM上去运行了,且这条指令刚好处在其运行地址处,所以程序就能正确的运行。
转载地址: http://blog.csdn.net/czxyhll/article/details/7859021