u-boot-2015.04 在tq2440上的移植(使用spl引导u-boot)
2015-05-31 11:37
330 查看
本次移植跟以往的不同之处是采用了spl来引导u-boot,参考了博客/article/1629823.html
下载链接:http://pan.baidu.com/s/1bnlRKgn
使用方法:
1、编译
maketq2440_defconfig
make
2、然后会在u-boot根目录下生成u-boot.bin,在spl目录下会生成u-boot-spl.bin,目前的分区是:
自己可以改动,在arch/arm/lib/crt0.S中:
#ifdefined(CONFIG_SPL_BUILD)
/*Readu-bootfromNandflashtoSDRAMaddress$CONFIG_SYS_TEXT_BASE*/
ldrr0,=CONFIG_UBOOT_MTD_ADDR/*u-boot镜像在NandFlash中存储地址*/
ldrr1,=CONFIG_SYS_TEXT_BASE/*u-boot在内存中的加载地址*/
ldrr2,=CONFIG_UBOOT_LENGTH/*u-boot镜像的大小*/
blcopy_code_to_sdram
ldrpc,=CONFIG_SYS_TEXT_BASE
#else
blboard_init_f
#endif
3、目前支持NandFlash和DM9000。
4、为什么要用spl来引导u-boot?
对于tq2440,采用的是S3C2440,当从NandFlash启动时,上电时S3C2440内部固化的程序自动把NandFlash的前4KB程序拷贝到片内SRAM,然后执行IRAM中的程序,同时要保证这4KB中的程序是位置无关码,在这4KB程序完成了内存的初始化,栈的设置,NandFlash的初始化,将u-boot镜像从NandFlash中拷贝到内存中,将PC跳转到内存中执行。
随着u-boot的更新,在u-boot的前4K已经无法完成上面这些事,在前4KB会执行位置相关码,导致u-boot无法正常运行。
为了解决这个问题,u-boot提供了SPL,用spl来引导u-boot,spl的体积很小,只完成将u-boot从NandFlash中拷贝到内存中,然后跳转到内存。
5、可能存在的问题:
由于从NandFlash启动的时候,IRAM被映射到了0地址处,现在是用spl引导u-boot,所以IRAM中是spl,如果有中断发生,PC执行的是spl中程序,而不是u-boot中的,可以考虑u-boot启动后,在将u-boot的前4KB拷贝到IRAM中。
后来再次阅读了u-boot代码,发现上面的这个担心纯属多余,这个u-boot在代码重定位,并且修改完相关的符号信息后,紧接着又将中断向量也进行了重定位,即将最终u-boot代码段在内存中运行起始地址的前64字节拷贝到了SRAM的0x0处,这样如果发生了中断也不用怕跳飞了。
下面我们简单看一下:
相关代码路径:
中断向量表:arch/arm/lib/vectors.S
复位异常入口:arch/arm/cpu/arm920t/start.S
_main:arch/arm/lib/crt0.S
board_init_f:common/board_f.c
relocate_code:arch/arm/lib/relocate.S
relocate_vectors:arch/arm/lib/relocate.S
board_init_r:common/board_r.c
main_loop:common/main.c
cli_loop:common/cli.c
parse_file_outer:common/cli_hush.c
crt0.S:
[/code]
relocate_code和relocate_vectors:
[/code]
这个关于relocation原理的解析参考博客:
完!
下载链接:
使用方法:
1、编译
maketq2440_defconfig
make
2、然后会在u-boot根目录下生成u-boot.bin,在spl目录下会生成u-boot-spl.bin,目前的分区是:
u-boot-spl.bin (1M) | u-boot.bin (1M) | kernel (3M) | rootfs (剩余) |
#ifdefined(CONFIG_SPL_BUILD)
/*Readu-bootfromNandflashtoSDRAMaddress$CONFIG_SYS_TEXT_BASE*/
ldrr0,=CONFIG_UBOOT_MTD_ADDR/*u-boot镜像在NandFlash中存储地址*/
ldrr1,=CONFIG_SYS_TEXT_BASE/*u-boot在内存中的加载地址*/
ldrr2,=CONFIG_UBOOT_LENGTH/*u-boot镜像的大小*/
blcopy_code_to_sdram
ldrpc,=CONFIG_SYS_TEXT_BASE
#else
blboard_init_f
#endif
3、目前支持NandFlash和DM9000。
4、为什么要用spl来引导u-boot?
对于tq2440,采用的是S3C2440,当从NandFlash启动时,上电时S3C2440内部固化的程序自动把NandFlash的前4KB程序拷贝到片内SRAM,然后执行IRAM中的程序,同时要保证这4KB中的程序是位置无关码,在这4KB程序完成了内存的初始化,栈的设置,NandFlash的初始化,将u-boot镜像从NandFlash中拷贝到内存中,将PC跳转到内存中执行。
随着u-boot的更新,在u-boot的前4K已经无法完成上面这些事,在前4KB会执行位置相关码,导致u-boot无法正常运行。
为了解决这个问题,u-boot提供了SPL,用spl来引导u-boot,spl的体积很小,只完成将u-boot从NandFlash中拷贝到内存中,然后跳转到内存。
5、可能存在的问题:
由于从NandFlash启动的时候,IRAM被映射到了0地址处,现在是用spl引导u-boot,所以IRAM中是spl,如果有中断发生,PC执行的是spl中程序,而不是u-boot中的,可以考虑u-boot启动后,在将u-boot的前4KB拷贝到IRAM中。
后来再次阅读了u-boot代码,发现上面的这个担心纯属多余,这个u-boot在代码重定位,并且修改完相关的符号信息后,紧接着又将中断向量也进行了重定位,即将最终u-boot代码段在内存中运行起始地址的前64字节拷贝到了SRAM的0x0处,这样如果发生了中断也不用怕跳飞了。
下面我们简单看一下:
相关代码路径:
中断向量表:arch/arm/lib/vectors.S
复位异常入口:arch/arm/cpu/arm920t/start.S
_main:arch/arm/lib/crt0.S
board_init_f:common/board_f.c
relocate_code:arch/arm/lib/relocate.S
relocate_vectors:arch/arm/lib/relocate.S
board_init_r:common/board_r.c
main_loop:common/main.c
cli_loop:common/cli.c
parse_file_outer:common/cli_hush.c
crt0.S:
[code]#if!defined(CONFIG_SPL_BUILD)
/*
*Setupintermediateenvironment(newspandgd)andcall
*relocate_code(addr_moni).Trickhereisthatwe'llreturn
*'here'butrelocated.
*/
ldrsp,[r9,#GD_START_ADDR_SP]/*sp=gd->start_addr_sp*/
bicsp,sp,#7/*8-bytealignmentforABIcompliance*/
ldrr9,[r9,#GD_BD]/*r9=gd->bd*/
subr9,r9,#GD_SIZE/*newGDisbelowbd*/
adrlr,here
ldrr0,[r9,#GD_RELOC_OFF]/*r0=gd->reloc_off*/
addlr,lr,r0
ldrr0,[r9,#GD_RELOCADDR]/*r0=gd->relocaddr*/
brelocate_code
here:
/*
*nowrelocatevectors
*/
blrelocate_vectors
[/code]
relocate_code和relocate_vectors:
[code]ENTRY(relocate_vectors)
/*
*Copytherelocatedexceptionvectorstothe
*correctaddress
*CP15c1Vbitgivesusthelocationofthevectors:
*0x00000000or0xFFFF0000.
*/
ldrr0,[r9,#GD_RELOCADDR]/*r0=gd->relocaddr*/
mrcp15,0,r2,c1,c0,0/*Vbit(bit[13])inCP15c1*/
andsr2,r2,#(1<<13)
ldreqr1,=0x00000000/*IfV=0*/
ldrner1,=0xFFFF0000/*IfV=1*/
ldmiar0!,{r2-r8,r10}
stmiar1!,{r2-r8,r10}
ldmiar0!,{r2-r8,r10}
stmiar1!,{r2-r8,r10}
bxlr
ENDPROC(relocate_vectors)
ENTRY(relocate_code)
ldrr1,=__image_copy_start/*r1<-SRC&__image_copy_start*/
subsr4,r0,r1/*r4<-relocationoffset*/
beqrelocate_done/*skiprelocation*/
ldrr2,=__image_copy_end/*r2<-SRC&__image_copy_end*/
copy_loop:
ldmiar1!,{r10-r11}/*copyfromsourceaddress[r1]*/
stmiar0!,{r10-r11}/*copytotargetaddress[r0]*/
cmpr1,r2/*untilsourceendaddress[r2]*/
blocopy_loop
/*
*fix.rel.dynrelocations
*/
ldrr2,=__rel_dyn_start/*r2<-SRC&__rel_dyn_start*/
ldrr3,=__rel_dyn_end/*r3<-SRC&__rel_dyn_end*/
fixloop:
ldmiar2!,{r0-r1}/*(r0,r1)<-(SRClocation,fixup)*/
andr1,r1,#0xff
cmpr1,#23/*relativefixup?*/
bnefixnext
/*relativefix:increaselocationbyoffset*/
addr0,r0,r4
ldrr1,[r0]
addr1,r1,r4
strr1,[r0]
fixnext:
cmpr2,r3
blofixloop
relocate_done:
[/code]
这个关于relocation原理的解析参考博客:
uboot的relocation原理详细分析
相关文章推荐
- EMA计算的C#实现(c# Exponential Moving Average (EMA) indicator )
- .net mvc 防止 xss 与 CSRF
- Java语法错误之-执行不到的代码(Unreachable code)
- Codeforces Round #305 (Div.2) D
- Linux驱动的platform机制
- 忘记普通登陆密码解决方式
- 如何反编译Android程序
- LeetCode Happy Number
- 过滤器链
- C++11 新特性整理
- Cornerstone详细操作
- SSDT-BI之九:数据流任务
- in和exist
- [转]深入理解JavaScript系列
- 戴尔第13代服务器 iDRAC8 远程管理卡升级成企业版的办法
- java范型的应用
- mark-点滴积累-字符串比较compare继承与重写
- 持续添加
- 验证信息格式
- Linux下执行py文件