u-boot-2014.10移植第28天----nand flash啟動(六)

fulinux發表於2015-03-26

硬體平臺:tq2440

開發環境:Ubuntu-3.11

u-boot版本:2014.10

本文允許轉載,請註明出處:http://blog.csdn.net/fulinus


我本來是想修改arch/arm/lib/relocate.S檔案的,將nand flash中的映象拷貝到SDRAM中執行,但是發現,前面4K空間中有board_init_f的C語言函式,函式裡又有很多的庫函式,這樣一來牽扯的檔案就很多了,很可能無法將他們全部包含在前4K空間內。我在arch/arm/lib/relocate.S檔案中做的修改如下:

ENTRY(relocate_code)
    /* Check it's boot from SDRAM */
    ldr r1, =__image_copy_start
    ldr r2, =CONFIG_SYS_TEXT_BASE
    cmp r1, r2
    beq NORFLASH_BOOT

#ifdef CONFIG_S3C2440
    /* Check it's boot from Norflash or Nandflash:
     * If it's boot from Nandflash on S3C24X0 CPU, then the 4K internal SRAM(iSRAM) will 
     * mapped to both  address 0x4000003C and 0x0000003C. Read this start.S upside source 
     * code can see, the data in offset address 0x3C from the iSRAM should be 0xdeadbeef
     * (.balignl 16,0xdeadbeef). So if it's boot from Nandflash, if we modify the address 0x4000003C 
     * value to 0; then 0x0000003C value should be 0. For they are both in the iSRAM;
     * But if it's boot from Norflash, then the iSRAM is not mapped to 0x0000003C. So if modify address 
     * 0x4000003C(it's in iSRAM) value, the 0x0000003C(it's in Norflash) should be still 0xdeadbeef.
     */
judgment_norflash_nandflash_boot:
    ldr r1, =((4<<28)|(3<<4)|(3<<2)) /* address of Internal SRAM  0x4000003C*/
    mov r2, #0  /* r2 = 0 */
    str r2, [r1]

    mov r1, #0x3c   /* address of men  0x0000003C*/
    ldr r2, [r1]
    cmp r2, #0
    bne NORFLASH_BOOT

    /* recovery address 0x0000003C date*/
    ldr r2, =(0xdeadbeef)
    ldr r1, =( (4<<28)|(3<<4)|(3<<2) )
    str r2, [r1]

NANDFLASH_BOOT:
    /* Read u-boot from Nandflash to SDRAM address r0 */
    /* r0: nand_read_ll() 1st argument;
     * r1: nand_read_ll() 2nd argument;
     * r2: nand_read_ll() 3rd argument;
     */
    ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */
    subs    r4, r0, r1      /* r4 <- relocation offset */
    beq relocate_done       /* skip relocation */
    ldr r3, =__rel_dyn_end  /* r3 <- SRC &__rel_dyn_end */
    subs    r2, r3, r1      /* r2 = r3 - r1 <- u-boot length */

    bl  nand_read_ll

    tst r0, #0x0           /*Check nand_read_ll() return value*/
    bne infinite_loop     /*nand_read_ll() not return 0, then goto dead loop*/

nand_read_ok:
    /*Then verify the read data validation*/
    mov r0, #0             /* The first 4K data in internal SRAM*/
    ldr r1, =__image_copy_start
    add r1, r1, r4  /* The first 4K data read from Nandflash in SDRAM */
    mov r2, #0x400         /*The compare data length*/

compare_next_byte:
    ldr r3, [r0], #4
    ldr r5, [r1], #4
    teq r3, r5
    bne infinite_loop
    subs r2, r2, #4
    bne compare_next_byte


    /*
     * fix .rel.dyn relocations
     */
    ldr r2, =__rel_dyn_start    /* r2 <- SRC &__rel_dyn_start */
    add r2, r2, r4  /* r2 = r2 + relocation offset */
    ldr r3, =__rel_dyn_end  /* r3 <- SRC &__rel_dyn_end */
    add r3, r3, r4 /* r3 = r3 + relocation offset */
    b fixloop


#define GPBDAT  0x56000014
infinite_loop:
    ldr     r2, =GPBDAT
    ldr     r3, [r2]
    bic     r3, r3, #0x100     /*Set bit 5 as low level, Turn On LED*/
    str     r3, [r2]
    b   infinite_loop


#endif


NORFLASH_BOOT:                /* relocate U-Boot from Flash to RAM */
    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:

沒有其他好的方法,只能好好的研究一下如何實現SPL啟動。

明天繼續。


相關文章