1、在做u‐boot移植的时候,多数人使用的是Nand FLASH启动或Nor FLASH启动。这样u‐boot就只能在Nand FLASH或Nor FLASH。那么我们如何让我们的u‐boot在Nand FLASH或Nor FLASH都能使用。u-boot是系统启动前执行的一段程序,如果是放在Nandflash中的,那么u‐boot自己可以把自己搬移到内存中执行。
2、根据s3c2440数据手册得知:
对于Nand的操作和Nor的操作是完全不同的,选择Nor FLASH启动是将Nor FLASH映射到片选0上也就是0x0地址而选择Nand FLASH启动则是将CPU的片内RAM(4K)映射到0地址,通过Nand FLASH控制器操作Nand FLASH。所以:
a:如果是Nandflash启动,Nandflash在初始化之前是不能读写的,所以在2440内部有4k SRAM,在这里4KB空间里,可以完成Nandflash的初始化和搬运u-boot到RAM。
b:Norflash上电默认状态是读,所以可以直接搬运u-boot到RAM执行。
3、通过下图我们可以发现,我们可以通过判断BWSCON的第2位和地3位的值判断是Nor FLASH启动还是Nand FLASH启动。如果[2:1]是0 0 那么是Nandflash启动,反之则为Norflash启动。
4、修改第一阶段启动函数
vi arch/arm/cou/arm920t/start.S
Norflash和Nandflash拷贝uboot到RAM函数分别如下:
//初始化内存
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
//nor/nand flash双启动判断
#define BWSCON 0x48000000
ldr r0, =BWSCON
ldr r0, [r0]
ands r0, r0, #6 //判断BWSCON[2:1]是否为00,如果是,Z=1即跳转到nand_boot
beq nand_boot
//系统从Norflash启动
relocate: /* 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
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
//下面添加2440中u-boot从Nand Flash启动-----------------
nand_boot:
mov r1, #NAND_CTL_BASE //复位Nand Flash
ldr r2, =( (0<<12)|(3<<8)|(0<<4)|(3<<2)|(1<<1) )
str r2, [r1, #oNFCONF] //设置配置寄存器的初始值,参考s3c2440手册
ldr r2, [r1, #oNFCONF]
ldr r2, =( (1<<4)|(1<<1)|(1<<0) )
str r2, [r1, #oNFCONT] //设置控制寄存器
ldr r2, [r1, #oNFCONT]
//ldr r2, =(0x01) //RnB Clear
//str r2, [r1, #oNFSTAT]
//ldr r2, [r1, #oNFSTAT]
mov r2, #0xff //复位command
strb r2, [r1, #oNFCMD]
mov r3, #0 //等待
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1
nand2:
ldr r2, [r1, #oNFSTAT] //等待就绪
tst r2, #0x4
beq nand2
ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x02 //取消片选
str r2, [r1, #oNFCONT]
//get read to call C functions (for nand_read())
ldr sp, DW_STACK_START //为C代码准备堆栈,DW_STACK_START定义在下面
mov fp, #0
//copy U-Boot to RAM
ldr r0, =TEXT_BASE//传递给C代码的第一个参数:u-boot在RAM中的起始地址
mov r1, #0x0 //传递给C代码的第二个参数:Nand Flash的起始地址
mov r2, #0x30000 //传递给C代码的第三个参数:u-boot的长度大小(192k)
bl nand_read_ll //此处调用C代码中读Nand的函数,/board/samsung/smdk2440/nand_read.c
tst r0, #0x0
beq ok_nand_read
bad_nand_read:
loop2: b loop2 //infinite loop
ok_nand_read:
//检查搬移后的数据,如果前4k完全相同,表示搬移成功
mov r0, #0
ldr r1, =TEXT_BASE
mov r2, #0x1000 //4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next
notmatch:
loop3:
b loop3 //infinite loop
4、make即可