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里。

    连接脚本文件lds中没有设置LMA,只是设置了VMA。VMA的设置是通过顶层目录下的config.mk文件中的LDFLAGS实现的
     
    在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

     此时装载地址和运行地址明显不一样,为什么程序还能运行呢?这里就涉及到PIC----代码无关设计方面的知识了。在汇编语言中,像bl、b、adr(adr属于伪指令,一般被编译器解释成sub指令)指令属于位置无关指令,不管程序装载在哪个位置上,bl、b、adr指令都能正确的运行,其原因是bl、b、adr指令的地址域是基于PC的相对偏移寻址,相当于[pc+offset]。当ARM启动时,ARM自动取0x00000000位置上的指令,此时PC=0x00000000。
基于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,这些就不说了。下面来说如何跳转的,请看下面这条指令。
     ldr pc, _start_armboot
    ldr伪指令中目的寄存器如果是pc,则ldr是与位置相关的指令, u-boot.map文件可以看出,_start_armboot=0x33f80044, 即pc=0x33f80004。这样uboot就跳到SDRAM上去运行了,且这条指令刚好处在其运行地址处,所以程序就能正确的运行。

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值