Chinaunix首页 | 论坛 | 博客
  • 博客访问: 146603
  • 博文数量: 29
  • 博客积分: 717
  • 博客等级: 上士
  • 技术积分: 352
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-16 16:17
文章分类

全部博文(29)

文章存档

2013年(4)

2012年(4)

2011年(21)

我的朋友

分类: LINUX

2011-05-16 19:00:21

uboot的引导阶段分为2个阶段,在第一阶段所有的寻址方式都是相对PC寻址,所以不管代码在什么地址都可以正确的运行,第一阶段还实现搬运代码到sdram,然后再跳转到第二阶段的入口地址,跳转后这时pc将指向sdram。
uboot第一阶段部分反汇编代码
  1. u-boot: file format elf32-littlearm
  2. Disassembly of section .text:
  3. 33f80000 <_start>:
  4. */
  5. .globl _start
  6. _start: b reset
  7. 33f80000: ea000012 b 33f80050
  8. ldr pc, _undefined_instruction
  9. 33f80004: e59ff014 ldr pc, [pc, #20] ; 33f80020 <_undefined_instruction>
  10. ldr pc, _software_interrupt
  11. 33f80008: e59ff014 ldr pc, [pc, #20] ; 33f80024 <_software_interrupt>
  12. ......
  13. ......
  14. reset:
  15. /*
  16. * set the cpu to SVC32 mode
  17. */
  18. mrs r0,cpsr
  19. 33f80050: e10f0000 mrs r0, CPSR
  20. bic r0,r0,#0x1f
  21. 33f80054: e3c0001f bic r0, r0, #31 ; 0x1f
  22. orr r0,r0,#0xd3
  23. ......
  24. ......
由于arm多级流水线所以PC指向当前指令向下偏移2条指令(8 bytes),下文PC指向当前指令的地址

如果是norflash系统加电后PC=0,如果是s3c则进入steppingstone,然后执行第一句跳转指令
33f80000: ea000012 b 33f80050
这条指令的机器码是:0xea000012
跳转指令B,BL格式如下

Cond

1

0

l

L

Offset

In arm state, bit[1:0] are zero and bits[31:2] contain the PC. IN THUMB state, bit[0] is zero and bits[31:1] contain the PC.
arm state:ALIGN(4)

thumb state:ALIGN(2)

指令操作的伪代码:

if L == 1 then

LR = address of the instruction after branch instruction

PC = PC+ OFFSET << 2

也就是说b,bl指令只能跳到可以被4整除的内存地址处去执行,因此汇编源文件里经常看到.align n的语句

指向该指令时PC=0,PC = PC + 0x8 + 0x12 * 4; PC=0x50,指向reset代码,
而0x12是链接时计算出来的值,该偏移量与地址无关。

同理:

33f80004: e59ff014 ldr pc, [pc, #20] ; 33f80020 <_undefined_instruction>

LDR指令格式

This addressing mode(mode 2) calculates an address by adding or subtracting the value of an immediate offset to or from the value of base register Rn

Syntax

[, #+/-]

where:

Specifies the register containing the base address.

Specifies the immediate offset used with the value of Rn to form the address.

Operation

if U == 1 then

address = Rn + offset_12

else /* U == 0 */

address = Rn - offset_12

所以该指令执行的效果后

PC = 【PC + 0x08 + offset_12】; PC = 【PC + 0x20】

PC的值等于PC+0x20内存地址的值

【总结】

B,Bl,LDR的地址访问方式是通过在当前值加一个偏移地址,反汇编的源码是在链接地址的基础上展开的,查看机器码可以发现代码的指向是通过相对偏移来实现的。

start.s的反汇编

  1. ./cpu/arm920t/start.o: file format elf32-littlearm
  2. Disassembly of section .text:
  3. 00000000 <_start>:
  4. 0: ea000012 b 50
  5. 4: e59ff014 ldr pc, [pc, #20] ; 20 <_undefined_instruction>
  6. 8: e59ff014 ldr pc, [pc, #20] ; 24 <_software_interrupt>
  7. ......
  8. ......
  9. 00000050 :
  10. 50: e10f0000 mrs r0, CPSR
  11. 54: e3c0001f bic r0, r0, #31 ; 0x1f
  12. 58: e38000d3 orr r0, r0, #211 ; 0xd3
  13. 5c: e129f000 msr CPSR_fc, r0
  14. 60: e3a00453 mov r0, #1392508928 ; 0x53000000
  15. ......
  16. ......

对比uboot的反汇编代码发现机器码完全一样,被改变只是链接地址,所以程序不管是在什么地址都可以正确运行,也就是所说的地址无关代码,当然只是第一阶段引导代码。

如果代码是通过调试器运行的话,仿真器对sdram做好初始化,那么所有计算出的加载地址等于链接地址,程序运行地址等于33f80000

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

jackettop2011-05-24 14:56:25

That was a great piece of information., I enjoyed reading it...
<a href=http://www.asicsshoesshopping.com>mexico 66</a>
[url=http://www.asicsshoesshopping.com]mexico 66[/url]
<a href="http://www.asicsshoesshopping.com" title="mexico 66">mexico 66</a>
[url=http://www.www.asicsshoesshopping.com mexico 66]


<a href=http://www.jerseyss