uboot之relocate代码的深入理解

在读网络原理时,发现Dave Clark说的一句话“我们拒绝国王,总统和选举。我们信奉的是是大体的一致意见和正在执行的代码”

     在读linux0.11内核时,发现linus说的一句话,“要了解系统真正的运行机制,一切尽在源代码中”。

     在读众多的关于uboot移植的文档如,大家却在说“第一阶段~~~~第二阶段~~~~~”,“ 这一段完成~~~~”却很少见到讲解过start_armboot()函数是怎么实现的,只是笼统的说完成神马神马的初始化~~

     在今天之前看了那么多文档,发现自己对uboot说的是头头是道,“第一阶段~~第二阶段~~”,然后移植到自己板子上,则是两眼一摸黑,神马都不知道~~~

    然而就是今天,就在写这篇文档之前。我才发现了uboot真正的执行与实现原理。而达到这一步的最初动力就是:要看看uboot到底是怎么执行的,而不光是知道它“应该”是怎么执行的和它的流程。在不懂得代码操作过程而只知道执行流程的时候,知道的执行流程只能是浮云~~~而要根根据自己的板子实际的改动uboot中的代码那就更别谈了。于是,深入到uboot的代码中去,尽管有些代码很难懂,尽管有些函数,宏定义根本不知道放在哪,但总是能找到的,总是能看懂的~只要方向正确,哪怕多走点路,也总能是到达目的地的~~

    至此,才真正算是明白学习之道:多看,多想,多写~~~

    还是那句话:除了代码,神马都是浮云!  这两天天气突然转冷,就刚才由大雪籽转而飘起了大雪,手也开始不听使唤的抖动起来了。自己的对uboot的理解也逐渐深入了,下面就一段段的写下,加深印象吧

 这两天天气突然转冷,就刚才由大雪籽转而飘起了大雪,手也开始不听使唤的抖动起来了。自己的对uboot的理解也逐渐深入了,下面就一段段的写下,加深印象吧

先贴上代码吧:

relocate:    /* relocate U-Boot to RAM     */
 adr r0, _start  /* r0 <- current position of code   */
 ldr r1, _TEXT_BASE  /* test if we run from flash or RAM */
 cmp     r0, r1                  /* don't reloc during debug         */
 beq     stack_setup

     最初看到这个代码的时候,发现功能还是很简单的,就是判断uboot是放在哪里的,flash? or SDRAM?如果放在SDRAM中,就不需要再把uboot代码从flash中搬移到SDRAM中,直接跳到stack_setup;如果是放在flash里的话,则要把代码从flash中搬移到指定的SDRAM地址(TEXT_BASE)中。细看之下,又发现了点问题:它是怎么知道uboot到底放在哪呢;又要把uboot放到SDRAM的什么地址去呢,也即TEXT_BASE是多少。

    先说TEXT_BASE吧。TEXT_BASE在功能上是指示uboot将要SDRAM中存放的起始地址。(理解这个很重要)在uboot\cpu\s3c44b0\start.S中有如下声明和定义:_TEXT_BASE:。word TEXT_BASE 而在uboot\board\B2\config.mk文件中有如下赋值:TEXT_BASE = 0x0c100000。在基于dave\B2板子的uboot是把uboot放在SDRAM中的0x0c100000处的。(点击浏览下一页个人暂时认为这个TEXT_BASE应该是可以修改的,比如TEXT_BASE=0x0c100004)再说这个_start:当uboot在flash中运行的时候,_start是程序的开始,也即地址0。而当uboot在SDRAM的时候,这个_start应该是多少呢??经过反复想,点击浏览下一页反复想之后,才发现,这个_start就应该是TEXT_BASE。

 由于_start是整个uboot的开头处,所以_start在uboot中的偏移地址_start_offset=0,这个无疑义。当uboot在flash中的时候,_start=0x00000000很好理解:flash映射起始地址为0x00000000。uboot放在flash当中的话,uboot起始地址就应该为0x00000000,而_start在uboot中的偏移地址为0,所以_start的绝对物理地址就应该是0x00000000。当uboot处于SDRAM中的时候,_start=??那么它为什么又会等于TEXT_BASE=0x0c1000000呢???原因就在于,我们要把(注意:是将要把,打算把)uboot搬到TEXT_BASE=0x0c100000(这个位置属于SDRAM的映射)处。那么uboot的绝对地址就应该是TEXT_BASE,而_start在uboot中的偏移地址是0,所以_start的绝对地址就是TEXT_BASE+0=TEXT_BASE。在ldr r1,_TEXT_BASE执行之后,r1=TEXT_BASE的;而adr r0,_start执行之后呢??adr指令是基于PC的相对寻址,执行之后r0=PC+_star_offset=PC。如果uboot放在SDRAM中的话,那么_start的绝对地址是TEXT_BASE,也即PC=TEXT_BASE。

 至此,才明白了是如何判断是否要进行代码搬移的。

   总结:开始一直以为,uboot在SDRAM中的话,其开始地址应该是SDRAM的映射开始地址,即0x0c000000,也即_start的绝对地址应该是0x0c000000。后来才发现,uboot放在SDRAM中的位置是由程序控制的,即放在TEXT_BASE处。这才明白上面那几行代码是怎么回事了~~~

 话外音::突然间想到---TEXT_BASE是uboot在SDRAM的开始处,所以在SDRAM中的时候_start=TEXT_BASE。只有这样才能判断正确~~


原文地址http://www.51hei.com/mcu/1131.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值