这次我们将从官网下载的最新uboot-2012-10移植到s5pv210开发板上,让其进入控制台,效果如下:
首先,我暂时没采用内核的SPL,这个将在后面给补上,这里的BL1是我自己参考资料写的,我用的是QT210开发板,内存1G,对于不同的开发板,需要重新配置memory和修改uboot在内存里的地址,也就是CONFIG_SYS_TEXT_BASE。我的BL1代码在这里下载。
一、添加smdkv210单板
1.cp -a board/samsung/smdkc100 board/samsung/smdkv210
2.cp include/configs/smdkc100.h include/configs/smdkv210.h
3.vim boards.cfg,在270行添加
270 smdkv210 arm armv7 smdkv210 samsung s5pc1xx
4.make smdkv210_config可以生成u-boot.bin了
二、让u-boot.bin在内存里启动起来
1.分析我的BL1代码可以得知,只拷贝了u-boot.bin,并没有清楚bss,在ls arch/arm/cpu/armv7/start.S +126中添加
reset: //by ZheGao clear bss ldr r0, =__bss_start ldr r1, =__bss_end__ mov r2, #0x0 1: str r2, [r0], #4 cmp r0, r1 bne 1b //end of clear bss bl save_boot_params
2.在BL0已经关了看门狗,在BL1里已经初始化了memory和串口,修改board/samsung/smdkv210/lowlevel_init.S +39中给屏蔽
.globl lowlevel_init lowlevel_init: mov r9, lr #if 0 /* r5 has always zero */ mov r5, #0 ldr r8, =S5PC100_GPIO_BASE /* Disable Watchdog */ ldr r0, =S5PC100_WATCHDOG_BASE @0xEA200000 orr r0, r0, #0x0 str r5, [r0] /* setting SRAM */ ldr r0, =S5PC100_SROMC_BASE ldr r1, =0x9 str r1, [r0] /* S5PC100 has 3 groups of interrupt sources */ ldr r0, =S5PC100_VIC0_BASE @0xE4000000 ldr r1, =S5PC100_VIC1_BASE @0xE4000000 ldr r2, =S5PC100_VIC2_BASE @0xE4000000 /* Disable all interrupts (VIC0, VIC1 and VIC2) */ mvn r3, #0x0 str r3, [r0, #0x14] @INTENCLEAR str r3, [r1, #0x14] @INTENCLEAR str r3, [r2, #0x14] @INTENCLEAR /* Set all interrupts as IRQ */ str r5, [r0, #0xc] @INTSELECT str r5, [r1, #0xc] @INTSELECT str r5, [r2, #0xc] @INTSELECT /* Pending Interrupt Clear */ str r5, [r0, #0xf00] @INTADDRESS str r5, [r1, #0xf00] @INTADDRESS str r5, [r2, #0xf00] @INTADDRESS /* for UART */ bl uart_asm_init /* for TZPC */ bl tzpc_asm_init 1: #endif mov lr, r9 mov pc, lr
3.修改第一步的sp指针,在include/configs/smdkv210.h +228修改
//#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) #define CONFIG_SYS_INIT_SP_ADDR (0x30000000)
4.修改board/samsung/smdkv210/smdkc100.c +80
int checkboard(void) { printf("Board:\tSMDKv210\n"); return 0; }
5.修改include/configs/smdkv210.h +51
//#define CONFIG_SYS_SDRAM_BASE 0x30000000 #define CONFIG_SYS_SDRAM_BASE 0x20000000
6.修改include/configs/smdkv210.h +189
//#define PHYS_SDRAM_1_SIZE (128 << 20) /* 0x8000000, 128 MB Bank #1 */ #define PHYS_SDRAM_1_SIZE (0x40000000) /* 0x8000000, 128 MB Bank #1 */
7.修改board/samsung/smdkv210/config.mk +16
CONFIG_SYS_TEXT_BASE = 0x5ff00000
8.修改 arch/arm/config.mk +88
#LDFLAGS_u-boot += -pie
9.修改include/configs/smdkv210.h +216
//#define CONFIG_ENV_IS_IN_ONENAND 1 #define CONFIG_ENV_IS_NOWHERE
10.修改arch/arm/lib/board.c +384
//addr -= gd->mon_len; addr = 0x5ff00000;
11.因为bl1已经复制程序到指定的地址就不需要重新定位代码了,但还是需要重新设置栈,所以修改了上面的第8步,修改arch/arm/cpu/armv7/start.S +192
ENTRY(relocate_code) mov r4, r0 /* save addr_sp */ mov r5, r1 /* save addr of gd */ mov r6, r2 /* save addr of destination */ #if 0 //debug ldr r0, =0xE0200C00 ldr r1, =0x1111 str r1, [r0] ldr r0, =0xE0200C04 ldr r1, =(7) str r1, [r0] #endif mov sp, r4 mov r0, r5 mov r1, r6 bl board_init_r #if 0 /* Set up the stack */ stack_setup: mov sp, r4 adr r0, _start cmp r0, r6 moveq r9, #0 /* no relocation. relocation offset(r9) = 0 */ beq clear_bss /* skip relocation */ mov r1, r6 /* r1 <- scratch for copy_loop */ ldr r3, _image_copy_end_ofs add r2, r0, r3 /* r2 <- source end address */ copy_loop: ldmia r0!, {r9-r10} /* copy from source address [r0] */ stmia r1!, {r9-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end address [r2] */ blo copy_loop /* * fix .rel.dyn relocations */ ldr r0, _TEXT_BASE /* r0 <- Text base */ sub r9, r6, r0 /* r9 <- relocation offset */ ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ add r10, r10, r0 /* r10 <- sym table in FLASH */ ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ add r0, r0, r9 /* r0 <- location to fix up in RAM */ ldr r1, [r2, #4] and r7, r1, #0xff cmp r7, #23 /* relative fixup? */ beq fixrel cmp r7, #2 /* absolute fixup? */ beq fixabs /* ignore unknown type of fixup */ b fixnext fixabs: /* absolute fix: set location to (offset) symbol value */ mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ add r1, r10, r1 /* r1 <- address of symbol in table */ ldr r1, [r1, #4] /* r1 <- symbol value */ add r1, r1, r9 /* r1 <- relocated sym addr */ b fixnext fixrel: /* relative fix: increase location by offset */ ldr r1, [r0] add r1, r1, r9 fixnext: str r1, [r0] add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop b clear_bss _rel_dyn_start_ofs: .word __rel_dyn_start - _start _rel_dyn_end_ofs: .word __rel_dyn_end - _start _dynsym_start_ofs: .word __dynsym_start - _start clear_bss: ldr r0, _bss_start_ofs ldr r1, _bss_end_ofs mov r4, r6 /* reloc addr */ add r0, r0, r4 add r1, r1, r4 mov r2, #0x00000000 /* clear */ clbss_l:cmp r0, r1 /* clear loop... */ bhs clbss_e /* if reached end of bss, exit */ str r2, [r0] add r0, r0, #4 b clbss_l clbss_e: /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ jump_2_ram: /* * If I-cache is enabled invalidate it */ #ifndef CONFIG_SYS_ICACHE_OFF mcr p15, 0, r0, c7, c5, 0 @ invalidate icache mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB #endif /* * Move vector table */ #if !defined(CONFIG_TEGRA20) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR #endif /* !Tegra20 */ ldr r0, _board_init_r_ofs adr r1, _start add lr, r0, r1 add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r6 /* dest_addr */ /* jump to it ... */ mov pc, lr _board_init_r_ofs: .word board_init_r - _start #endif ENDPROC(relocate_code) #endif
重新make一下,使用下面命令烧写到sd卡里,插入开发板启动即可,看看上面的启动信息,还有很多很多地方要完善~
dd iflag=dsync oflag=dsync if=blSD.bin of=/dev/sdb seek=1 dd iflag=dsync oflag=dsync if=u-boot.bin of=/dev/sdb seek=49