u-boot-2010-06在mini2440上的移植(四)

四.添加对Nand Flash的支持

4.1 支持u-bootNand flash启动

目前u-boot中还没有对2440Nand Flash的支持,也就是说要想u-bootNand Flash上启动得自己去实现了。

首先,在include/configs/mini2440.h头文件中定义Nand要用到的宏和寄存器,如下:

#gedit include/configs/my2440.h  //在文件末尾加入以下Nand Flash相关定义

/*

 * Nand flash register and envionment variables

 */

#define CONFIG_S3C2440_NAND_BOOT  1

#define NAND_CTL_BASE  0x4E000000  //Nand Flash配置寄存器基地址,查2440手册可得知

#define bINT_CTL(Nb)   __REG(INT_CTL_BASE+(Nb))

#define UBOOT_RAM_BASE  0x33f80000

#define STACK_BASE  0x33F00000     //定义堆栈的地址

#define STACK_SIZE  0x8000         //堆栈的长度大小

 

其次,修改cpu/arm920t/start.S这个文件,使u-bootNand Flash启动,在上一节中提过,u-boot默认是从Nor Flash启动的。修改部分如下:

#gedit cpu/arm920t/start.S

/*注意:在上一篇Nor Flash启动中,我们为了把u-bootsupervivi下载到内存中运行而屏蔽掉这段有关CPU初始化的代码。而现在我们要把u-boot下载到Nand Flash中,从Nand Flash启动,所以现在要恢复这段代码。*/

 

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

    bl cpu_init_crit

#endif

 

#if 0 //屏蔽掉u-boot中的从Nor Flash启动部分

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

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

#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

#endif

 

 

//下面添加2440u-bootNand Flash启动

 

#ifdef CONFIG_S3C2440_NAND_BOOT

 

#define  oNFCONF  0x00

#define  oNFCONT  0x04

#define  oNFCMD   0x08

#define  oNFSTAT   0x20

