0

我试图了解 u-boot 从内部 ROM 到 SRAM 的重定位。下面的代码显示 u-boot 从 ROM 复制到 SRAM,然后 pc 跳转到 _start_armboot。但是我无法弄清楚内存重映射操作在代码中发生的位置。

摘自 u-boot-2010.09\arch\arm\cpu\arm920t\start.S

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
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 stack_setup

    ldr r2, _armboot_start
    ldr r3, _bss_start
    sub r2, r3, r2      /* r2 <- size of armboot            */
    add r2, r0, r2      /* r2 <- source end address         */

copy_loop:
    ldmia   r0!, {r3-r10}       /* copy from source address [r0]    */
    stmia   r1!, {r3-r10}       /* copy to   target address [r1]    */
    cmp r0, r2          /* until source end addreee [r2]    */
    ble copy_loop
#endif  /* CONFIG_SKIP_RELOCATE_UBOOT */

    /* Set up the stack                         */
stack_setup:
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */
    sub r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area              */
    sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
#ifdef CONFIG_USE_IRQ
    sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
    sub sp, r0, #12     /* leave 3 words for abort-stack    */
    bic sp, sp, #7      /* 8-byte alignment for ABI compliance */

clear_bss:
    ldr r0, _bss_start      /* find start of bss segment        */
    ldr r1, _bss_end        /* stop here                        */
    mov r2, #0x00000000     /* clear                            */

clbss_l:str r2, [r0]        /* clear loop...                    */
    add r0, r0, #4
    cmp r0, r1
    ble clbss_l

    ldr pc, _start_armboot

AT91RM9200 数据表描述了内部 ROM 在复位后可以在地址 0x0000_0000 访问,而 SRAM 只能在地址 0x0020_0000 访问。重新映射后,SRAM 也可在地址 0x0000_0000 处使用,而内部 ROM 可在地址 0x0010_0000 处访问。

谁能帮我理解u-boot中的重映射操作并给我看对应的代码?

谢谢

4

2 回答 2

2

我试图了解 u-boot 从内部 ROM 到 SRAM 的重定位。

您的询问是基于两个误解。

错误前提#1:U-Boot 存储在内部 ROM 中

U-Boot 不存储在 AT91RM9200 的内部 ROM 中。
内部 ROM 包含未发布的专有 Atmel 代码。AT91RM9200 数据表将该内部 ROM 代码的功能描述为“引导程序”和“引导上传器”。

在 AT91 SoC 的下一个版本中,AT91SAM926x 产品中,内部 ROM 中的固件被明确称为ROM Boot程序(又名RomBOOT (sic))和SAM-BA Monitor Program

错误前提 #2:U-Boot 被加载到 SRAM

U-Boot(通常)不加载到 AT91RM9200 的嵌入式 SRAM 中。
AT91RM9200 的内部 SRAM 太小(堆栈和变量只有 16KiB 减去 3KiB),无法包含 U-Boot 的(典型)副本。

U-Boot 通常由二级引导加载程序(在 SRAM 中)(在后续 AT91SAM 产品中称为AT91Bootstrap )加载到外部 SDRAM。
在 AT91M9200(和其他 AT91SAM 产品)上,U-Boot 通常用作第三级引导加载程序。

使用 AT91M9200 时,不应考虑将 U-Boot 从内部 ROM 重新定位。


AT91RM9200 的启动顺序已针对后续的 AT91SAM SoC 进行了形式化,并在下面的 Linux4SAM图中进行了描述。左侧描述代码模块和启动顺序,右侧是物理内存,包含已安装或加载(用箭头表示)的程序。在此处输入图像描述


附录

另请参阅 AT91RM9200 引导加载程序上的此线程(引导进入 u-boot)
显着的文本是“... u-boot(对于 ROM 引导加载程序来说太大了,无法处理)”
显然也提到了关于 AT91RM9200 引导程序的“atmel appnote”,但我在 Atmel 网站上找不到它。有人存档了这个应用笔记AT91RM9200DK U-Boot Flash Programming Solutions,但该板通常从外部 NOR 闪存启动(即 BMS=1 禁用内部 ROM)。

附录#2

有关 U-Boot 开发人员 (Wolfgang Denk) 和 Atmel 工程师 (Ulf Samuelsson) 的明确(和确认)答案,请参阅此线程
突出的文字是“根据我从 Atmel 的说明中收集到的信息,在 U-Boot 之前总是有一个引导加载程序,从数据闪存、串行端口或 [NAND] 闪存加载它......”(除非你从外部 NOR 引导Flash 和 BMS=1,即禁用内部 ROM)。

附录#3

关于 CONFIG_SKIP_RELOCATE_UBOOT 的说明:
U-Boot 在被加载到主内存后,可能会重新定位到高内存以最大化可用内存。
例如,我加载了一个链接到从 0x03F30000 开始的 U-Boot 映像,假设有 64MB。然而,该板实际上有 128MB 的 RAM。我在 0x07F70000 找到了 U-Boot 的重复图像。
执行mtest 0x00000000 0x07F00000测试并覆盖除最高兆字节之外的所有 RAM,并证明在 0x03F30000 加载的 U-Boot 不再被执行。执行 amtest 0x04000000 0x08000000以测试内存的上半部分行为不端/失败,并表明 U-Boot 正在超出上层内存而不是在其原始加载位置执行。

于 2014-12-29T00:40:39.080 回答
0

我怀疑这段代码,如果它在 ROM 中,已经被编译/汇编为在 RAM 中的特定地址上运行(不管是 SRAM 还是 SDRAM 都无关紧要)。您发布的代码片段是使用与位置无关的代码编写的。位置无关代码将自身复制到 RAM 中,然后将实际 RAM 地址加载到 PC 中以执行下一步。您的代码段没有显示 _start_armboot 在哪里,但我的猜测是标签在下一条指令上。这里没有进行硬件重新映射。您可以通过单步执行代码来证明这一点。起初,调试器可能只能向您显示反汇编的指令,直到您逐步执行“ldr pc,_start_armboot”指令,此时实际的源代码会神奇地出现(至少 GDB 会这样做)。

于 2014-12-27T13:55:59.977 回答