打印

uboot移植过程中的运行地址和装载地址的区别

[复制链接]
664|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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,这些就不说了。下面来说如何跳转的,请看下面这条指令。
    ldrpc, _start_armboot
    ldr伪指令中目的寄存器如果是pc,则ldr是与位置相关的指令,u-boot.map文件可以看出,_start_armboot=0x33f80044, 即pc=0x33f80004。这样uboot就跳到SDRAM上去运行了,且这条指令刚好处在其运行地址处,所以程序就能正确的运行。

相关帖子

沙发
wml18883730241| | 2017-7-7 21:53 | 只看该作者
感觉楼主理解的比较透彻,本人做硬件的,想请教楼主几个问题,我手里有一块CPU最小系统,含CPU芯片,flash芯片,ddr芯片,boot程序烧录在flash芯片里,先烧程序后焊接的那种,boot烧录后是怎样运行的呢?是复制到cpu芯片里,然后到ddr2里面的吗?这个流程是怎样?

使用特权

评论回复
板凳
fengm| | 2017-7-7 23:33 | 只看该作者

使用特权

评论回复
地板
fengm| | 2017-7-7 23:33 | 只看该作者
这个是AM335的吗?

使用特权

评论回复
5
wml18883730241| | 2017-7-8 08:44 | 只看该作者
本帖最后由 wml18883730241 于 2017-7-8 08:47 编辑

现在我遇到一个问题就是flash烧录boot程序后,CPU串口信号一直没有输出,CPU对flash的片选信号只有一次,正常的片选波形应该是连续好几次,我用的是并行flash

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

116

帖子

0

粉丝