加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

增加从Nand 启动的代码:

发布时间:2020-12-15 18:42:00 所属栏目:百科 来源:网络整理
导读:?FS2410板有跳线,跳线短路时从NAND启动,否则从NOR启动。根据FS2410 BIOS源码,我修改了start.s加入了可以从两种FLASH中启动u-boot的 ?代码。原理在于:在重定位之前先读BWSCON寄存器,判断OM0位是0(有跳线,NAND启动)还是1(无跳线,NOR启动),采取不同


?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部分哪里会用到浮点运算呢? ? ?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读