FS2410板有跳线,跳线短路时从NAND启动,否则从nor启动。根据FS2410 BIOS源码,我修改了start.s加入了可以从两种FLASH中启动u-boot的
代码。原理在于:在重定位之前先读BWSCON寄存器,判断OM0位是0(有跳线,NAND启动)还是1(无跳线,nor启动),采取不同的重定位代码
分别从nand或nor中拷贝u-boot镜像到RAM中。这里面也有问题,比如从Nand启动后,nor flash的初始化代码和与它相关的命令都是不能使用的。
这里我采用比较简单的方法,定义一个全局变量标志_boot_flash保存当前启动FLASH标志,_boot_flash=0则表明是nor启动,否则是从NAND。
在每个与nor flash 相关的命令执行函数一开始就判断这个变量,如果为1立即返回。flash_init()也必须放在这个if(!_boot_flash)条件中。
这里方法比较笨,主要是为了能在跳线处于任意状态时都能启动u-boot。
修改后的start.s如下。
.......
//修改1
.globl _boot_flash
_boot_flash: //定义全局标志变量,0:nor FLASH启动,1:NAND FLASH启动。
.word 0x00000000
.........
///修改2:
ldr r0,=BWSCON
ldr r0,[r0]
ands r0,r0,#6
beq nand_boot //OM0=0,有跳线,从Nand启动。nand_boot在后面定义。
............
//修改4,这里在全局变量_boot_flash中设置当前启动flash设备是nor还是NAND
//这里已经完成搬运到RAM的工作,即将跳转到RAM中_start_armboot函数中执行。
adr r1,_boot_flash //取_boot_flash的当前地址,这时还在nor FLASH或者NAND 4KB缓冲中。
ldr r2,_TEXT_BASE
add r1,r1,r2 //得到_boot_flash重定位后的地址,这个地址在RAM中。
ldr r0,#6 //
mov r2,#0x00000001
streq r2,[r1] //如果当前是从NAND启动,置_boot_flash为1
ldr pc,_start_armboot
_start_armboot: .word start_armboot
........
//////// 修改4,从NAND拷贝U-boot镜像(最大128KB),这段代码由fs2410 BIOS修改得来。
nand_boot:
mov r5,#NFCONF
ldr r0, =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7)
str r0, [r5]
bl ReadNandID
mov r6,#0
ldr r0,=0xec73
cmp r5, r0
beq x1
ldr r0,=0xec75
cmp r5,r0
beq x1
mov r6,#1
x1:
bl ReadNandStatus
mov r8,#0 //r8是PAGE数变量
ldr r9,_TEXT_BASE //r9指向u-boot在RAM中的起始地址。
x2:
ands r0,r8,#0x1f
bne x3 //此处意思在于页数是32的整数倍的时候才进行一次坏块检查 1 block=32 pages,否则直接读取页面。
mov r0,r8
bl CheckBadBlk //检查坏块返回值非0表明当前块不是坏块。
cmp r0,#0
addne r8,#32 //如果当前块坏了,跳过读取操作。 1 block=32 pages
bne x4
x3:
mov r0,r8
mov r1,r9
bl ReadNandPage //读取一页(512B)
add r9,r9,#512
add r8,#1
x4:
cmp r8,#256 //一共读取256*512=128KB。
bcc x2
mov r5,#NFCONF //DsNandFlash
ldr r0,[r5]
and r0,#~0x8000
str r0,[r5]
adr lr,stack_setup //注意这里直接跳转到stack_setup中执行
mov pc,lr
///
/*************************************************
*
*Nand basic functions:
*************************************************
*/
//读取Nand的ID号,返回值在r5中 ReadNandID: mov r7,#NFCONF ldr r0,[r7,#0] //NFChipEn(); bic r0,#0x800 str r0,#0] mov r0,#0x90 //WrNFCmd(RdIDCMD); strb r0,#4] mov r4,#0 //WrNFAddr(0); strb r4,#8] y1: //while(NFIsBusy()); ldr r0,#0x10] tst r0,#1 beq y1 ldrb r0,#0xc] //id = RdNFDat()<<8; mov r0,lsl #8 ldrb r1,#0xc] //id |= RdNFDat(); orr r5,r0 ldr r0,#0] //NFChipDs(); orr r0,#0] mov pc,lr //读取Nand状态,返回值在r1,此处没有用到返回值。 ReadNandStatus: mov r7,#NFCONF ldr r0,#0] //NFChipEn(); bic r0,#0] mov r0,#0x70 //WrNFCmd(QUERYCMD); strb r0,#4] ldrb r1,#0xc] //r1 = RdNFDat(); ldr r0,#0] //NFChipDs(); orr r0,#0] mov pc,lr //等待Nand内部操作完毕 WaitNandBusy: mov r0,#0x70 //WrNFCmd(QUERYCMD); mov r1,#NFCONF strb r0,[r1,#4] z1: //while(!(RdNFDat()&0x40)); ldrb r0,#0xc] tst r0,#0x40 beq z1 mov r0,#0 //WrNFCmd(READCMD0); strb r0,#4] mov pc,lr //检查坏block: CheckBadBlk: mov r7,lr mov r5,#NFCONF bic r0,#0x1f //addr &= ~0x1f; ldr r1,[r5,#0] //NFChipEn() bic r1,#0x800 str r1,#0] mov r1,#0x50 //WrNFCmd(READCMD2) strb r1,#4] mov r1,#6 strb r1,#8] //WrNFAddr(6) strb r0,#8] //WrNFAddr(addr) mov r1,lsr #8 //WrNFAddr(addr>>8) strb r1,#8] cmp r6,#0 //if(NandAddr) movne r0,lsr #16 //WrNFAddr(addr>>16) strneb r0,#8] bl WaitNandBusy //WaitNFBusy() ldrb r0,#0xc] //RdNFDat() sub r0,#0xff mov r1,#0 //WrNFCmd(READCMD0) strb r1,#4] ldr r1,#0] //NFChipDs() orr r1,#0] mov pc,r7 ReadNandPage: mov r7,lr mov r4,r1 mov r5,#NFCONF ldr r1,#4] strb r1,#8] //WrNFAddr(0) strb r0,#0 //if(NandAddr) movne r0,#8] ldr r0,#0] //InitEcc() orr r0,#0x1000 str r0,#0] bl WaitNandBusy //WaitNFBusy() mov r0,#0 //for(i=0; i<512; i++) r1: ldrb r1,#0xc] //buf[i] = RdNFDat() strb r1,[r4,r0] add r0,#1 bic r0,#0x10000 cmp r0,#0x200 bcc r1 ldr r0,#0] //NFChipDs() orr r0,#0] mov pc,r7 关于nand命令,我尝试打开CFG_CMD_NAND选项,并定义 #define CFG_MAX_NAND_DEVICE 1 #define MAX_NAND_CHIPS 1 #define CFG_NAND_BASE 0x4e000000 添加boar_nand_init()定义(空实现)。但是连接时出现问题,原因是u-boot使用的是软浮点,而我的交叉编译arm-linux-gcc是硬件浮点。 看过一些解决方法,比较麻烦,还没有解决这个问题,希望好心的高手指点。不过我比较纳闷,u-boot在nand部分哪里会用到浮点运算呢?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。