我试图了解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,只能在地址0x0020_0000访问SRAM。重映射后,SRAM也可在地址0x0000_0000&amp;可以在地址0x0010_0000访问内部ROM。
任何人都可以帮我理解u-boot中的重映射操作并向我显示与此对应的代码吗?
由于
答案 0 :(得分:1)
我试图了解u-boot从内部ROM重新定位到SRAM。
您的查询基于两个误解。
错误的前提#1 :U-Boot存储在内部ROM中
U-Boot未存储在AT91RM9200的内部ROM中 内部ROM包含未发布的专有Atmel代码。 AT91RM9200数据表描述了这个内部ROM代码的功能,作为&#34;引导程序&#34;和#34; Boot Uploader&#34;。
在下一版本的AT91 SoC中,AT91SAM926x产品,内部ROM中的固件明确称为 ROM Boot 程序(又名 RomBOOT (原文如此) )和 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)
上的这个主题
突出的文字是&#34; ... u-boot(这太大了
用于ROM引导程序处理)&#34; 。
还提到了&#34; atmel appnote&#34; 显然是关于AT91RM9200引导程序,但我在Atmel网站上找不到它。有人已经存档了这个appnote AT91RM9200DK U-Boot Flash Programming
Solutions,但该板通常从外部NOR Flash启动(即BMS = 1,禁用内部ROM)。
ADDENDUM#2
请参阅this thread以获取U-Boot开发人员(Wolfgang Denk)和Atmel工程师(Ulf Samuelsson)的最终(并确认)答案。
突出的文字是&#34;对于我从Atmel的指示中收集的内容,总有一个
U-Boot之前的bootloader,从dataflash,串口或[NAND] Flash加载它
......&#34; (除非您从外部NOR Flash启动并且BMS = 1,即禁用内部ROM)。
ADDENDUM#3
关于CONFIG_SKIP_RELOCATE_UBOOT的澄清:
U-Boot在加载到主存储器后,可以将自身重新定位到高内存,以便最大化可用内存
例如,我加载了一个U-Boot映像,该映像被链接到0x03F30000,假设有64MB。然而,该板实际上有128MB的RAM。我在0x07F70000找到了U-Boot的重复图像
执行mtest 0x00000000 0x07F00000
测试并覆盖除最高兆字节RAM之外的所有RAM,并证明在0x03F30000处加载的U-Boot不再被执行。执行mtest 0x04000000 0x08000000
以测试内存不正常/失败的上半部分,并指示U-Boot正在高端内存执行,而不是在其原始加载位置。
答案 1 :(得分:0)
我怀疑这个代码,如果它在ROM中,已被编译/汇编为在RAM中的特定地址运行(无论SRAM或SDRAM是无关紧要的)。您发布的代码段是使用与位置无关的代码编写的。位置无关代码将自身复制到RAM,然后加载具有实际RAM地址的PC以执行下一步。你的代码片段没有显示_start_armboot的位置,但我的猜测是标签在下一条指令上。这里没有硬件重映射。 您可以通过单步执行代码来证明这一点。首先,调试器可能只能向您显示反汇编指令,直到您逐步执行“ldr pc,_start_armboot”指令时,实际源将会神奇地出现(至少GDB会这样做)。