u-boot1.1.6 start.s代码分析

在start.s中有如下定义
.globl _start (start.s的第一条语句)
………
_TEXT_BASE:
.word TEXT_BASE
.word表示在当前地址保存TEXT_BASE这个值,TEXT_BASE在config.mk中定义,它的值为0x33D00000,_TEXT_BASE是这个地址的标号,我们可以通过这个标号找到这个地址,在编译之后它才有具体的值。
下面是relocate部分的汇编程序,这段程序的作用是判断程序当前运行的位置(在内部RAM还是在SDRAM中),在debug的时候uboot是直接在SDRAM中运行的,所以就没有必要拷贝了。也就是说,这段程序是判断uboot是正常运行还是在debug状态下运行。

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     clear_bss/*相等则跳过拷贝部分的代码*/
/*不相等则执行以下代码,调用C函数CopyCode2Ram的时候r0,r1,r2用于传递参数*/
    ldr r2, _armboot_start
    ldr r3, _bss_start
    sub r2, r3, r2      /* r2 <- size of armboot            */
    bl  CopyCode2Ram        /* r0: source, r1: dest, r2: size */

adr r0, _start
adr是位置无关指令,它取得的时相对的位置。例如这段代码在 0x33d00000 运行,那么 adr r0, _start 得到 r0 = 0x33d00000 ;如果在地址 0 运行,就是 0x00000000 了。
也就是说如果uboot是开发板上电后启动的,那么执行这条指令后r0的值就是0x00000000 ,如果uboot是用jlink等工具debug的,那么执行这条指令后r0的值就是0x33D00000
ldr r1, _TEXT_BASE
ldr指令把_TEXT_BASE这个地址处的值赋给r1(注意跟ldr伪指令区分开来ldr r0, =_TEXT_BASE,这条指令是把_TEXT_BASE的绝对地址赋给r1),这条指令执行完后r1的值为0x33D00000
cmp r0, r1
比较r0和r1,如果相等则说明是处于debug状态,uboot已经处于SDRAM中了,没必要再拷贝;不相等则说明uboot还处于内部RAM中,需要拷贝。

下面是对应的反汇编代码:

33d000b0 :
33d000b0: e24f00b8  sub r0, pc, #184 ; 0xb8
;非debug状态下pc的值为0x000000b8(pc指向当前指令的下两条指令),r0=0x000000b8-0xb8=0x00000000
33d000b4: e51f107c  ldr r1, [pc, #-124] ; 33d00040 <_TEXT_BASE>
;pc的值为0x000000bc,也就是ldr r1,[0x40],0x40处存放的值为0x33d00000,所以r1=0x33d00000
33d000b8: e1500001  cmp r0, r1
33d000bc: 0a000003  beq 33d000d0 
33d000c0: e51f2084  ldr r2, [pc, #-132] ; 33d00044 <_armboot_start>
33d000c4: e51f3084  ldr r3, [pc, #-132] ; 33d00048 <_bss_start>
33d000c8: e0432002  sub r2, r3, r2
33d000cc: eb00020a  bl 33d008fc 

最后由汇编跳转到C是通过执行下面的语句实现的:

    ldr pc, _start_armboot

_start_armboot: .word start_armboot

其中start_armboot是c函数名,改函数的地址存放在_start_armboot这个地址处,ldr pc, _start_armboot通过把_start_armboot这个地址里面存放的值赋给pc,实现跳转。

你可能感兴趣的:(linux系统学习,笔记,arm)