s5pv210 uboot-2012-10移植(spl的分析)
转载于 : http://7090376.blog.51cto.com/7080376/1265264
http://blog.csdn.net/xiaojiaohuazi/article/details/8265199 // 原地址
我的开发板是TQ210的。s5pv210的启动分为BL0,BL1,BL2,BL0是出厂的时候就固化在IROM里的,所以我们的uboot就要实现BL1和BL2,BL1在uboot里叫做u-boot-spl.bin,BL2就是我们很熟悉的u-boot.bin了。
1.顶层的Makefile,从中可以知道,我们要想生成u-boot-spl.bin就必须配置COFNIG_SPL,那么u-boot-spl.bin依赖什么呢,我们继续
|
1
2
|
ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.binall: $(ALL-y) |
搜索发现,是进入到uboot顶层目录的spl目录下执行Makefile的
|
1
2
|
$(obj)spl/u-boot-spl.bin: depend$(MAKE) -C spl all |
2.打开spl/Makefile分析,一开始就给我们导出CONFIG_SPL_BUILD
|
1
2
|
CONFIG_SPL_BUILD := yexport CONFIG_SPL_BUILD |
然后分析目标,因为我们的平台是三星的,所以,会有两个目标,一个是不带头信息的u-boot-spl.bin,一个是$(obj)$(BOARD)-spl.bin
|
1
2
3
4
5
|
ALL-y += $(obj)u-boot-spl.binifdef CONFIG_SAMSUNGALL-y += $(obj)$(BOARD)-spl.binendifall: $(ALL-y) |
搜索$(obj)$(BOARD)-spl.bin,发现,他是通过一个工具生成带头信息的u-boot-spl.bin
|
1
2
3
4
5
|
ifdef CONFIG_SAMSUNG$(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin$(TOPDIR)/board/$(BOARDDIR)/tools/mk$(BOARD)spl.exe \$(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.binendif |
好了,Makefile就分析到这里,知道了BL1是如何生成的了。下面里分析代码了。
首先分析arch/arm/cpu/armv7/start.S
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
reset:bl save_boot_params/** set the cpu to SVC32 mode*/mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0xd3msr cpsr,r0/* the mask ROM code should have PLL and others stable */#ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_crit#endif/* Set stackpointer in internal RAM to call board_init_f */call_board_init_f:ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ldr r0,=0x00000000bl board_init_f |
其中,cpu_init_crit中主要做初始化了memory和串口,接下来就是调用C函数board_init_f了,在调用C函数之前得设置栈,board_init_f有两个,一个是在arch/arm/lib/board.c,一个在board/samsung/mini210/mmc_boot.c那么道理是那个呢,看各个目录下的Makefile
1.arch/arm/lib/下的
|
1
2
3
4
5
|
ifndef CONFIG_SPL_BUILD...COBJS-y += board.o...endif |
2.board/samsung/mini210/
|
1
2
3
|
ifdef CONFIG_SPL_BUILDCOBJS += mmc_boot.oendif |
得出,是board/samsung/mini210/mmc_boot.c了,打开
|
1
2
3
4
5
6
7
8
9
|
void board_init_f(unsigned long bootflag){__attribute__((noreturn)) void (*uboot)(void);copy_uboot_to_ram();/* Jump to U-Boot image */uboot = (void *)CONFIG_SYS_TEXT_BASE;(*uboot)();/* Never returns Here */} |
得出,首先拷贝BL2完整的UBOOT到RAM里去,然后从ram里开始执行,然后就没有了。那么是如何拷贝的呢,这就得需要一个文档了S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf中


好了,看看copy_uboot_to_ram代码
|
1
2
|
typedef u32(*copy_sd_mmc_to_mem)(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init); |
|
1
2
|
ch = *(volatile u32 *)(0xD0037488);copy_sd_mmc_to_mem copy_bl2 =(copy_sd_mmc_to_mem) (*(u32 *) (0xD0037F98)); |
|
1
2
3
4
5
6
7
8
|
u32 ret;if (ch == 0xEB000000) {ret = copy_bl2(0, MOVI_BL2_POS, MOVI_BL2_BLKCNT,CONFIG_SYS_TEXT_BASE, 0);} else if (ch == 0xEB200000) {ret = copy_bl2(2, MOVI_BL2_POS, MOVI_BL2_BLKCNT,CONFIG_SYS_TEXT_BASE, 0);} |
其中,MOVI_BL2_POS是1,MOVI_BL2_BLKCNT是49,CONFIG_SYS_TEXT_BASE是uboot在内存里的其实地址。
复制完成之后就会在内存里从u-boot.bin的start.S出开始重新执行了。
浙公网安备 33010602011771号