u-boot-2015.04 在tq2440上的移植(使用spl引導u-boot)


本次移植跟以往的不同之處是采用了spl來引導u-boot,參考了博客http://blog.csdn.net/fulinus/article/details/42738641

下載鏈接:http://pan.baidu.com/s/1bnlRKgn

 

使用方法:

1、 編譯

  make tq2440_defconfig

  make

2、 然后會在u-boot根目錄下生成u-boot.bin,在spl目錄下會生成u-boot-spl.bin,目前的分區是:

 

u-boot-spl.bin

(1M)

u-boot.bin

(1M)

kernel

(3M)

rootfs

(剩余)

   

自己可以改動,在arch/arm/lib/crt0.S中:

  #if defined(CONFIG_SPL_BUILD)
     /* Read u-boot from Nandflash to SDRAM address $CONFIG_SYS_TEXT_BASE */
     ldr r0, =CONFIG_UBOOT_MTD_ADDR               /*u-boot鏡像在NandFlash中存儲地址*/
     ldr r1, =CONFIG_SYS_TEXT_BASE                /*u-boot在內存中的加載地址*/
     ldr r2, =CONFIG_UBOOT_LENGTH                 /*u-boot鏡像的大小*/

     bl  copy_code_to_sdram

     ldr pc, =CONFIG_SYS_TEXT_BASE
  #else
     bl    board_init_f
  #endif

3、目前支持NandFlash和DM9000。

4、為什么要用spl來引導u-boot?

  對於tq2440,采用的是S3C2440,當從NandFlash啟動時,上電時S3C2440內部固化的程序自動把NandFlash的前4KB程序拷貝到片內SRAM,然后執行IRAM中的程序,同時要保證這4KB中的程序是位置無關碼,在這4KB程序完成了內存的初始化,棧的設置,NandFlash的初始化,將u-boot鏡像從NandFlash中拷貝到內存中,將PC跳轉到內存中執行。

  隨着u-boot的更新,在u-boot的前4K已經無法完成上面這些事,在前4KB會執行位置相關碼,導致u-boot無法正常運行。

  為了解決這個問題,u-boot提供了SPL,用spl來引導u-boot,spl的體積很小,只完成將u-boot從NandFlash中拷貝到內存中,然后跳轉到內存。

5、可能存在的問題:

  由於從NandFlash啟動的時候,IRAM被映射到了0地址處,現在是用spl引導u-boot,所以IRAM中是spl,如果有中斷發生,PC執行的是spl中程序,而不是u-boot中的,可以考慮u-boot啟動后,在將u-boot的前4KB拷貝到IRAM中。

    后來再次閱讀了u-boot代碼,發現上面的這個擔心純屬多余,這個u-boot在代碼重定位,並且修改完相關的符號信息后,緊接着又將中斷向量也進行了重定位,即將最終u-boot代碼段在內存中運行起始地址的前64字節拷貝到了SRAM的0x0處,這樣如果發生了中斷也不用怕跳飛了。

 

下面我們簡單看一下

相關代碼路徑:

中斷向量表:arch/arm/lib/vectors.S

復位異常入口:arch/arm/cpu/arm920t/start.S

_main: arch/arm/lib/crt0.S

board_init_f:common/board_f.c

relocate_code: arch/arm/lib/relocate.S

relocate_vectors: arch/arm/lib/relocate.S

board_init_r:common/board_r.c

main_loop: common/main.c

cli_loop: common/cli.c

parse_file_outer: common/cli_hush.c

 

crt0.S:

#if ! defined(CONFIG_SPL_BUILD)
 
/*
 * Set up intermediate environment (new sp and gd) and call
 * relocate_code(addr_moni). Trick here is that we'll return
 * 'here' but relocated.
 */
 
    ldr    sp, [r9, #GD_START_ADDR_SP]    /* sp = gd->start_addr_sp */
    bic    sp, sp, #7    /* 8-byte alignment for ABI compliance */
    ldr    r9, [r9, #GD_BD]        /* r9 = gd->bd */
    sub    r9, r9, #GD_SIZE        /* new GD is below bd */
 
    adr    lr, here
    ldr    r0, [r9, #GD_RELOC_OFF]        /* r0 = gd->reloc_off */
    add    lr, lr, r0
    ldr    r0, [r9, #GD_RELOCADDR]        /* r0 = gd->relocaddr */
    b    relocate_code
here:
/*
 * now relocate vectors
 */
 
    bl    relocate_vectors

 

relocate_code 和 relocate_vectors:

ENTRY(relocate_vectors)
    /*
     * Copy the relocated exception vectors to the
     * correct address
     * CP15 c1 V bit gives us the location of the vectors:
     * 0x00000000 or 0xFFFF0000.
     */
    ldr    r0, [r9, #GD_RELOCADDR]    /* r0 = gd->relocaddr */
    mrc    p15, 0, r2, c1, c0, 0    /* V bit (bit[13]) in CP15 c1 */
    ands    r2, r2, #(1 << 13)
    ldreq    r1, =0x00000000        /* If V=0 */
    ldrne    r1, =0xFFFF0000        /* If V=1 */
    ldmia    r0!, {r2-r8,r10}
    stmia    r1!, {r2-r8,r10}
    ldmia    r0!, {r2-r8,r10}
    stmia    r1!, {r2-r8,r10}
    bx    lr
 
ENDPROC(relocate_vectors)
 
ENTRY(relocate_code)
    ldr    r1, =__image_copy_start    /* r1 <- SRC &__image_copy_start */
    subs    r4, r0, r1        /* r4 <- relocation offset */
    beq    relocate_done        /* skip relocation */
    ldr    r2, =__image_copy_end    /* r2 <- SRC &__image_copy_end */
 
copy_loop:
    ldmia    r1!, {r10-r11}        /* copy from source address [r1]    */
    stmia    r0!, {r10-r11}        /* copy to   target address [r0]    */
    cmp    r1, r2            /* until source end address [r2]    */
    blo    copy_loop
 
    /*
     * fix .rel.dyn relocations
     */
    ldr    r2, =__rel_dyn_start    /* r2 <- SRC &__rel_dyn_start */
    ldr    r3, =__rel_dyn_end    /* r3 <- SRC &__rel_dyn_end */
fixloop:
    ldmia    r2!, {r0-r1}        /* (r0,r1) <- (SRC location,fixup) */
    and    r1, r1, #0xff
    cmp    r1, #23            /* relative fixup? */
    bne    fixnext
 
    /* relative fix: increase location by offset */
    add    r0, r0, r4
    ldr    r1, [r0]
    add    r1, r1, r4
    str    r1, [r0]
fixnext:
    cmp    r2, r3
    blo    fixloop
 
relocate_done:

 

這個關於relocation原理的解析參考博客:

uboot的relocation原理詳細分析

 

完!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM