• 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原理详细分析

    完!
  • 相关阅读:
    语言模型工具kenlm安装
    linux操作系统远程连接方法
    Windows操作系统远程连接方法
    Majority Number III
    Majority Number II
    不同颜色在Halcon中的色相值规律
    流程图
    Redis实战(24)使用rdbtools工具来解析redis rdb文件
    EasyExcel
    pktgen 使用小记
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/4541705.html
Copyright © 2020-2023  润新知