#define  LENGTH_UBOOT  0x60000

 

    mov r1, #NAND_CTL_BASE   //复位Nand Flash

    ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )

    str r2, [r1, #oNFCONF]   //设置配置寄存器的初始值,参考s3c2440手册

    ldr r2, [r1, #oNFCONF]

 

    ldr r2, =( (1<<4)|(0<<1)|(1<<0) )

    str r2, [r1, #oNFCONT]   //设置控制寄存器

    ldr r2, [r1, #oNFCONT]

 

    ldr r2, =(0x6)           //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, #0x2         //取消片选

    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-bootRAM中的起始地址

    mov r1, #0x0      //传递给C代码的第二个参数:Nand Flash的起始地址

    mov r2, # LENGTH_UBOOT //传递给C代码的第三个参数:u-boot的长度大小(128k)

    bl nand_read_ll   //此处调用C代码中读Nand的函数,现在还没有要自己编写实现

    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, #0x400           //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

#endif                      //CONFIG_S3C2440_NAND_BOOT

 

_start_armboot: .word start_armboot //在这一句的下面加上DW_STACK_START的定义

 

.align 2

DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

再次,在board/samsung/mini2440/目录下新建一个nand_read.c文件,在该文件中来实现上面汇编中要调用的nand_read_ll函数,代码如下:

#gedit board/samsung/mini2440/nand_read.c  //新建一个nand_read.c文件,记得保存

#include <common.h>

#include <linux/mtd/nand.h>

 

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGw(x) (*(volatile unsigned short *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

 

#define NF_BASE 0x4e000000

#if defined(CONFIG_S3C2410) && !define (CONFIG_S3C2440)

#define NFCONF __REGi(NF_BASE + 0x0)

#define NFCMD  __REGb(NF_BASE + 0x4)

#define NFADDR __REGb(NF_BASE + 0x8)

#define NFDATA __REGb(NF_BASE + 0xc)

#define NFSTAT __REGb(NF_BASE + 0x10)

#define NFSTAT_BUSY 1

#define nand_select() (NFCONF &= ~0x800)

#define nand_deselect() (NFCONF |= 0x800)

#define nand_clear_RnB() do {} while (0)

#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)

#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 NFDATA16 __REGw(NF_BASE + 0x10)

#define NFSTAT   __REGb(NF_BASE + 0x20)

#define NFSTAT_BUSY 1

#define nand_select()    (NFCONT &= ~(1 << 1))

#define nand_deselect()  (NFCONT |= (1 << 1))

#define nand_clear_RnB() (NFSTAT |= (1 << 2))

#endif

 

static inline void nand_wait(void)

{

       int i;

       while (!(NFSTAT & NFSTAT_BUSY))

            for (i=0; i<10; i++);

}

 

struct boot_nand_t {

       int page_size;

       int block_size;

       int bad_block_offset;

       // unsigned long size;

};

 

static int is_bad_block(struct boot_nand_t * nand, unsigned long i)

{

       unsigned char data;

       unsigned long page_num;

       nand_clear_RnB();

       if (nand->page_size == 512) {

              NFCMD = NAND_CMD_READOOB; /* 0x50 */

              NFADDR = nand->bad_block_offset & 0xf;

              NFADDR = (i >> 9) & 0xff;

              NFADDR = (i >> 17) & 0xff;

              NFADDR = (i >> 25) & 0xff;

       } else if (nand->page_size == 2048) {

              page_num = i >> 11; /* addr / 2048 */

              NFCMD = NAND_CMD_READ0;

              NFADDR = nand->bad_block_offset & 0xff;

              NFADDR = (nand->bad_block_offset >> 8) & 0xff;

              NFADDR = page_num & 0xff;

              NFADDR = (page_num >> 8) & 0xff;

              NFADDR = (page_num >> 16) & 0xff;

              NFCMD = NAND_CMD_READSTART;

       } else {

              return -1;

       }

       nand_wait();

       data = (NFDATA & 0xff);

       if (data != 0xff)

               return 1;

       return 0;

}

 

static int nand_read_page_ll(struct boot_nand_t * nand, unsigned char *buf, unsigned long addr)

{

       unsigned short *ptr16 = (unsigned short *)buf;

       unsigned int i, page_num;

       nand_clear_RnB();

       NFCMD = NAND_CMD_READ0;

       if (nand->page_size == 512) {

              /* Write Address */

              NFADDR = addr & 0xff;

              NFADDR = (addr >> 9) & 0xff;

              NFADDR = (addr >> 17) & 0xff;

              NFADDR = (addr >> 25) & 0xff;

              } else if (nand->page_size == 2048) {

              page_num = addr >> 11; /* addr / 2048 */

              /* Write Address */

              NFADDR = 0;

              NFADDR = 0;

              NFADDR = page_num & 0xff;

              NFADDR = (page_num >> 8) & 0xff;

              NFADDR = (page_num >> 16) & 0xff;

              NFCMD = NAND_CMD_READSTART;

              } else {

                     return -1;

              }

              nand_wait();

#if defined(CONFIG_S3C2410)&& !define (CONFIG_S3C2440)

              for (i = 0; i < nand->page_size; i++) {

              *buf = (NFDATA & 0xff);

              buf++;

                }

 

#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)

 

       for (i = 0; i < (nand->page_size>>1); i++) {

              *ptr16 = NFDATA16;

              ptr16++;

       }

#endif

       return nand->page_size;

}

 

static unsigned short nand_read_id()

{

       unsigned short res = 0;

       NFCMD = NAND_CMD_READID;

       NFADDR = 0;

       res = NFDATA;

       res = (res << 8) | NFDATA;

       return res;

}

 

extern unsigned int dynpart_size[];

 

/* low level nand read function */

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

{

       int i, j;

       unsigned short nand_id;

       struct boot_nand_t nand;

       /* chip Enable */

       nand_select();

       nand_clear_RnB();

       for (i = 0; i < 10; i++)

       ;

       nand_id = nand_read_id();

       if (0) {                          /* dirty little hack to detect if nand id is misread */

       unsigned short * nid = (unsigned short *)0x31fffff0;

       *nid = nand_id;

       }

       if (nand_id == 0xec76 ||            /* Samsung K91208 */

           nand_id == 0xad76 ) {         /*Hynix HY27US08121A*/

              nand.page_size = 512;

              nand.block_size = 16 * 1024;

              nand.bad_block_offset = 5;

       // nand.size = 0x4000000;

       } else if (nand_id == 0xecf1 ||       /* Samsung K9F1G08U0B */

              nand_id == 0xecda ||          /* Samsung K9F2G08U0B */

              nand_id == 0xecd3 ) {         /* Samsung K9K8G08 */

              nand.page_size = 2048;

              nand.block_size = 128 * 1024;

              nand.bad_block_offset = nand.page_size;

       // nand.size = 0x8000000;

       } else {

              return -1; // hang

       }

       if ((start_addr & (nand.block_size-1)) || (size & ((nand.block_size-1))))

              return -1; /* invalid alignment */

       for (i=start_addr; i < (start_addr + size);) {

#ifdef CONFIG_S3C2410_NAND_SKIP_BAD

              if (i & (nand.block_size-1)== 0) {

              if (is_bad_block(&nand, i) ||

                 is_bad_block(&nand, i + nand.page_size)) {

                     /* Bad block */

                     i += nand.block_size;

                     size += nand.block_size;

                     continue;

              }

              }

#endif

              j = nand_read_page_ll(&nand, buf, i);

              i += j;

              buf += j;

       }

       /* chip Disable */

       nand_deselect();

       return 0;

}

然后,在board/samsung/mini2440/Makefile中添加nand_read.c的编译选项,使他编译到u-boot中,如下:

COBJS    := mini2440.o flash.o nand_read.o

还有一个重要的地方要修改,在cpu/arm920t/u-boot.lds中,这个u-boot启动连接脚本文件决定了u-boot运行的入口地址,以及各个段的存储位置,这也是链接定位的作用。添加下面两行代码的主要目的是防止编译器把我们自己添加的用于nandboot的子函数放到4K之后,否则是无法启动的。如下:

.text :

{

    cpu/arm920t/start.o    (.text)

    board/samsung/mini2440/lowlevel_init.o (.text)

    board/samsung/mini440/nand_read.o (.text)

    *(.text)

}

最后编译u-boot,生成u-boot.bin文件。然后先将mini2440开发板调到Nor启动档,利用supervivia命令将u-boot.bin下载到开发板的Nand Flash中,再把开发板调到Nand启动档,打开电源就从Nand Flash启动了。

 

4.2 添加Nand Flash(K9F2g08U0C)的有关操作支持

在上一节中我们说过,通常在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启动和从Nand Flash启动,但不管是从Nor启动或者从Nand启动,进入第二阶段以后,两者的执行流程是相同的。

现在的u-boot-2010-06版本对Nand的初始化、读写实现是基于最近的Linux内核的MTD架构,删除了以前传统的执行方法,使移植没有以前那样复杂了,实现Nand的操作和基本命令都直接在drivers/mtd/nand目录下(doc/README.nand中讲得很清楚)。下面我们结合代码来分析一下u-boot在第二阶段的执行流程:

1.lib_arm/board.c文件中的start_armboot函数调用了drivers/mtd/nand/nand.c文件中的nand_init函数,如下:

  #if defined(CONFIG_CMD_NAND) //可以看到CONFIG_CMD_NAND宏决定了Nand的初始化

      puts ("NAND: ");

      nand_init();

  #endif

2.nand_init调用了同文件下的nand_init_chip函数;

3.nand_init_chip函数调用drivers/mtd/nand/s3c2410_nand.c文件下的board_nand_init函数,然后再调用drivers/mtd/nand/nand_base.c函数中的nand_scan函数;

4.nand_scan函数调用了同文件下的nand_scan_ident函数等。

我们在u-boot提供的关于S3C2410nand_flash驱动文件的基础上添加相关代码以支持S3C2440.

#gedit driver/mtd/nand/s3c2410_nand.c

#include <common.h>

#include <nand.h>

#include <asm/arch-s3c24x0/s3c24x0_cpu.h>

#include <asm/io.h>

#define   NF_BASE             0x4e000000

 

#if defined(CONFIG_S3C2410)&&!defineCONFIG_S3C2440

#define S3C2410_NFCONF_EN          (1<<15)

#define S3C2410_NFCONF_512BYTE     (1<<14)

#define S3C2410_NFCONF_4STEP       (1<<13)

#define S3C2410_NFCONF_INITECC     (1<<12)

#define S3C2410_NFCONF_nFCE        (1<<11)

#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)

#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)

#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)

 

#define S3C2410_ADDR_NALE 4

#define S3C2410_ADDR_NCLE 8

#endif

 

#if defined(CONFIG_S3C2440)

#define S3C2410_NFCONT_EN          (1<<0)

#define S3C2410_NFCONT_INITECC     (1<<4)

#define S3C2410_NFCONT_nFCE        (1<<1)

#define S3C2410_NFCONT_MAINECCLOCK (1<<5)

#define S3C2410_NFCONF_TACLS(x)    ((x)<<12)

#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<8)

#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<4)

 

#define S3C2410_ADDR_NALE 0x08

#define S3C2410_ADDR_NCLE 0x0c

#endif

 

ulong IO_ADDR_W = NF_BASE;

#ifdef CONFIG_NAND_SPL

/* in the early stage of NAND flash booting, printf() is not available */

#define printf(fmt, args...)

 

static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)

{

       int i;

       struct nand_chip *this = mtd->priv;

 

       for (i = 0; i < len; i++)

              buf[i] = readb(this->IO_ADDR_R);

}

#endif

 

static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)

{

//     struct nand_chip *chip = mtd->priv;

       struct s3c2410_nand *nand = s3c2410_get_base_nand();

 

       debugX(1, "hwcontrol(): 0x%02x 0x%02x/n", cmd, ctrl);

 

       if (ctrl & NAND_CTRL_CHANGE) {

    //  ulong IO_ADDR_W = (ulong) nand;

              IO_ADDR_W = (ulong)nand;

 

              if (!(ctrl & NAND_CLE))

                     IO_ADDR_W |= S3C2410_ADDR_NCLE;

              if (!(ctrl & NAND_ALE))

                     IO_ADDR_W |= S3C2410_ADDR_NALE;

 

//            chip->IO_ADDR_W = (void *)IO_ADDR_W;

 

#if defined(CONFIG_S3C2410)&& !defineCONFIG_S3C2440

              if (ctrl & NAND_NCE)

                     writel(readl(&nand->NFCONF) & ~S3C2410_NFCONF_nFCE,

                            &nand->NFCONF);

              else

                     writel(readl(&nand->NFCONF) | S3C2410_NFCONF_nFCE,

                            &nand->NFCONF);

       }

#endif

#if defined(CONFIG_S3C2440)

              if (ctrl & NAND_NCE)

                     writel(readl(&nand->NFCONT) & ~S3C2410_NFCONT_nFCE,

                            &nand->NFCONT);

              else

                     writel(readl(&nand->NFCONT) | S3C2410_NFCONT_nFCE,

                            &nand->NFCONT);

       }

#endif

 

       if (cmd != NAND_CMD_NONE)

       // writeb(cmd, chip->IO_ADDR_W);

              writeb(cmd, (void *)IO_ADDR_W);

}

static int s3c2410_dev_ready(struct mtd_info *mtd)

{

       struct s3c2410_nand *nand = s3c2410_get_base_nand();

       debugX(1, "dev_ready/n");

       return readl(&nand->NFSTAT) & 0x01;

}

 

#ifdef CONFIG_S3C2410_NAND_HWECC

void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)

{

       struct s3c2410_nand *nand = s3c2410_get_base_nand();

       debugX(1, "s3c2410_nand_enable_hwecc(%p, %d)/n", mtd, mode);

#if defined(CONFIG_S3C2410)&& !defineCONFIG_S3C2440

       writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);

#endif

 

#if defined(CONFIG_S3C2440)

       writel(readl(&nand->NFCONT) | S3C2410_NFCONT_INITECC, &nand->NFCONT);

#endif

}

 

static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,

                                  u_char *ecc_code)

