在 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的主要内容,如果未能解决你的问题,请参考以下文章