为什么在U-boot中完成代码重定位?

时间:2018-05-18 12:58:02

标签: beagleboneblack bootloader u-boot omap

我试图通过浏览源代码来了解BeagleBone Black的启动过程。假设Iam将MLO和u-boot.img文件保存在micro-SD卡中,并使BeagleBone从SD卡启动。

根据我的理解,首先执行ROM代码,并将MMC文件从MMC加载到SOC的内部SRAM中。 MLO文件包含x-loader的代码,即第二阶段程序加载器(SPL)。然后,SPL设置DRAM并将第三级程序加载器(U-boot适当)复制到DRAM中。 U-boot适当直接从DRAM开始执行。

U-boot本身的体系结构相关部分位于U-boot源的arch / arm /目录中。 与SPL相关的代码位于spl /目录中。(执行make mrproper后跟make SPL,* .o文件只在spl /目录中创建)

对于U-boot,我猜测这是执行流程 - arch / arm / cpu / armv7 / start.S位于复位向量(因此它首先运行),并在初始化后调用' _main'程序位于arch / arm / lib / crt0.S。

在crt0.S中,调用board_init_f(),它设置DRAM(和其他东西),然后返回到它停止的位置(在main_中)。它稍后调用函数relocate_code,它再次将它重新定位到DRAM。

ENTRY(_main)

/*
 * Set up initial C runtime environment and call board_init_f(0).
 */

#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
        ldr     r0, =(CONFIG_SPL_STACK)
#else
        ldr     r0, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
        bic     r0, r0, #7      /* 8-byte alignment for ABI compliance */
        mov     sp, r0
        bl      board_init_f_alloc_reserve
        mov     sp, r0
        /* set up gd here, outside any C code */
        mov     r9, r0
        bl      board_init_f_init_reserve

        mov     r0, #0
        bl      board_init_f

#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     r0, [r9, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */
        bic     r0, r0, #7      /* 8-byte alignment for ABI compliance */
        mov     sp, r0
        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
#if defined(CONFIG_CPU_V7M)
        orr     lr, #1                          /* As required by Thumb-only */
#endif
        ldr     r0, [r9, #GD_RELOCADDR]         /* r0 = gd->relocaddr */
        b       relocate_code
here:

为什么U-boot需要再次设置DRAM并重新定位自己,如果这已经由SPL完成了?我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:0)

  

为什么U-boot需要再次设置DRAM并重新定位自己,如果这已经由SPL完成了?

重新定位到内存顶部是为了最大化连续的可用空间 您可以在此高内存地址上构建/链接并加载U-Boot(以保存在副本上)。但是,无论何时使用添加的功能重建U-Boot并且图像变大,都必须重新计算该加载地址。
这也意味着必须改变SPL。

BTW “设置DRAM”通常会被认为是初始化DRAM控制器,这在此阶段尚未完成。
除了重定位代码之外,U-Boot还必须移动堆栈和堆,即C运行时环境。

  

我在这里错过了什么吗?

在主内存中加载U-Boot更方便,然后让U-Boot将自身重定位到高内存。