{

       struct s3c2410_nand *nand = s3c2410_get_base_nand();

       ecc_code[0] = readb(&nand->NFECC);

       ecc_code[1] = readb(&nand->NFECC + 1);

       ecc_code[2] = readb(&nand->NFECC + 2);

       debugX(1, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x/n",

              mtd , ecc_code[0], ecc_code[1], ecc_code[2]);

 

       return 0;

}

 

static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,

                                 u_char *read_ecc, u_char *calc_ecc)

{

       if (read_ecc[0] == calc_ecc[0] &&

           read_ecc[1] == calc_ecc[1] &&

           read_ecc[2] == calc_ecc[2])

              return 0;

 

       printf("s3c2410_nand_correct_data: not implemented/n");

       return -1;

}

#endif

 

int board_nand_init(struct nand_chip *nand)

{

       u_int32_t cfg;

       u_int8_t tacls, twrph0, twrph1;

       struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();

       struct s3c2410_nand *nand_reg = s3c2410_get_base_nand();

 

       debugX(1, "board_nand_init()/n");

 

       writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON);

 

#if defined(CONFIG_S3C2410)&& !defineCONFIG_S3C2440

       /* initialize hardware */

       twrph0 = 3;

       twrph1 = 0;

       tacls = 0;

 

       cfg = S3C2410_NFCONF_EN;

       cfg |= S3C2410_NFCONF_TACLS(tacls - 1);

       cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);

       cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);

       writel(cfg, &nand_reg->NFCONF);

 

       /* initialize nand_chip data structure */

       nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;

#endif

#if defined(CONFIG_S3C2440)

       twrph0 = 4;

       twrph1 = 2;

       tacls = 0;

 

       cfg = 0;

       cfg |= S3C2410_NFCONF_TACLS(tacls - 1);

       cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);

       cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);

       writel(cfg, &nand_reg->NFCONF);

 

       cfg = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0);

       writel(cfg, &nand_reg->NFCONT);

       /* initialize nand_chip data structure */

       nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;

#endif

 

       nand->select_chip = NULL;

 

       /* read_buf and write_buf are default */

       /* read_byte and write_byte are default */

#ifdef CONFIG_NAND_SPL

       nand->read_buf = nand_read_buf;

#endif

 

       /* hwcontrol always must be implemented */

       nand->cmd_ctrl = s3c2410_hwcontrol;

 

       nand->dev_ready = s3c2410_dev_ready;

 

#ifdef CONFIG_S3C2410_NAND_HWECC

       nand->ecc.hwctl = s3c2410_nand_enable_hwecc;

       nand->ecc.calculate = s3c2410_nand_calculate_ecc;

       nand->ecc.correct = s3c2410_nand_correct_data;

       nand->ecc.mode = NAND_ECC_HW;

       nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;

       nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;

#else

       nand->ecc.mode = NAND_ECC_SOFT;

