uboot之relocate代码的深入理解
在读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 /* dont 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中存放的起始地址。(理解这个很重要)在ubootcpus3c44b0start.S中有如下声明和定义:_TEXT_BASE:。word TEXT_BASE 而在ubootoardB2config.mk文件中有如下赋值:TEXT_BASE = 0x0c100000。在基于daveB2板子的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处。这才
ubootrelocate代码深入理 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)