打印
[Atmel]

uboot在flash上运行

[复制链接]
745|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ji7423|  楼主 | 2015-2-26 17:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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是全局标号,是链接器算出来的绝对地址。


相关帖子

沙发
ddllxxrr| | 2015-2-26 20:43 | 只看该作者
顶一下

使用特权

评论回复
板凳
jiang390625| | 2015-2-27 17:21 | 只看该作者
,写的不错。

使用特权

评论回复
地板
丶tiantian| | 2015-2-27 17:50 | 只看该作者
谢谢楼主总结、

使用特权

评论回复
5
阳光豆苗| | 2015-2-27 18:03 | 只看该作者
写的有技术含量啊。

使用特权

评论回复
6
ji7411| | 2015-2-27 18:03 | 只看该作者
支持下,多谢楼主分享。

使用特权

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

本版积分规则

10

主题

401

帖子

0

粉丝