u-boot1.1.6移植到S3C2410的详细步骤--nand flash(新代码)

时间:2022-09-18 03:01:30

一、移植前说明:

1. 工作环境:
         RedHat 9 ,内核 2.4.20
     交叉编译器:
       Arm-linux-gcc 3.4.4
     目标板:
    s3c2410,NAND Flash:64M K9F1208U0B

2. 下载源码,建立工作目录
    u-boot的源码可以从以下网址下载:
    http://downloads.sourceforge.net/u-boot/u-boot-1.1.6.tar.bz2
    把下载的源码拷贝到/tmp目录,解压;
    tar jxvf u-boot-1.1.6.tar.bz2

二、移植步骤如下:
1.在board子目录中建立自己的目录tbwoody2410
[root@localhost u-boot-1.1.6]#cp -rf board/smdk2410 board/tbwoody2410
[root@localhost u-boot-1.1.6]#cp include/configs/smdk2410.h include/configs/tbwoody2410.h
[root@localhost u-boot-1.1.6]#cd board/tbwoody2410
[root@localhost tbwoody2410]#mv smdk2410.c tbwoody2410.c

tbwoody2410.h是开发板的配置文件,他包括开发板的CPU、系统时钟、RAM、FLASH系统及其他相关的配置信息,
由于u-boot已经支持三星的SMDK2410开发板,所以移植的时候直接拷贝SMDK2410的配置文件,做相应的修改即可。
由于Uboot对SMDK2410板的NAND Flash初始化部分没有写,即lib_arm/board.c中的start_armboot函数中有这么一句:
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND:");
nand_init(); /* go init the NAND */
#endif
但是在board/smdk2410目录下源文件中都没有定义nand_init这个函数。所以需要我们补充这个函数以及这个函数涉及的底层操作,
NAND Flash的读写操作相对复杂。

2.修改顶层Makefile,回到u-boot-1.1.6目录

[root@localhost u-boot-1.1.6]#gedit Makefile
找到1879行,
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
在后面添加自己的配置:
tbwoody2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t tbwoody2410 NULL s3c24x0
各项的意思如下:
arm:        CPU的架构(ARCH)
arm920t:    CPU的类型(CPU),其对应于cpu/arm920t子目录。
tbwoody2410:    开发板的型号(BOARD),对应于board/tbwoody2410目录。
NULL:       开发者/或经销商(vender)。
s3c24x0:    片上系统(SOC)。

3.修改include/configs/tbwoody2410.h文件
修改:111行
# define   CFG_PROMPT     “SMDK2410 #”
为:
# define   CFG_PROMPT     “tbwoody2410 #”
这是u-boot的命令行提示符。

4.修改board/tbwoody2410/Makefile
将:
    OBJS    := smdk2410.o flash.o
改为:
    OBJS     := tbwoody2410.o flash.o
当然,tbwoody2410下的 smdk2410.c在前面我们已经改成了tbwoody2410.c;

5.依照你自己开发板的内存地址分配情况修改board/tbwoody2410/lowlevel_init.S文件
#include <config.h>
#include <version.h>


#define BWSCON 0x48000000

/* BWSCON */
#define DW8        (0x0)
#define DW16   (0x1)
#define DW32   (0x2)
#define WAIT   (0x1<<2)
#define UBLB   (0x1<<3)

#define B1_BWSCON   (DW16)
#define B2_BWSCON   (DW16)
#define B3_BWSCON   (DW16 + WAIT + UBLB)
#define B4_BWSCON   (DW16)
#define B5_BWSCON   (DW16)
#define B6_BWSCON   (DW32)
#define B7_BWSCON   (DW32)

/* BANK0CON */
#define B0_Tacs   0x3 /* 0clk */
#define B0_Tcos   0x3 /* 0clk */
#define B0_Tacc   0x7 /* 14clk */
#define B0_Tcoh   0x3 /* 0clk */
#define B0_Tah   0x3 /* 0clk */
#define B0_Tacp   0x3
#define B0_PMC   0x3 /* normal */

/* BANK1CON */
#define B1_Tacs   0x3 /* 0clk */
#define B1_Tcos   0x3 /* 0clk */
#define B1_Tacc   0x7 /* 14clk */
#define B1_Tcoh   0x3 /* 0clk */
#define B1_Tah   0x3 /* 0clk */
#define B1_Tacp   0x3
#define B1_PMC   0x0

#define B2_Tacs   0x0
#define B2_Tcos   0x0
#define B2_Tacc   0x7
#define B2_Tcoh   0x0
#define B2_Tah   0x0
#define B2_Tacp   0x0
#define B2_PMC   0x0

#define B3_Tacs   0x0 /* 0clk */
#define B3_Tcos   0x3 /* 4clk */
#define B3_Tacc   0x7 /* 14clk */
#define B3_Tcoh   0x1 /* 1clk */
#define B3_Tah   0x0 /* 0clk */
#define B3_Tacp   0x3     /* 6clk */
#define B3_PMC   0x0 /* normal */

#define B4_Tacs   0x0 /* 0clk */
#define B4_Tcos   0x0 /* 0clk */
#define B4_Tacc   0x7 /* 14clk */
#define B4_Tcoh   0x0 /* 0clk */
#define B4_Tah   0x0 /* 0clk */
#define B4_Tacp   0x0
#define B4_PMC   0x0 /* normal */

#define B5_Tacs   0x0 /* 0clk */
#define B5_Tcos   0x0 /* 0clk */
#define B5_Tacc   0x7 /* 14clk */
#define B5_Tcoh   0x0 /* 0clk */
#define B5_Tah   0x0 /* 0clk */
#define B5_Tacp   0x0
#define B5_PMC   0x0 /* normal */

#define B6_MT   0x3 /* SDRAM */
#define B6_Trcd 0x1
#define B6_SCAN   0x1 /* 9bit */

#define B7_MT   0x3 /* SDRAM */
#define B7_Trcd   0x1 /* 3clk */
#define B7_SCAN   0x1 /* 9bit */

/* REFRESH parameter */
#define REFEN   0x1 /* Refresh enable */
#define TREFMD   0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp   0x0 /* 2clk */
#define Trc   0x3 /* 7clk */
#define Tchr   0x2 /* 3clk */
#define REFCNT   1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
/**************************************/

_TEXT_BASE:
.word TEXT_BASE

.globl lowlevel_init
lowlevel_init:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr     r0, =SMRDATA
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =BWSCON /* Bus Width Status Controller */
add     r2, r0, #13*4
0:
ldr     r3, [r0], #4
str     r3, [r1], #4
cmp     r2, r0
bne     0b

/* everything is fine now */
mov pc, lr

.ltorg
/* the literal pools origin */

SMRDATA:
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0x32
    .word 0x30
    .word 0x30

6.测试编译能否成功
[root@localhost u-boot-1.1.6]#make tbwoody2410_config
[root@localhost u-boot-1.1.6]#make CROSS_COMPILE=arm-linux-
如果没有问题,在u-boot-1.1.6目录下就生成u-boot.bin,因为到这一步只是做了点小改动,
并未涉及敏感问题,测试一下可增加点信心.O(∩_∩)O~

7.在board/tbwoody2410下加入NAND FLASH 读函数,建立nand_read.c,加入如下内容(copy from vivi):

#include <config.h>
#include "linux/mtd/mtd.h"
#include "linux/mtd/nand.h"

#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#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 BUSY 1
inline void wait_idle(void) {
    int i;
    while(!(NFSTAT & BUSY))
      for(i=0; i<10; i++);
}
#define NAND_SECTOR_SIZE 512
#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;
    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
        return -1; /* invalid alignment */
    }
    /* chip Enable */
    NFCONF &= ~0x800;
    for(i=0; i<10; i++);
     for(i=start_addr; i < (start_addr + size);) {
      /* READ0 */
      NFCMD = 0;
       /* Write Address */
      NFADDR = i & 0xff;
      NFADDR = (i >> 9) & 0xff;
      NFADDR = (i >> 17) & 0xff;
      NFADDR = (i >> 25) & 0xff;
       wait_idle();
       for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = (NFDATA & 0xff);
buf++;
      }
    }
     /* chip Disable */
    NFCONF |= 0x800; /* chip disable */
    return 0;
}

8.修改cpu/arm920t/start.S文件
2410的启动代码可以在外部的NAND FLASH上执行,启动时,NAND FLASH的前4KB(地址为0x00000000,OM[1:0]=0)
将被装载到SDRAM中被称为Setppingstone的地址中,然后开始执行这段代码。启动以后,这4KB的空间可以做其他用途,
在start.S加入搬运代码如下: 174行
...........
...........
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

/*08-6-24********************************************************/
#ifdef CONFIG_S3C2410_NAND_BOOT /*这个一定要放在堆栈设置之前*/
    bl    copy_myself
#endif    /*CONFIG_S3C2410_NAND_BOOT*/
/*08-6-24********************************************************/

#endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

    /* Set up the stack                            */
