移植uboot第四步:设置NAND启动
2016-08-11 01:12
381 查看
移植的uboot使用NOR启动,不支持NAND,这次就是修改代码以支持NAND。
之前uboot的Makefile里面有-pie,前面写到了,这是为了生成位置无关码,代码可以copy到任何地方。因为代码段里面是有变量的,程序去读取变量的时候要知道变量的存放地址,你移到别的地方,变量的存储位置肯定会变。位置无关就是额外在一块内存区域中存放变量的地址信息,当移动代码的时候,要去读取这块区域,重新修改变量的读取地址。
1.去掉“pie选项”。
设置NAND启动的时候,cpu会自动从NAND里面读取4k代码到片内内存,所以设置pie的话,代码的体积会比较大,不利于复制到片内内存,重定位之前的代码应该少于4k。
现在不清楚这个pie在哪,所以命令:
看起来第二个比较像,所以打开第二个文件:
找到LDFLAGS_u-boot += -pie,前面加上#注释掉,保存退出。这样应该把pie选项去掉了,实际等make完以后,看看链接文件就能知道了。
2.添加NAND代码。之前写过NAND的代码,直接将文件init放到
将这个文件添加到SI工程里。找到start.S,一路往下看,设置时钟之后是板子片内各种资源的初始化,我把NAND的代码放到时钟和资源初始化中间。
a.要做一些修改,因为调用了C函数,要设置栈,下面板子资源初始化也调用了C,直接将它的栈设置拿过来
然后跳转到nand_init初始化nand。uboot里面有很多nand_init重名函数,将其修改为nand_init_ll。其他不用修改。
b.调用copy_code_to_sdram的时候有三个参数,第一个是0不变,第二个是代码的初始位置。之前写了_start,但是这是一条伪汇编指令,如果_start这个值很复杂,编译的时候可能把这个值放到别的合适的位置,就可能不在4k以内了,cpu复制4k到片内内存以后,可能就没有复制_start这个值,程序执行的时候就懵逼了,要代码重定位,找不到第二个参数了。所以为了保证在4k内,人为写一个值(猜测这样子这条代码就不算伪汇编,保存的地址就可以保证在4K内)。实际上
两种写法意思是一样的,只是担心出问题。所以改为
ldr r1, _TEXT_BASE
_TEXT_BASE有定义:
把CONFIG_SYS_TEXT_BASE 值改为0x33f00000
因为内存一共64M,就是34000000,在内存的顶部是uboot的存放空间,这里给uboot留了1M的空间,让代码copy进去。64M-1M=0x33f00000。
copy_code_to_sdram的第三个参数是copy的长度,查看start.S可以看到
_bss段是存放初始值为0的变量,bss段的文件是不会存在在bin文件里面的,所以__bss_start - _start就是二进制文件的长度。copy的长度就写为_bss_start_ofs。
copy_code_to_sdram文件内部查看以后发现不需要修改
clear_bss需要修改一些值。
源文件的bss段的结束地址定义为bss_end,在这个uboot中为__bss_end,修改即可。
因此汇编中的代码段改为,同时去掉原先的clear_bss
同时clear_bss改为
c.去掉自带的重定位代码。
进入board_init_f函数,找到relocate_code(addr_sp, id, addr);注释掉。
因为后面的代码是在SDRAM,bl是相对跳转指令,使用
这样一下就从片内内存跳到SDRAM中了。
d.下面是调用第二阶段的代码。
有两个参数gd_t *gd, ulong dest_addr。ID和目的地址。目的地址就是程序的链接地址。
ID可以观察到在board_init_f中有获得,直接添加返回值为id。返回值存在r0,就省得我们再做别的事了。
e.差不多改完了,把init文件添加进uboot,
在COBJS := smdk2410.o这句话后面加上init.o
保存退出。
f.修改链接脚本,把Start.o init之类的文件放到代码的最前头,这样能保证需要的代码都在4k里。
将
g:编译,有一些错误,比如之前增加了board_init_f的返回值,原先是没有的,改一下就行了。
h.烧到NAND,启动,成功
之前uboot的Makefile里面有-pie,前面写到了,这是为了生成位置无关码,代码可以copy到任何地方。因为代码段里面是有变量的,程序去读取变量的时候要知道变量的存放地址,你移到别的地方,变量的存储位置肯定会变。位置无关就是额外在一块内存区域中存放变量的地址信息,当移动代码的时候,要去读取这块区域,重新修改变量的读取地址。
1.去掉“pie选项”。
设置NAND启动的时候,cpu会自动从NAND里面读取4k代码到片内内存,所以设置pie的话,代码的体积会比较大,不利于复制到片内内存,重定位之前的代码应该少于4k。
现在不清楚这个pie在哪,所以命令:
grep "\-pie" * -R,返回
arch/x86/config.mk:LDFLAGS_FINAL += --gc-sections -pie arch/arm/config.mk:LDFLAGS_u-boot += -pie doc/README.arm-relocation:At arch level: add linker flag -pie
看起来第二个比较像,所以打开第二个文件:
vi arch/arm/config.mk
找到LDFLAGS_u-boot += -pie,前面加上#注释掉,保存退出。这样应该把pie选项去掉了,实际等make完以后,看看链接文件就能知道了。
2.添加NAND代码。之前写过NAND的代码,直接将文件init放到
\board\samsung\smdk2440
将这个文件添加到SI工程里。找到start.S,一路往下看,设置时钟之后是板子片内各种资源的初始化,我把NAND的代码放到时钟和资源初始化中间。
/* 重定位 */ ldr sp, =0x34000000 bl nand_init mov r0, #0 ldr r1, =_start ldr r2, = __bss_start sub r2, r2, r1 bl copy_code_to_sdram bl clear_bss
a.要做一些修改,因为调用了C函数,要设置栈,下面板子资源初始化也调用了C,直接将它的栈设置拿过来
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
然后跳转到nand_init初始化nand。uboot里面有很多nand_init重名函数,将其修改为nand_init_ll。其他不用修改。
b.调用copy_code_to_sdram的时候有三个参数,第一个是0不变,第二个是代码的初始位置。之前写了_start,但是这是一条伪汇编指令,如果_start这个值很复杂,编译的时候可能把这个值放到别的合适的位置,就可能不在4k以内了,cpu复制4k到片内内存以后,可能就没有复制_start这个值,程序执行的时候就懵逼了,要代码重定位,找不到第二个参数了。所以为了保证在4k内,人为写一个值(猜测这样子这条代码就不算伪汇编,保存的地址就可以保证在4K内)。实际上
两种写法意思是一样的,只是担心出问题。所以改为
ldr r1, _TEXT_BASE
_TEXT_BASE有定义:
_TEXT_BASE: .word CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_TEXT_BASE 0x0
把CONFIG_SYS_TEXT_BASE 值改为0x33f00000
因为内存一共64M,就是34000000,在内存的顶部是uboot的存放空间,这里给uboot留了1M的空间,让代码copy进去。64M-1M=0x33f00000。
copy_code_to_sdram的第三个参数是copy的长度,查看start.S可以看到
_bss_start_ofs: .word __bss_start - _start
_bss段是存放初始值为0的变量,bss段的文件是不会存在在bin文件里面的,所以__bss_start - _start就是二进制文件的长度。copy的长度就写为_bss_start_ofs。
copy_code_to_sdram文件内部查看以后发现不需要修改
clear_bss需要修改一些值。
void clear_bss (void) { extern int __bss_start, __bss_end; int *p = &__bss_start; for (; p < &__bss_end; p++) *p = 0; }
源文件的bss段的结束地址定义为bss_end,在这个uboot中为__bss_end,修改即可。
因此汇编中的代码段改为,同时去掉原先的clear_bss
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
bl nand_init_ll
mov r0, #0
//ldr r1, =_start
ldr r1, _TEXT_BASE
ldr r2, _bss_start_ofs;
bl copy_code_to_sdram
bl clear_bss
同时clear_bss改为
void clear_bss (void) { extern int __bss_start, __bss_end__; int *p = &__bss_start; for (; p < &__bss_end__; p++) *p = 0; }
c.去掉自带的重定位代码。
进入board_init_f函数,找到relocate_code(addr_sp, id, addr);注释掉。
因为后面的代码是在SDRAM,bl是相对跳转指令,使用
ldr pc, =call_board_init_f
这样一下就从片内内存跳到SDRAM中了。
d.下面是调用第二阶段的代码。
/* 调用第二阶段代码 */ bl board_init_r
有两个参数gd_t *gd, ulong dest_addr。ID和目的地址。目的地址就是程序的链接地址。
ldr r1, _TEXT_BASE
ID可以观察到在board_init_f中有获得,直接添加返回值为id。返回值存在r0,就省得我们再做别的事了。
e.差不多改完了,把init文件添加进uboot,
vi board/samsung/smdk2440/Makefile
在COBJS := smdk2410.o这句话后面加上init.o
保存退出。
f.修改链接脚本,把Start.o init之类的文件放到代码的最前头,这样能保证需要的代码都在4k里。
vi arch/arm/cpu/u-boot.lds . = 0x00000000; . = ALIGN(4); .text : { __image_copy_start = .; CPUDIR/start.o (.text) *(.text) }
将
board/samsung/smdk2440/libsmdk2440.o (.text)添加进去变成:
. = ALIGN(4); .text : { __image_copy_start = .; CPUDIR/start.o (.text) board/samsung/smdk2440/libsmdk2440.o (.text) *(.text) }
g:编译,有一些错误,比如之前增加了board_init_f的返回值,原先是没有的,改一下就行了。
h.烧到NAND,启动,成功
相关文章推荐
- uboot-2010.03移植到2410(从nand启动)
- UBOOT-2012-10在OK6410平台的移植(七)关于NAND启动
- UBOOT-2010-03在S3C2440上的移植<三>------------自动识别启动模式Nand Or Nor
- uboot-2010.03 移植到 2410( 从 nand 启动 )
- UBOOT-2010-03在S3C2440上的移植<四>------------支持NANDFLASH<续>
- Uboot启动参数设置
- Uboot启动分析之stage1-Nand-Flash启动部分详解
- u-boot-2011.03在TQ2440上的移植(5)—实现Nand/Nor 双启动
- 第一次移植uboot(2)(NAND中环境变量读写)
- TQ2440从nor烧写nand启动uboot和kennel
- [NAND]UBOOT从NAND FLASH启动分析
- u-boot2010.03 移植篇(二)-----修改start.S,支持nand启动 .
- uboot启动命令设置详解
- uboot启动参数设置和内核引导方法总结
- OK6410之uboot移植(4)——uboot启动代码植及支持nand flansh启动
- u-boot移植(七)支持nand启动
- [NAND]UBOOT从NAND FLASH启动分析
- uboot移植,编译及环境变量,启动等方面---from README
- 移植u-boot-2010.09到三星SC32442平台(一):时钟和nand启动
- 移植u-boot-2010.09到S3C2440(三)——判断NAND还是NOR启动的汇编代码