Uboot二进制镜像分析:
在文件board/samsung/smdkc110/config.mk里面定义了uboot的基地址:
TEXT_BASE = 0xc3e00000
在文件board/samsung/smdkc110/u-boot.lds里面定义了uboot链接格式:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/s5pc11x/start.o
(.text)
cpu/s5pc11x/s5pc110/cpu_init.o
(.text)
board/samsung/smdkc110/lowlevel_init.o
(.text)
cpu/s5pc11x/onenand_cp.o (.text)
cpu/s5pc11x/nand_cp.o (.text)
cpu/s5pc11x/movi.o (.text)
board/samsung/smdkc110/flash.o (.text)
common/secure.o (.text)
common/ace_sha1.o (.text)
cpu/s5pc11x/pmic.o (.text)
*(.text)
}
…
}
S5pv210如果设置从SD卡启动,则IROM先探测channel 0和后探测channel 2,从中读取有效BL1(uboot的BL1跟Uboot是在一个文件里,对于wince eboot和bl1是分开的两个文件)。
BL1的分析
typedef u32(*copy_sd_mmc_to_mem)
void movi_bl2_copy(void)
{
ulong ch;
#if defined(CONFIG_EVT1)
//0xD0037488是位于IRAM的地址,尽管没有文档说明,但是,显然IROM把从channel 0还是channel 2启动的信息放在了0xD0037488
ch = *(volatile u32 *)(0xD0037488);
//BL1这么小显然没有实现SD驱动,但是IROM实现了SD驱动,而且把使用SD驱动拷贝的函数放在了地址(0xD0037F98),将函数指针copy_sd_mmc_to_mem copy_bl2指向这里。
copy_sd_mmc_to_mem copy_bl2 =
(copy_sd_mmc_to_mem) (*(u32 *) (0xD0037F98));
…
#else
…
#endif
u32 ret;
// channel 0是启动盘
if (ch == 0xEB000000) {
//把uboot拷进DDR2内存
ret = copy_bl2(0, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
CFG_PHY_UBOOT_BASE, 0);
…
}
// channel 2是启动盘
else if (ch == 0xEB200000) {
//把uboot拷进DDR2内存
ret = copy_bl2(2, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
CFG_PHY_UBOOT_BASE, 0);
…
}
else
return;
…
}
跳入uboot的准备
Uboot代码使用的是虚拟地址,首先要把mmu打开,mmu_table在uboot_smdkv210/board/samsung/smdkc110/lowlevel_init.S里面,以静态数组的形式定义,其中虚拟地址:0xC000_0000 -- 0xC7FF_FFFF 映射到DDR2的起始地址,其中注释里面指出映射到0x30000000并不全对,如果是DDR2物理地址在0x30000000的board,的确是这样。但是DDR2物理地址在0x20000000的board被映射到0x20000000,注释有误。
after_copy:
#if defined(CONFIG_ENABLE_MMU)
enable_mmu:
/* enable domain access */
ldr
r5, =0x0000ffff
mcr
p15, 0, r5, c3, c0, 0
@load domain access register
/* Set the TTB register */
ldr
r0, _mmu_table_base
ldr
r1, =CFG_PHY_UBOOT_BASE
ldr
r2, =0xfff00000
bic
r0, r0, r2
orr
r1, r0, r1
mcr
p15, 0, r1, c2, c0, 0
/* Enable the MMU */
mmu_on:
mrc
p15, 0, r0, c1, c0, 0
orr
r0, r0, #1
mcr
p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
#endif
skip_hw_init:
/* Set up the stack
*/
stack_setup:
#if defined(CONFIG_MEMORY_UPPER_CODE)
ldr
sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
#else
ldr
r0, _TEXT_BASE
/* upper 128 KiB: relocated uboot */
sub
r0, r0, #CFG_MALLOC_LEN
/* malloc area */
sub
r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#if defined(CONFIG_USE_IRQ)
sub
r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub
sp, r0, #12
/* leave 3 words for abort-stack */
#endif
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
//从这里跳入uboot
ldr
pc, _start_armboot
//这里放着uboot的入口地址
_start_armboot:
.word start_armboot