经过前四篇的移植,uboot现在能从nor flash 中启动并且能识别nand flash的大小,并能对nand flash 作基本的读写操作等,如果虚拟机安装了TFTP服务器,就能通过“tftp 30008000 yourfile” 命令从tftp服务器上下载yourfile到内存中(30008000为内存地址).为了让u-boot.bin烧录到nand flash 中后能从nand flash 启动,现在就u-boot源文件中相应的文件进行修改,让其实现这个功能。
1.修改/cpu/arm920t/u-boot.lds文件,使lowlevel_init.o在前4K范围:
.text :
{
cpu/arm920t/start.o (.text)
board/samsung/ok2440v3/lowlevel_init.o (.text)
*(.text)
}
u-boot根目录下的u-boot.map文件可查看lowlevel_init.o并在不在前4K的范围。
2.修改/cpu/arm920t/start.S文件,注释掉原来的relocate 部分,用飞凌公司提供的bootloader中的nand启动相关部分来替代。
#if 0
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:/* relocate U-Boot to RAM */
adrr0, _start/* r0 <- current position of code */
ldrr1, _TEXT_BASE/* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
ldrr2, _armboot_start
ldrr3, _bss_start
subr2, r3, r2/* r2 <- size of armboot */
addr2, r0, r2/* r2 <- source end address */
copy_loop:
ldmiar0!, {r3-r10}/* copy from source address [r0] */
stmiar1!, {r3-r10}/* copy to target address [r1] */
cmpr0, r2/* until source end addreee [r2] */
blecopy_loop
#endif/* CONFIG_SKIP_RELOCATE_UBOOT */
#endif
紧跟其后增加以下代码:
#ifndef CONFIG_SKIP_S3C2440_NAND_BOOT
#define NFCONF 0x4E000000
relocate_nand: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
mov r5, #NFCONF
//set timing value
ldr r0, =(7<<12)|(7<<8)|(7<<4)
str r0, [r5]
//enable control
ldr r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
str r0, [r5, #4]
bl ReadNandID
mov r6, #0
ldr r0, =0xecF1
cmp r5, r0
beq 1f
ldr r0, =0xec76
cmp r5, r0
beq 1f
mov r6, #1
1:
bl ReadNandStatus
mov r8, #0
ldr r9, =_start
mov r10, #128 //u-boot 256k,128页 --这里原来是32!!
2:
ands r0, r8, #0x3f //如果是第一页,则检测坏块
bne 3f
mov r0, r8
bl CheckBadBlk
cmp r0, #0
addne r8, r8, #64 //每块的页数
addne r10,r10,#64 //+081010 feiling
bne 4f
3:
mov r0, r8
mov r1, r9
bl ReadNandPage
add r9, r9, #2048 //每页的字节数
add r8, r8, #1 //页数+1
4:
cmp r8, r10 //要拷贝的页数 081010 pht:#32->r10
bcc 2b
mov r5, #NFCONF //DsNandFlash
ldr r0, [r5, #4]
bic r0, r0, #1
str r0, [r5, #4]
#endif
由于上面代码段中用到了ReadNandID、ReadNandStatu、 WaitNandBusy、CheckBadBlk、ReadNandPage等几个子函数。故要在本文件中增加这些函数体。以下就是这些函数的代码,把它放在本文件末尾。
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
ReadNandID:
ldr r7,=NFCONF
ldr r0,[r7,#4]
bic r0,r0,#2
str r0,[r7,#4]
mov r0,#0x90
strb r0,[r7,#8]
mov r4,#0
strb r4,[r7,#0xc]
1:
ldr r0,[r7,#0x20]
tst r0,#1
beq 1b
ldrb r0,[r7,#0x10]
mov r0,r0,lsl #8
ldrb r1,[r7,#0x10]
orr r5,r1,r0
ldr r0,[r7,#4]
orr r0,r0,#2
str r0,[r7,#4]
mov pc,lr
ReadNandStatus:
ldr r7,=NFCONF
ldr r0,[r7,#4]
bic r0,r0,#2
str r0,[r7,#4]
mov r0,#0x70
strb r0,[r7,#8]
ldrb r1,[r7,#0x10]
ldr r0,[r7,#4]
orr r0,r0,#2
str r0,[r7,#4]
mov pc,lr
WaitNandBusy:
mov r0,#0x70
ldr r1,=NFCONF
strb r0,[r1,#8]
1:
ldrb r0,[r1,#0x10]
tst r0,#0x40
beq 1b
mov r0,#0
strb r0,[r1,#8]
mov pc,lr
CheckBadBlk:
mov r7,lr
ldr r5,=NFCONF
bic r0,r0,#0x3f
ldr r1,[r5,#4]
bic r1,r1,#2
str r1,[r5,#4]
mov r1,#0x00
strb r1,[r5,#8]
mov r1,#0
strb r1,[r5,#0xc]
mov r1,#8
strb r1,[r5,#0xc]
strb r0,[r5,#0xc]
mov r1,r0,lsr #8
strb r1,[r5,#0xc]
/*******************nand为256M时,加下面代码********
cmp r6,#0 ;if(NandAddr)
movne r1,r0,lsr #16 ;WrNFAddr(addr>>16)
strb
******************nand为256,加上面代码*********/
mov r1,#0x30
strb r1,[r5,#8]
mov r0,#100
1:
subs r0,r0,#1
bne 1b
2:
ldr r0,[r5,#0x20]
tst r0,#1
beq 2b
ldrb r0,[r5,#0x10]
sub r0,r0,#0xff
ldr r1,[r5,#4]
orr r1,r1,#2
str r1,[r5,#4]
mov pc,r7
ReadNandPage:
mov r7,lr
mov r4,r1
ldr r5,=NFCONF
ldr r1,[r5,#4]
bic r1,r1,#2
str r1,[r5,#4]
mov r1,#0
strb r1,[r5,#8]
strb r1,[r5,#0xc]
strb r1,[r5,#0xc]
strb r0,[r5,#0xc]
mov r1,r0,lsr #8
strb r1,[r5,#0xc]
/*******************nand为256M时,加下面代码********
cmp r6,#0 ;if(NandAddr)
movne r1,r0,lsr #16 ;WrNFAddr(addr>>16)
strb
******************nand为256,加上面代码*********/
mov r1,#0x30
strb r1,[r5,#8]
ldr r0,[r5,#4]
orr r0,r0,#0x10
str r0,[r5,#4]
bl WaitNandBusy
mov r0,#0
1:
ldrb r1,[r5,#0x10]
strb r1,[r4,r0]
add r0,r0,#1
bic r0,r0,#0x10000
cmp r0,#0x800
bcc 1b
ldr r0,[r5,#4]
orr r0,r0,#2
str r0,[r5,#4]
mov pc,r7
#endif
最后就是修改保存环境变量的相关宏,打开/include/configs/ok2440.h文件。修改如下:
/*#defineCONFIG_ENV_IS_IN_FLASH1*/ //注释掉这句
#define CONFIG_ENV_IS_IN_NAND 1 //增加这一句
#define CONFIG_ENV_SIZE 0x40000/* Total Size of Environment Sector */
#define CONFIG_ENV_OFFSET 0x100000 //yu fen qu zhong yi zhi
接着在终端执行:make distclean
make ok2440v3_config
make
从nor flash启动uboot,然后将生成的uboot.bin通过tftp服务下载到nand flash 中,执行命令如下:
- tftp 30008000 u-boot.bin //从tftp 服务器上下载u-boot.bin到内存地址30008000处
- nand erase 0 100000 //擦除 nand 上从0-100000(1M大小空间);如果不行或有坏块,可执行命令:nand scrub
- nand write 30008000 0 100000 /把30008000内存地址的数据写入到0地址开头,大小为100000(1M)的空间
启动信息uboo后,会有一个警告信息“*** Warning - bad CRC or NAND, using default environment”,只要执行命令:saveenv;这里的saveenv命令用来保存环境变量,保存后这个警告就会消失。如下图:
感谢网上的各位大牛,本博文主要参考: