I'm trying to understand relocation of u-boot from internal ROM to SRAM. The below code shows that u-boot is copied from ROM to SRAM and then pc is jumped to _start_armboot. However I'm unable to figure out where the memory remap operation is happening in the code.
Excerpt from 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 data sheet describes that Internal ROM is accessible at address 0x0000_0000 after reset and SRAM is only accessible at address 0x0020_0000. After Remap, the SRAM is also available at address 0x0000_0000 & Internal ROM is accessible at address 0x0010_0000.
Can anyone please help me understand the remap operation in u-boot and show me the code corresponding to this?
Thanks
I'm trying to understand relocation of u-boot from internal ROM to SRAM.
Your query is based on two misunderstandings.
Faulty premise #1: U-Boot is stored in internal ROM
U-Boot is not stored in the internal ROM of the AT91RM9200.
The internal ROM contains proprietary Atmel code that is not published. The AT91RM9200 datasheet describes the functionality of this internal ROM code as the "Boot Program" and the "Boot Uploader".
In the next versions of AT91 SoCs, the AT91SAM926x products, the firmware in the internal ROM are explicitly referred to as the ROM Boot program (aka RomBOOT (sic)) and the SAM-BA Monitor Program.
Faulty premise #2: U-Boot is loaded into SRAM
U-Boot is (typically) not loaded into the embedded SRAM of the AT91RM9200.
The internal SRAM of the AT91RM9200 is too small (only 16KiB minus 3KiB for stack and variables) to contain a (typical) copy of U-Boot.
U-Boot is typically loaded into the external SDRAM by a second-level bootloader (in SRAM) (known as AT91Bootstrap in subsequent AT91SAM products).
On the AT91M9200 (and other AT91SAM products), U-Boot is typically used as a third-level bootloader.
There should be no relocation of U-Boot from internal ROM to ponder when using the AT91M9200.
The boot sequence of the AT91RM9200 was formalized for the subsequent AT91SAM SoCs, and is depicted in the following Linux4SAM diagram. The left side describes code modules and boot sequence, and the right side are physical memories with the installed or loaded (indicated with arrows) programs.
ADDENDUM
Also see this thread on AT91RM9200 bootloaders (to boot into u-boot)
.
The salient text is "... u-boot (Which is too big
for the ROM bootloader to handle)".
There's also mention of an "atmel appnote" apparently about AT91RM9200 bootstrap, but I cannot find it at the Atmel site. Someone has archived this appnote, AT91RM9200DK U-Boot Flash Programming
Solutions, but that board normally boots from external NOR Flash (i.e. BMS=1 which disables the internal ROM).
ADDENDUM #2
See this thread for definitive (and confirming) answers from the U-Boot developer (Wolfgang Denk) and an Atmel engineer (Ulf Samuelsson).
Salient text is "For what I gather from the instructions from Atmel, there is always a
bootloader before U-Boot, loading it from the dataflash, serial port or [NAND] Flash
..." (unless you're booting from external NOR Flash and BMS=1, i.e. disabling the internal ROM).
ADDENDUM #3
Clarification regarding CONFIG_SKIP_RELOCATE_UBOOT:
U-Boot, after being loaded into main memory, may relocate itself to high memory in order to maximize available memory.
For example, I loaded a U-Boot image that was linked to start at 0x03F30000 assuming there was 64MB. However the board actually had 128MB of RAM. I found a duplicate image of U-Boot at 0x07F70000.
Performing a mtest 0x00000000 0x07F00000
tested and overwrote all but the highest megabyte of RAM, and proved that the U-Boot loaded at 0x03F30000 was no longer being executed. Performing a mtest 0x04000000 0x08000000
to test the upper half of memory misbehaved/failed, and indicated that U-Boot was executing out of upper memory and not at its original loaded location.