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 <relocate>:
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 <clear_bss>
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 <CopyCode2Ram>

最後由彙編跳轉到C是通過執行下面的語句實現的:

    ldr pc, _start_armboot

_start_armboot: .word start_armboot

其中start_armboot是c函數名,改函數的地址存放在_start_armboot這個地址處,ldr pc, _start_armboot通過把_start_armboot這個地址裏面存放的值賦給pc,實現跳轉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章