Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2161257
  • 博文数量: 361
  • 博客积分: 10828
  • 博客等级: 上将
  • 技术积分: 4161
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-20 14:34
文章分类

全部博文(361)

文章存档

2011年(132)

2010年(229)

分类: LINUX

2011-03-15 15:52:26

uboot的start.s文件作用很简单。就初始化和启动芯片等功能。

在写start.S的时候,一定注意这个文件在uboot中是一个相对运行的文件,与文件所处的地址无关。而其他的文件都是地址相关的,只能在ram里面运行。(ram或者rom中要修改TEXT_BASE 但环境变量不能在flash中更改,所以还是只能运行在ram)

要判断是否该段程序是否地址无关,最好把语句翻成最原始最原始的语句,这种语句接近于机器码(参考arm嵌入式基础教程 周立功)。

在汇编中的地址包含两个概念:

一个是局部的标号label (在编译时被计算)

另外一种是全局的符号symbol(在链接时计算出来,是绝对地址,具体的值要通过开发者自己设置)

要很注意:

理解汇编的标号的意思:

1:在汇编中,标号存在于某个语句中,只与某个语句挂钩,标号的作用要翻成原始的汇编码去看。

例如:

  ldr,label表示的是 ldr,【pc,#a】 a是在汇编过程中计算出来的具体的值。而后面这句话是arm的执行语句,无论程序在哪运行,都会运行 ldr,【pc,#a】。所以pc值不一样,运行的过程也不一样(这个是取某个地址上的内容,结果是一样的)

而label这样的标号为局部的标号。

  最重要的是:

adr r x,label 表示的是add ,pc,#a 。这里的pc都是当前值。a是局部标号,是在汇编的过程中计算出来的。

所以当程序运行所在的地址不相同时,rx的值也不一样。这就uboot为什么要使用adr来观察是否是在flash中运行的道理。

汇编还有很多要注意的地方:

因为一个机器码为32位,除了一些参数,命令外留给立即数的不多。除了伪指令ldr能够获得立即数外,其他的指令中所含的立即数都是受到位数的限制的。要把arm汇编的指令分成几类来看。

像ldr,str属于存储读取指令,操作的是内存,flash

像add,mov等是寄存器操作指令

这些指令后都有少部分留给立即数的。所以可以使用标号,而标号不是表示的各别值,而需要汇编器去计算以符合32机器码的要求。

我的atmel arm7还有一个remap的功能。

remap之后,因为流水线的缘故,所以mov pc,r12会执行。

在atmel公司给的启动程序中一般会 1:ldr r12,initremap。。

                                                 2:remap操作。。

                                               3: mov pc,r12

                                                 4:initremap:

                                                    5:    dcd (.word)aaa

                                         6:aaa:。。。。。。

     在uboot的代码中也有上面红色部分表示的代码。这里的aaa就不再是局部标号了,而是一个绝对地址,一个具体的数,是全局标号,通过设置ro,ri或者通过uboot的u-boot。lds文件设置(一般不用设置,就是0x0+TEXT_BASE)后,链接器会算出来。 所以如果单单只是在flash中运行,设置ro的值,这个值就被固定了。在uboot中start。s要求是位置无关的,所以remap之后,必须保留当前的PC值, 清楚该pc值与remap后pc值的差值。利用上面一样的方式跳到原来的flash中运行。        

    说道这个,这个说下_start。在start.s中,所有用到start。s的执行语句都是将_start作为局部标号。

      如adr r0,_start(机器码 如上面所述)

  而。gloabl _start

      _arm_boot:

        .word _start中start是全局标号,是链接器算出来的绝对地址。  

阅读(1876) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~