stack_setup:
..................
    /**************************************************************************
*
* copy u-boot    to ram 放在start.S靠后的位置
*
*************************************************************************
*/
#ifdef CONFIG_S3C2410_NAND_BOOT
/*
@ copy_myself: copy u-boot to ram
*/
copy_myself:
    mov   r10, lr

    @ reset NAND
    mov    r1, #NAND_CTL_BASE
    ldr    r2, =0xf830        @ initial value
    str    r2, [r1, #oNFCONF]
    ldr    r2, [r1, #oNFCONF]
    bic    r2, r2, #0x800        @ enable chip
    str    r2, [r1, #oNFCONF]
    mov    r2, #0xff        @ RESET command
    strb    r2, [r1, #oNFCMD]
    mov    r3, #0            @ wait
1:    add    r3, r3, #0x1
    cmp    r3, #0xa
    blt    1b
2:    ldr    r2, [r1, #oNFSTAT]    @ wait ready
    tst    r2, #0x1
    beq    2b
    ldr    r2, [r1, #oNFCONF]
    orr    r2, r2, #0x800        @ disable chip
    str    r2, [r1, #oNFCONF]

    @ get read to call C functions
    ldr    sp, DW_STACK_START    @ setup stack pointer
    mov    fp, #0            @ no previous frame, so fp=0

    @ copy UBOOT to RAM
    ldr    r0, _TEXT_BASE
    mov     r1, #0x0
    mov    r2, #0x20000
    bl    nand_read_ll

    teq    r0, #0x0
    beq    ok_nand_read

bad_nand_read:
1:    b    1b        @ infinite loop
    
ok_nand_read:

    @ verify
    
    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    done_nand_read    
    bne    go_next
notmatch:
1:    b    1b
done_nand_read:
    
    mov   pc, r10

#endif    
    @ CONFIG_S3C2440_NAND_BOOT

DW_STACK_START:
    .word    STACK_BASE+STACK_SIZE-4

9.修改include/configs/tbwoody2410.h文件,添加如下内容:

/*08-6-25***************************************************/
/*-----------------------------------------------------------------------
* NAND FLASH BOOT
*/
#define    CONFIG_S3C2410_NAND_BOOT    1
#define    STACK_BASE            0x33f00000
#define    STACK_SIZE                0x8000
#define    UBOOT_RAM_BASE          0x30100000

#define    NAND_CTL_BASE            0x4e000000
#define    bINT_CTL(Nb)            _REG(INT_CTL_BASE+(Nb))


#define    oNFCONF                0x00
#define    oNFCMD                0x04
#define    oNFADDR                0x08
#define    oNFDATA                0x0c
#define    oNFSTAT                0x10
#define    oNFECC                0x14
/*--------------------------------------------------------------------*/
#define NAND_MAX_CHIPS        1


10.修改board/tbwoody2410/Makefile
OBJS := tbwoody2410.o flash.o nand_read.o
就是在后面加入了一个nand_read.o


11.重新测试编译能否成功
[root@localhost u-boot-1.1.6]#make tbwoody2410_config
[root@localhost u-boot-1.1.6]#make CROSS_COMPILE=arm-linux-

 


下面进行第二部分的配置:使用新代码


一、代码搬运

    u-boot启动时,需要 copy u-boot to ram 的过程,通过自己定义的 nand_read.c实现,
需要注意的是增加对nand flash支持后编译出来的bin文件将大于128KB,所以修改
cpu/arm920t/start.S即可:
@ copy UBOOT to RAM
    ldr    r0, _TEXT_BASE
    mov     r1, #0x0
    mov    r2, #0x20000 //改为mov r2,#0x40000,这是s3c2410分配给u-boot的存储空间
    bl    nand_read_ll

二、修改配置文件 include/configs/tbwoody2410.h 使支持NAND
/***********************************************************
* Command definition
***********************************************************/
#define CONFIG_COMMANDS /
    (CONFIG_CMD_DFL | /
    CFG_CMD_CACHE | /
    CFG_CMD_NAND          | /
            CFG_CMD_ENV           | /
            CFG_CMD_NET            | /
            CFG_CMD_PING          | /
    /*CFG_CMD_EEPROM |*/ /
    /*CFG_CMD_I2C |*/ /
    /*CFG_CMD_USB |*/ /
    CFG_CMD_REGINFO | /
    CFG_CMD_DATE | /
    CFG_CMD_ELF)

/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF*/
#define CFG_NAND_BASE 0x4E000000
#define CFG_MAX_NAND_DEVICE 1
#define NAND_MAX_CHIPS    1

#define CFG_ENV_IS_IN_NAND 1
#define CMD_SAVEENV
#define CFG_ENV_SIZE     0x10000
#define CFG_ENV_OFFSET 0x30000
/*FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF*/

#define CONFIG_BOOTDELAY 2
#define CONFIG_BOOTARGS    "noinitrd root=/dev/mtdblock2 init=/linuxrc devfs=mount console=ttySAC0,115200"
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK          255.255.255.0
#define CONFIG_IPADDR   10.0.0.110
#define CONFIG_SERVERIP   10.0.0.1
/*#define CONFIG_BOOTFILE "elinos-lart" */
#define CONFIG_BOOTCOMMAND "nand read 0x30008000 0x100000 0x300000;bootm 0x30008000"

三、建立cpu/arm920t/s3c24x0/nand_flash.c,实现board_nand_init函数
   《嵌入式Linux应用开发完全手册》中介召的nand_flash.c包含对S3C2440的支持,
   在这里一并列出,供日后参考。
(1)针对S3C2410、S3C2440 NAND Flash控制器的不同来定义一些数据结构和函数,
   在include/s3c24x0.h 文件中增加S3C2440_NAND数据结构。
   /* NAND FLASH (see S3C2440 manual chapter 6, www.100ask.net) */
typedef struct {
    S3C24X0_REG32    NFCONF;
    S3C24X0_REG32    NFCONT;
    S3C24X0_REG32    NFCMD;
    S3C24X0_REG32    NFADDR;
    S3C24X0_REG32    NFDATA;
    S3C24X0_REG32    NFMECCD0;
    S3C24X0_REG32    NFMECCD1;
    S3C24X0_REG32    NFSECCD;
    S3C24X0_REG32    NFSTAT;
    S3C24X0_REG32    NFESTAT0;
    S3C24X0_REG32    NFESTAT1;
    S3C24X0_REG32    NFMECC0;
    S3C24X0_REG32    NFMECC1;
    S3C24X0_REG32    NFSECC;
    S3C24X0_REG32    NFSBLK;
    S3C24X0_REG32    NFEBLK;
} /*__attribute__((__packed__))*/ S3C2440_NAND;

(2)在 include/s3c2410.h 文件中仿照 S3C2410_GetBase_NAND函数定义S3C2440_GetBase_NAND函数。

/* for s3c2440, www.100ask.net */
static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)
{
    return (S3C2440_NAND * const)S3C2410_NAND_BASE;
}

(3) cpu/arm920t/s3c24x0/nand_flash.c

/*
* Nand flash interface of s3c2410/s3c2440, by www.100ask.net
* Changed from drivers/mtd/nand/s3c2410.c of kernel 2.6.13
*/

#include <common.h>

#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include <s3c2410.h>
#include <nand.h>

DECLARE_GLOBAL_DATA_PTR;

#define S3C2410_NFSTAT_READY    (1<<0)
#define S3C2410_NFCONF_nFCE     (1<<11)

#define S3C2440_NFSTAT_READY    (1<<0)
#define S3C2440_NFCONT_nFCE     (1<<1)


/* select chip, for s3c2410 */
static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
{
    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

    if (chip == -1) {
        s3c2410nand->NFCONF |= S3C2410_NFCONF_nFCE;
    } else {
        s3c2410nand->NFCONF &= ~S3C2410_NFCONF_nFCE;
    }
}

/* command and control functions, for s3c2410
*
* Note, these all use tglx's method of changing the IO_ADDR_W field
* to make the code simpler, and use the nand layer's code to issue the
* command and address sequences via the proper IO ports.
*
*/
static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
    struct nand_chip *chip = mtd->priv;

    switch (cmd) {
    case NAND_CTL_SETNCE:
    case NAND_CTL_CLRNCE:
        printf("%s: called for NCE/n", __FUNCTION__);
        break;

    case NAND_CTL_SETCLE:
        chip->IO_ADDR_W = (void *)&s3c2410nand->NFCMD;
        break;

    case NAND_CTL_SETALE:
        chip->IO_ADDR_W = (void *)&s3c2410nand->NFADDR;
        break;

        /* NAND_CTL_CLRCLE: */
        /* NAND_CTL_CLRALE: */
    default:
        chip->IO_ADDR_W = (void *)&s3c2410nand->NFDATA;
        break;
    }
}

/* s3c2410_nand_devready()
*
* returns 0 if the nand is busy, 1 if it is ready
*/
static int s3c2410_nand_devready(struct mtd_info *mtd)
{
    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

    return (s3c2410nand->NFSTAT & S3C2410_NFSTAT_READY);
}


/* select chip, for s3c2440 */
static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chip)
{
    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

    if (chip == -1) {
        s3c2440nand->NFCONT |= S3C2440_NFCONT_nFCE;
    } else {
        s3c2440nand->NFCONT &= ~S3C2440_NFCONT_nFCE;
    }
}

/* command and control functions */
static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
    struct nand_chip *chip = mtd->priv;

    switch (cmd) {
    case NAND_CTL_SETNCE:
    case NAND_CTL_CLRNCE:
        printf("%s: called for NCE/n", __FUNCTION__);
        break;

    case NAND_CTL_SETCLE:
        chip->IO_ADDR_W = (void *)&s3c2440nand->NFCMD;
        break;

    case NAND_CTL_SETALE:
        chip->IO_ADDR_W = (void *)&s3c2440nand->NFADDR;
        break;

        /* NAND_CTL_CLRCLE: */
        /* NAND_CTL_CLRALE: */
    default:
        chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
        break;
    }
}

/* s3c2440_nand_devready()
*
* returns 0 if the nand is busy, 1 if it is ready
*/
static int s3c2440_nand_devready(struct mtd_info *mtd)
{
    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

    return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);
}

/*
* Nand flash hardware initialization:
* Set the timing, enable NAND flash controller
*/
static void s3c24x0_nand_inithw(void)
{
    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

#define TACLS   0
#define TWRPH0 4
#define TWRPH1 2

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
    {
        /* Enable NAND flash controller, Initialize ECC, enable chip select, Set flash memory timing */
        s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
    }
    else
    {
        /* Set flash memory timing */
        s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
        /* Initialize ECC, enable chip select, NAND flash controller enable */
        s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0);
    }
}

/*
* Called by drivers/nand/nand.c, initialize the interface of nand flash
*/
void board_nand_init(struct nand_chip *chip)
{
    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

    s3c24x0_nand_inithw();

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410) {
        chip->IO_ADDR_R    = (void *)&s3c2410nand->NFDATA;
        chip->IO_ADDR_W    = (void *)&s3c2410nand->NFDATA;
        chip->hwcontrol    = s3c2410_nand_hwcontrol;
        chip->dev_ready    = s3c2410_nand_devready;
        chip->select_chip = s3c2410_nand_select_chip;
        chip->options      = 0;
    } else {
        chip->IO_ADDR_R    = (void *)&s3c2440nand->NFDATA;
        chip->IO_ADDR_W    = (void *)&s3c2440nand->NFDATA;
        chip->hwcontrol    = s3c2440_nand_hwcontrol;
        chip->dev_ready    = s3c2440_nand_devready;
        chip->select_chip = s3c2440_nand_select_chip;
        chip->options      = 0;
    }

    chip->eccmode       = NAND_ECC_SOFT;
}

