本次移植的目的:
1.u-boot能够跑起来
2.能够进入控制台打印出如下信息
本次移植是基于官方的u-boot版本是u-boot-2012.10,温馨提示,如果是新手可以完全按照这个步骤走就行。好,下面开始。
第一步,修改u-boot-2012.10根目录下的boards.cfg文件,用gedit打开该文件,使用搜索功能,搜索文件smdkc100定位到这里,然后另起一行,拷贝smdkc100这行,复制到下面一行中,然后把smdkc100修改为real210,如下图所示:
第二步,建立real210文件夹
进入到目录/board/samsung/把smdkc100文件夹里所有的文件拷贝到当前目录下的real210文件夹,如下图所示:
第三步,建立real210.h文件
进入/include/configs,把smdkc100.h拷贝到real210.h中,具体的拷贝方式,大家自行选择,只要完整正确拷贝即可。
第四步,修改根目录下Makefile
打开Makefile文件,找到CROSS_COMPILE ?=这个位置,修改为:
CROSS_COMPILE ?=arm-linux-
注意,上面的这个修改需要你的系统已做好了arm-liunx-gcc编译器的安装以及环境变量的设置,如果没有需要加入编译器的路径,如/usr/local/arm/arm-2009q3/bin/arm-linux-。
第五步,修改board/samsung/smdkv210/lowlevel_init.S
由于我们在BL1已经做了串口和内存的初始化,所以在u-boot中就不需要进行初始化了,这里需要把u-boot中这部分代码给屏蔽掉。
注释掉lowlevel_init.S文件中第42行到第85行。
第六步,修改start.S
在BL1阶段只做了u-boot.bin的拷贝,并没有清除BSS,所以需要在start.S文件中增加该代码。
reset:
clear_bss:
//BSS清除,由用户添加
ldr r0, =__bss_start
ldr r1, =__bss_end__
mov r2, #0x0
clbss_l:
str r2, [r0],#4
cmp r0, r1
bne clbss_l
//BSS清除,由用户添加
bl save_boot_params
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0
/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
* Continue to use ROM code vector only in OMAP4 spl)
*/
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
/* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTRL Register
bic r0, #CR_V @ V = 0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTRL Register
/* Set vector address in CP15 VBAR register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#endif
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_ini _cp15
bl cpu_init_crit
#endif
在该文件中还要对 ENTRY(relocate_code) 进行修改,这部分是 u-boot 的搬运操作,由于我们已经拷贝到制定的内存,我们不在需要搬移了,所以这里做如下修改:整个函数代码如下:
ENTRY(relocate_code)
mov r4, r0 /* save addr_sp */
mov r5, r1 /* save addr of gd */
mov r6, r2 /* save addr of destination */
//用户添加,跳转到board_init_r函数执行
mov sp, r4
mov r0, r5
mov r1, r6
bl board_init_r
//用户添加,跳转到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
第七步,修改SDRAM基地址include/configs/smdkv210.h +51,修改如下:
#defineCONFIG_SYS_SDRAM_BASE 0x30000000
由于我要使用的地址就是0x30000000所以我不必修改,如果你的板子基地址不是,请修改之。
第八步,修改内存的Banks设置,include/configs/smdkv210.h+186
修改为如下所示:
/* SMDKC100 has 1 banks of DRAM, we use only one in U-Boot */
//#define CONFIG_NR_DRAM_BANKS 1
//#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE /* SDRAM Bank #1 */
//#define PHYS_SDRAM_1_SIZE (128 << 20) /* 0x8000000, 128 MB Bank #1 */
/* SMDKC100 has 2 banks of DRAM */
#define CONFIG_NR_DRAM_BANKS 2 /* we have 1 bank of DRAM */
#define SDRAM_BANK_SIZE 0x10000000 /* 256 MB */
#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE
#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) /* SDRAM Bank #2 */
#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE
第九步,修改board/samsung/real210/smdkc100.c 中void dram_init_banksize(void)函数,修改成所示:
void dram_init_banksize(void)
{
/*gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;*/
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
}
该函数是用于计算内存的总量。
第十步,修改board/samsung/real210/smdkc100.c中int dram_init(void)函数成如下所示:
int dram_init(void)
{
//gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE;
return 0;
}
第十一步,还是修改board/samsung/real210/smdkc100.c该文件,函数是下面两个,修改成下面所示的即可:
int board_init(void)
{
//smc9115_pre_init();
gd->bd->bi_arch_number = MACH_TYPE_SMDKC100;
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
return 0;
}
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_SMC911X
//rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
#endif
return rc;
}
上面主要是注释掉smc9115_pre_init(); 和smc911x_initialize(0, CONFIG_SMC911X_BASE);因为我们没有smc911网络,所以不需要。
int checkboard(void)
{
printf("Board:\treal210\n");
return 0;
}
smdkc100.c这个文件已经修改完成,后面不再修改。
第十二步,修改sp指针,在include/configs/smdkv210.h修改,搜索CONFIG_SYS_INIT_SP_ADDR文字,修改成如下所示:
//#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR + 0x10000000)
第十三步,在include/configs/smdkv210.h修改,搜索CONFIG_SYS_PROMPT文字,修改成如下:
//#define CONFIG_SYS_PROMPT "SMDKC100 # "
#define CONFIG_SYS_PROMPT "REAL210 # "
第十四步,在include/configs/smdkv210.h修改,搜索CONFIG_SERIAL文字,修改成如下:
//#define CONFIG_SERIAL0 1 /* use SERIAL 0 on SMDKC100 */
#define CONFIG_SERIAL2 1 /* use SERIAL 2 on REAL210 */
第十五步,在include/configs/smdkv210.h修改,搜索CONFIG_IDENT_STRING文字,修改成如下:
//#define CONFIG_IDENT_STRING " for SMDKC100"
#define CONFIG_IDENT_STRING " for REAL210"
第十六步,在include/configs/smdkv210.h修改,搜索CONFIG_ENV_IS_IN_ONENAND文字,修改成如下:
//#define CONFIG_ENV_IS_IN_ONENAND 1
#define CONFIG_ENV_IS_NOWHERE 1
第十七步,在include/configs/smdkv210.h修改,搜索CONFIG_CMD_ONENAND文字,修改成如下:
//#define CONFIG_CMD_ONENAND
#undef CONFIG_CMD_ONENAND
因为开发板上无onenand,所以不进行定义。
第十八步,修改board/samsung/smdkv210/config.mk,修改为:
1. CONFIG_SYS_TEXT_BASE = 0x33e00000
第十九步,修改 arch/arm/config.mk+88,注释掉该行(网上解释的原因是:原来的代码在链接时加了"-pie"选项, 使得u-boot.bin里多了"*(.rel*)","*(.dynsym)",使得程序非常大,不利于从NAND启动(重定位之前的启动代码应该少于4K),目前不太明白,有待研究。),修改后如下:
1. #LDFLAGS_u-boot += -pie
好,到这里我们可以进行试着编译了,看看是否能够正常编译通过。
第二十步,编译测试
打开终端进入到u-boot-2012.10的根目录下,输入makereal210_config命令进行先配置。如下图所示:
配置成功,注意这里只在官方源码中修改了上面步骤,其他地方没有任何更改,输入make指令进行编译。完成后会在根目录下得到u-boot.bin文件。当然这时的u-boot仅仅实现了能够跑起来的功能。
下载到SD卡的测试命令为:
dd iflag=dsyncoflag=dsync if=u-boot.binof=/dev/sdb seek=49
放到SD卡看看是不是有下面的效果呢。
如果上述成功完成,那么下面可以再做一个小小的修改。
把board/samsung/real210/目录下的smdkc100.c文件名修改成real210.c
打开board/samsung/ real210/目录下的Makefile文件,把所有的smdkc100修改成real210。
OK,第二弹完成。