Chinaunix首页 | 论坛 | 博客
  • 博客访问: 416787
  • 博文数量: 131
  • 博客积分: 1990
  • 博客等级: 上尉
  • 技术积分: 996
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-24 12:15
文章分类
文章存档

2011年(4)

2010年(19)

2009年(108)

我的朋友

分类: 嵌入式

2009-10-30 16:19:18

一、代码搬运
 
    u-boot启动时,需要 copy u-boot to ram 的过程,通过自己定义的 nand_read.c实现,该步骤与u-boot- 1.1.6移植(一)同,需要注意的是增加对nand flash支持后编译出来的bin文件将大于128KB,所以修改start.S即可:
@ copy UBOOT to RAM
    ldr    r0, _TEXT_BASE
    mov     r1, #0x0
    mov    r2, #0x20000 //改为mov r2,#0x40000,这是FS2410分配给u-boot的存储空间
    bl    nand_read_ll
二、修改配置文件 include/configs/s3c2410.h 使支持NAND
 
#define CONFIG_COMMANDS \
            (CONFIG_CMD_DFL     | \
            CFG_CMD_CACHE     | \
            CFG_CMD_ENV         | \
            CFG_CMD_NET         | \
            CFG_CMD_PING     | \
            CFG_CMD_NAND     | \
            \
            \
            \
            CFG_CMD_REGINFO  | \
            CFG_CMD_DATE     | \
            CFG_CMD_ELF)
#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

#define CONFIG_BOOTDELAY    3
#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        202.193.74.101
#define CONFIG_SERVERIP        202.193.74.235
#define CONFIG_BOOTCOMMAND    "nand read 0x30007fc0 0x40000 0x1c0000; bootm 0x30007fc0"
三、建立cpu/arm920t/s3c24x0/nand_flash.c,实现board_nand_init函数
    《嵌入式Linux应用开发完全手册》中介召的nand_flash.c包含对S3C2440的支持,在这里一并列出,供日后参考。
(1)针对S3C2410、S3C2440 NAND Flash控制器的不同来定义一些数据结构和函数,在include/s3c24x0.h 文件中增加S3C2440_NAND数据结构。

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;
} S3C2440_NAND;
(2)在 include/s3c2410.h 文件中仿照 S3C2410_GetBase_NAND函数定义S3C2440_GetBase_NAND函数。

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.c文件
 
#include
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include
#include
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)
 
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;
    }
}

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;
      
      
    default:
        chip->IO_ADDR_W = (void *)&s3c2410nand->NFDATA;
        break;
    }
}

static int s3c2410_nand_devready(struct mtd_info *mtd)
{
    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();
    return (s3c2410nand->NFSTAT & S3C2410_NFSTAT_READY);
}
 
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;
    }
}

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;
      
      
    default:
        chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
        break;
    }
}

static int s3c2440_nand_devready(struct mtd_info *mtd)
{
    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
    return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);
}

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)
    {
      
        s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
    }
    else
    {
      
        s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
      
        s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0);
    }
}

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  

至此,编译生成 u-boot.bin 并烧入NAND Flash,启动,便可以引导内核了。
 
本文来自: () 详细出处参考:
阅读(1204) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~