#endif


四、将nand_flash.c编入 u-boot,修改cpu/arm920t/s3c24x0/Makefile文件

COBJS    = i2c.o interrupts.o serial.o speed.o /
      usb_ohci.o nand_flash.o


接下来修改board/tbwoody2410/tbwoody2410.c下面的代码,关闭蜂鸣器,否则太烦人了,
/* set up the I/O ports */
gpio->GPACON = 0x007FFFFF;
//gpio->GPBCON = 0x00044555;
    gpio->GPBCON = 0x0004455F;//关闭蜂鸣器
gpio->GPBUP = 0x000007FF;
gpio->GPCCON = 0xAAAAAAAA;
gpio->GPCUP = 0x0000FFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0x0000FFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
//gpio->GPFCON = 0x000055AA;
gpio->GPFCON = 0x000055AF;//关闭LED
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF95FFBA;
gpio->GPGUP = 0x0000FFFF;
gpio->GPHCON = 0x002AFAAA;
gpio->GPHUP = 0x000007FF;


五.重新测试编译能否成功
[root@localhost u-boot-1.1.6]#make tbwoody2410_config
[root@localhost u-boot-1.1.6]#make CROSS_COMPILE=arm-linux-

如果出现下面错误:
......
......uses hardware FP, whereas u-boot uses software FP......
......
改正方法如下:
修改u-boot-1.1.6/cpu/arm920t/config.mk
去掉-msoft-float就可以了
然后别忘了执行
[root@localhost u-boot-1.1.6]#make distclean
[root@localhost u-boot-1.1.6]#make tbwoody2410_config
[root@localhost u-boot-1.1.6]#make CROSS_COMPILE=arm-linux-