#endif

 

#ifdef CONFIG_S3C2410_NAND_BBT

       nand->options = NAND_USE_FLASH_BBT;

#else

       nand->options = 0;

#endif

 

       debugX(1, "end of nand_init/n");

 

       return 0;

}

  s3c24x0.h里添加S3C2440相关nand_flash的结构体,修改代码如下:

#gedit include/asm/arch-s3c24x0/s3c24x0.h

#if defined(CONFIG_S3C2440)

struct s3c2410_nand {

  u32 NFCONF;

  u32 NFCONT;

  u32 NFCMD;

  u32 NFADDR;

  u32 NFDATA;

  u32 NFMECCD0;

  u32 NFMECCD1;

  u32 NFSECCD;

  u32 NFSTAT;

  u32 NFESTAT0;

  u32 NFESTAT1;

  u32 NFMECC0;

  u32 NFMECC1;

  u32 NFSECC;

  u32 NFSBLK;

  u32 NFEBLK;

};

#endif

#if defined(CONFIG_S3C2410)&& !defineCONFIG_S3C2440

/* NAND FLASH (see S3C2410 manual chapter 6) */

struct s3c2410_nand {

       u32  NFCONF;

       u32  NFCMD;

       u32  NFADDR;

       u32  NFDATA;

       u32  NFSTAT;

       u32  NFECC;

};

#endif

  mini2440.h里添加nand_flash相关宏定义

#gedit include/configs/mini2440.h

#define CONFIG_CMD_NAND

/* NAND flash settings */

#if defined(CONFIG_CMD_NAND)

#define CONFIG_NAND_S3C2410

#define CONFIG_SYS_NAND_BASE            0x4E000000 //Nand配置寄存器基地址

#define CONFIG_SYS_MAX_NAND_DEVICE      1 

#define CONFIG_MTD_NAND_VERIFY_WRITE    1 

//#define NAND_SAMSUNG_LP_OPTIONS       1  //注意:我们这里是MNand Flash,所以不、//,如果是M的大块Nand Flash,则需加上

#endif

       mini2440.h里添加saveenv命令的支持

#gedit include/configs/mini2440.h

//#define CONFIG_ENV_IS_IN_FLASH   1   /*屏蔽Nor Flash saveenv相关宏定义*/

//#define CONFIG_ENV_SIZE          0x10000  /* Total Size of Environment Sector */

#define   CONFIG_ENV_IS_IN_NAND  1

#define   CONFIG_ENV_OFFSET        0x60000

#define   CONFIG_ENV_SIZE          0x20000

#define   CONFIG_CMD_SAVEENV

编译下载,从Nand Flash启动,从出现的信息看出,此时已经支持Nand Flash了:

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值