在 AT91RM9200 上将 U-Boot 从内部 ROM 重新定位到 SRAM

Posted

技术标签:

【中文标题】在 AT91RM9200 上将 U-Boot 从内部 ROM 重新定位到 SRAM【英文标题】:Relocating U-Boot from internal ROM to SRAM on AT91RM9200 【发布时间】:2014-12-24 12:46:23 【问题描述】:

我正在尝试了解 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中的remap操作,给我看一下这个对应的代码吗?

谢谢

【问题讨论】:

该代码没有告诉我们任何有关所有地址的实际值的信息。我不知道这个设备,但数据表显示(第 125 页)“通过将 MC_RCR(重映射控制寄存器)RCB 字段写入 1,可以通过内存控制器用户界面访问重映射命令”。显然 MC_RCR 位于 0xFFFFFF00 (p.129),所以寻找一些写入那里的代码。您确定在此搬迁期间甚至会发生重映射吗?根据引导概述 (p.83),它仅发生在 从外部 EEPROM 加载用户程序之后。 【参考方案1】:

我正在尝试了解 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 监控程序

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

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

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

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


AT91RM9200 的启动顺序已针对后续的 AT91SAM SoC 进行了形式化,如下图Linux4SAM 所示。左侧描述代码模块和启动顺序,右侧是物理内存,带有已安装或加载(用箭头表示)的程序。


附录

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

附录#2

有关 U-Boot 开发人员 (Wolfgang Denk) 和 Atmel 工程师 (Ulf Samuelsson) 的明确(和确认)答案,请参阅 this thread。 显着文本是 “对于我从 Atmel 的说明中收集到的信息,总有一个 U-Boot之前的bootloader,从dataflash、串口或[NAND] Flash加载 ..."(除非您从外部 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 不再被执行。执行mtest 0x04000000 0x08000000 测试内存的上半部分行为异常/失败,并表明 U-Boot 是在上层内存之外执行,而不是在其原始加载位置。

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于在 AT91RM9200 上将 U-Boot 从内部 ROM 重新定位到 SRAM的主要内容,如果未能解决你的问题,请参考以下文章

AT91RM9200---定时器简介

如何将jar包手工推到远程仓库

在 Linux 上将 MCU 设置为低功耗模式

51单片机SPI接口是啥?

AT91SAM7S64B解密爱特梅尔系列芯片解密

如何在 i386 上将“推 2000”从 AT&T asm 转换为 Intel 语法