微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

增加从Nand 启动的代码:


 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 举报,一经查实,本站将立刻删除。

相关推荐