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

FL2440的U-boot-2010.09移植(六)NAND Flash启动支持

发布时间:2020-12-15 07:18:35 所属栏目:百科 来源:网络整理
导读:?从NAND Flash启动的原理很简单,就是利用S3C2440内部4K大小的SRAM,存储在NAND Flash中的代码不能被执行,而S3C2440在从NAND Flash启动把NAND Flash的前4k代码复制到SRAM中运行,U-boot支持从NAND Flash启动的方法就是利用这前4K代码完成SDRAM的初始化(SDR

?从NAND Flash启动的原理很简单,就是利用S3C2440内部4K大小的SRAM,存储在NAND Flash中的代码不能被执行,而S3C2440在从NAND Flash启动把NAND Flash的前4k代码复制到SRAM中运行,U-boot支持从NAND Flash启动的方法就是利用这前4K代码完成SDRAM的初始化(SDRAM有64M),然后还要完成从U-boot代码从NAND Flash中复制到SDRAM中,然后再跳转到SDRAM中去运行完整的U-boot。

????? 为了便于系统启动的方便,可以在start.S文件中添加代码以识别系统是从NAND Flash启动还是从NOR Flash启动,从S3C2440芯片手册中可以看到

到OM[1:0]都为0时,说明是从NAND Flash启动,01和10都是从NOR Flash启动,OM[1:0]就是寄存器BWSCON的第2位~第1位(DW0)

一、添加NOR Flash启动和NAND Flash启动的识别

修改arch/arm/cpu/arm920t/start.S,首先将217行附近修改为:

[cpp]? view plain copy
  1. #ifndef?CONFIG_SKIP_LOWLEVEL_INIT??
  2. ????bl??cpu_init_crit??
  3. #endif??
  4. ??
  5. #define?BWSCON?0x48000000??
  6. ????????ldr?????r0,?=BWSCON??
  7. ????????ldr?????r0,?[r0]??
  8. ????????ands????r0,?r0,?#0x6??
  9. ????????tst?????r0,?#0x0??
  10. ????????bne?????norflash_boot?????????????/*OM[1:0]?!=?0,?跳转到NOR?FLASH?启动处*/??
  11. /*判断uboot是从nand?flash启动还是从?nor?flash启动*/??

在220行附近将:

  • #ifndef?CONFIG_SKIP_RELOCATE_UBOOT??
  • relocate:??
  • 修改为

    [html]?
  • norflash_boot:??
  • #ifndef?CONFIG_SKIP_RELOCATE_UBOOT??
  • relocate:??
  • 二、添加NAND Flash的U-boot代码从NAND FLash到SDRAM搬移的代码
    在前面修改的 bne norflash_boot ,227行后添加

  • /*****************************nand?boot**************************/??
  • nandflash_boot:??
  • #define?LENGTH_UBOOT?0x40000??
  • #define?NAND_CTL_BASE?0x4e000000??
  • #define?oNFCONF?0x00??
  • #define?oNFCONT?0x04??
  • #define?oNFCMD??0x08??
  • #define?oNFSTAT?0x20??
  • ??
  • ????????@reset?NAND??
  • ????????mov?????r1,#NAND_CTL_BASE??
  • ????????ldr?????r2,=((7<<12)|(7<<8)|(7<<4))??
  • ????????str?????r2,[r1,#oNFCONF]??
  • ????????ldr?????r2,#oNFCONF]??
  • ??????????
  • ????????ldr?????r2,=((1<<4)|(1<<1)|(1<<0))?@Active?low?CE?control??
  • ????????str?????r2,#oNFCONT]??
  • ????????ldr?????r2,#oNFCONT]??
  • ??????????
  • ????????@?get?read?to?call?C?functions??
  • ????????ldr?????sp,DW_STACK_START???@setup?stack?point??
  • ????????mov?????fp,#0???????????????@no?previous?frame,?so?fp?=?0??
  • ??????????
  • ????????@copy?Uboot?to?ram??
  • ????????ldr?????r0,?=TEXT_BASE??
  • ????????mov?????r1,#0x0??
  • ????????mov?????r2,#LENGTH_UBOOT??
  • ????????bl??????nand_read_ll??
  • ????????tst?????r0,#0x0??
  • ????????beq?????ok_nand_read??
  • ??
  • bad_nand_read:??
  • loop2:??
  • ????????b???????loop2?????@infinite?loop??
  • ??
  • ok_nand_read:??
  • ????????@verify??
  • ????????mov?????r0,#0??
  • ????????ldr?????r1,=TEXT_BASE??
  • ????????mov?????r2,#0x400?????@?compare?4k?code?from?sram?to?sdram??
  • ??
  • go_next:??
  • ????????ldr?????r3,?[r0],?#4??
  • ????????ldr?????r4,?[r1],?#4??
  • ????????teq?????r3,?r4??
  • ????????bne?????notmatch??
  • ????????subs????r2,r2,#4??
  • ????????tst?????r2,#0x0???@do?not?forget?the?instruction?if?have?not?this?command?the?uboot?can't?break?the?loop??
  • ????????beq?????stack_setup??
  • ????????bne?????go_next??
  • ??
  • notmatch:??
  • loop3:??
  • ????????b???????loop3?@infinite?loop??
  • /*****************************nand?boot**************************/??
  • 上面这部分代码首先初始化了NAND Flash寄存器,然后进行了一个函数调用(这个函数中完成了代码搬移)后面则是对复制出来的数据进行一个简单的校验。在327行附近添加为:

  • _start_armboot:?.word?start_armboot??
  • #define??STACK_BASE?0x33f00000??
  • #define??STACK_SIZE?0x10000??
  • ????????.align?2??
  • DW_STACK_START:?.word?STACK_BASE+STACK_SIZE-4??
  • 添加函数的栈调用空间

    三、添加C语言从NAND Flash搬移代码部分

    首先在board/fl2440目录下新建一个名为nand_read.c的文件,其内容如下:

    /*??
  • ?*?vivi/s3c2410/nand_read.c:?Simple?NAND?read?functions?for?booting?from?NAND?
  • ?*?
  • ?*?Copyright?(C)?2002?MIZI?Research,?Inc.?
  • ?*?Author:?Hwang,?Chideok?<hwang@mizi.com>?
  • ?*?Date??:?$Date:?2002/08/14?10:26:47?$?
  • ?*?
  • ?*?$Revision:?1.6?$?
  • ?*?$Id:?param.c,v?1.9?2002/07/11?06:17:20?nandy?Exp??
  • ?*/??
  • ??
  • #include?<config.h>??
  • ??
  • #define?__REGb(x)???(*(volatile?unsigned?char?*)(x))??
  • #define?__REGi(x)???(*(volatile?unsigned?int?*)(x))??
  • #define?NF_BASE?????0x4e000000??
  • ??
  • /*S3C2440与S3C2440?nandflash控制寄存器地址不同需要进行修改*/??
  • #define?NFCONF??????__REGi(NF_BASE?+?0x0)??
  • #define?NFCONT??????????__REGi(NF_BASE?+?0x4)??
  • #define?NFCMD???????__REGb(NF_BASE?+?0x8)??
  • #define?NFADDR??????__REGb(NF_BASE?+?0xc)??
  • #define?NFDATA??????__REGb(NF_BASE?+?0x10)??
  • #define?NFSTAT??????__REGb(NF_BASE?+?0x20)??
  • ??
  • #define?NAND_CHIP_ENABLE?(NFCONT?&=?~(1<<1))??
  • #define?NAND_CHIP_DISABLE?(NFCONT?|=?(1<<1))??
  • #define?NAND_CLEAR_RB?(NFSTAT?|=?(1<<2))??
  • #define?NAND_DETECT_RB?{while(!?(NFSTAT&(1<<2)));}??
  • #define?NAND_ECC_CLEAR?(NFCONT?|=?0x10)??
  • /*see?data?sheet?P193*/??
  • ??
  • #define?BUSY?1??
  • static?inline?void?wait_idle(void)?{??
  • ????int?i;??
  • ????while(!(NFSTAT?&?BUSY))??
  • ??????for(i=0;?i<10;?i++);??
  • }??
  • ??
  • /*根据fl2440的nand?flash?作相应修改*/??
  • #define?NAND_SECTOR_SIZE????2048??
  • #define?NAND_BLOCK_MASK?????(NAND_SECTOR_SIZE?-?1)??
  • ??
  • /*?low?level?nand?read?function?*/??
  • ?int??
  • nand_read_ll(unsigned?char?*buf,?unsigned?long?start_addr,?int?size)??
  • {??
  • ????int?i,?j;??
  • ????int?pagenum;??
  • ??
  • ????if?((start_addr?&?NAND_BLOCK_MASK)?||?(size?&?NAND_BLOCK_MASK))?{??
  • ????????return?-1;??/*?invalid?alignment?*/??
  • ????}??
  • ??
  • ????/*?chip?Enable?*/??
  • ????NAND_CHIP_ENABLE;??
  • ??????
  • ????for(i?=?start_addr;?i?<?(start_addr?+?size);)?{??
  • ??????/*?READ0?*/??
  • ??
  • ??????NAND_CLEAR_RB;??
  • ??????for(j?=?0;?j?<?10;?j++);??
  • ????????
  • ??????pagenum?=?i?>>?11;??
  • ??????/*?Write?Address??
  • ????????该步骤详见nand?flash(k9f2g08u0a)手册p17?
  • ????????参考fl2440开发板nand_lowlevel.c文件中ReadPage函数?
  • ??????*/??
  • ??????NFCMD?=?0x0;??
  • ????????
  • ??????NFADDR?=?0;??
  • ??????NFADDR?=?0;??
  • ??????NFADDR?=?pagenum?&?0xff;??
  • ??????NFADDR?=?(pagenum?>>?8)?&?0xff;??
  • ??????NFADDR?=?(pagenum?>>?16)?&?0xff;??
  • ??????/*如果不理解见数据手册nand?flashP9*/??
  • ??
  • ??????NFCMD?=?0x30;??
  • ??????wait_idle();??
  • ??
  • ??????for(j=0;?j?<?NAND_SECTOR_SIZE;?j++)?{??
  • ??????????*buf?=?(NFDATA?&?0xff);??
  • ???????????buf++;??
  • ??????}??
  • ???????
  • ?????i?+=?NAND_SECTOR_SIZE;??
  • ???
  • ????}??
  • ??
  • ????NAND_CHIP_DISABLE;??
  • ?????
  • ????/*?chip?Disable?*/??
  • ??????
  • ????return?0;??
  • }??
  • ????开发板的NAND Flash型号为k9f2g08u0a,它的容量是256MByte,NAND Flash的最小读取单位是以页为单位的,即2KByte(12位)每页,共128K页(17位),而地址线是8位的,因此当需要读取一页时,需分周期发送页地址,这款芯片规定前两个地址周期发送页内地址,后面的三周期发送页编号,它的流程如表1:

    1 NAND Flash地址

    ?

    I/O 0

    I/O 1

    I/O 2

    I/O 3

    I/O 4

    I/O 5

    I/O 6

    I/O 7

    第一周期

    A0

    A1

    A2

    A3

    A4

    A5

    A6

    A7

    第二周期

    A8

    A9

    A10

    A11

    0

    0

    0

    0

    第三周期

    A12

    A13

    A14

    A15

    A16

    A17

    A18

    A19

    第四周期

    A20

    A21

    A22

    A23

    A24

    A25

    A26

    A27

    第五周期

    A28

    0

    0

    0

    0

    0

    0

    0

    我们在读取uboot.bin时,直接按页读取,所以前两周期地址我们设成了全0,后面的3周期实际就是也编号。

    修改board/fl2440/Makefile文件,使得nand_read.c能被编译到u-boot.bin中,修改28行为:

  • COBJS???:=?fl2440.o?nand_read.o?flash.o??
  • 我们还知道由于我们需要在前4K代码中完成代码的搬移,而搬移的代码集中在start.S和nand_read.c中,而U-boot的编译过程并不能保证nand_read.c能在前4K代码中,所以需要我们手动设置,修改文件arch/arm/cpu/arm920t/u-boot.lds文件40行为:

  • .text?:??
  • {??
  • ????arch/arm/cpu/arm920t/start.o????(.text)??
  • ???????????????board/fl2440/lowlevel_init.o?(.text)??
  • ???????????????board/fl2440/nand_read.o?(.text)??
  • ????*(.text)??
  • }??

  • 这样,编译器在编译时能保证start.S和nand_read.c编译出的二进制代码在前4K。

    修改include/configs/fl2440.h中,添加相关的宏定义以支持NAND Flash的串口操作命令:

  • #define?CONFIG_CMD_NAND???/*****add?by?yanghao*****/??
  • <p>#if?defined(CONFIG_CMD_NAND)</p><p>#define?CONFIG_NAND_S3C2410??
  • #define?CONFIG_SYS_MAX_NAND_DEVICE???1?????/*?Max?number?of?NAND?devices????????*/??
  • #define?NAND_MAX_CHIPS???1??
  • #define?CONFIG_SYS_NAND_BASE?0x4E000000</p>#endif??
  • ?

    然后将开发板设置成为从NAND Flash启动,将编译出来的u-boot.bin烧写入NAND Flash,上电这样就完成了从NAND Flash的启动。

    (编辑:李大同)

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

      推荐文章
        热点阅读