免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 729 | 回复: 0
打印 上一主题 下一主题

u-boot NAND flash的支持(使用新代码) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-20 16:18 |只看该作者 |倒序浏览

                                在u-boot-1.1.6移植(二)
http://blog.chinaunix.net/u2/74310/showart.php?id=1091929
中提到:u-boot 运行至第二阶段进入 start_armboot()函数。其中 nand_init()函数是对 nand flash 的最初初始化函数。其调用与 CFG_NAND_LEGACY 宏有关,如果没定义 CFG_NAND_LEGACY 这个宏,就按照start_armboot()调用 drivers/nand/nand.c 中的 nand_init 函数(该函数在 1.1.6 已经被实现), 但还有个 board_nand_init()函数没实现,需自己添加;如果定义了CFG_NAND_LEGACY,就不使用默认的 nand_init,而调用自己写的 nand_init 函数了。u-boot-1.1.6中对NAND flash的支持有新旧两套代码,新代码在drivers/nand目录下,旧代码在drivers/nand_legacy目录下,文档doc/README.nand对这两套代码有所说明:使用旧代码需要定义更多的宏,u-boot-1.1.6移植(二)中可以看到,比较复杂,而新代码移植自Linux 2.6.12,它更加智能,可以自动识别更多型号的NAND flash。本文使用新代码并移植在优龙FS2410成功。
    NAND flash 的支持以及下篇《u-boot烧写yaffs文件系统映象》参考《嵌入式Linux应用开发完全手册》,实验时得到该书作者南方兄的热情帮助,在此感谢!

移植过程:

一、代码搬运

    u-boot启动时,需要 copy u-boot to ram 的过程,通过自己定义的 nand_read.c实现,该步骤与u-boot-1.1.6移植(一)同,参考
http://blog.chinaunix.net/u2/74310/showart.php?id=1091899
,需要注意的是增加对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/fs2410.h 使支持NAND
     /***********************************************************
* Command definition
***********************************************************/
#define CONFIG_COMMANDS \
            (CONFIG_CMD_DFL     | \
            CFG_CMD_CACHE     | \
            CFG_CMD_ENV         | \
            CFG_CMD_NET         | \
            CFG_CMD_PING     | \
            CFG_CMD_NAND     | \
            /*CFG_CMD_EEPROM |*/ \
            /*CFG_CMD_I2C     |*/ \
            /*CFG_CMD_USB     |*/ \
            CFG_CMD_REGINFO  | \
            CFG_CMD_DATE     | \
            CFG_CMD_ELF)
#define CFG_NAND_BASE        0x4E000000#define CFG_MAX_NAND_DEVICE    1    /* Max number of NAND devices        */#define NAND_MAX_CHIPS        1
/*保存环境变量用到的宏,否则不能 saveenv */
#define CFG_ENV_IS_IN_NAND    1#define CFG_NAND_BASE        0x4E000000#define CMD_SAVEENV#define CFG_ENV_SIZE            0x10000 /* Total Size of Environment Sector */
#define CFG_ENV_OFFSET      0x30000 /*环境变量在NAND FLASH的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        192.168.1.100#define CONFIG_SERVERIP        192.168.1.2/*#define CONFIG_BOOTFILE    "elinos-lart" */#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数据结构。
/* 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
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include
#include
DECLARE_GLOBAL_DATA_PTR;
#define S3C2410_NFSTAT_READY    (1NFCONF |= 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 = (1NFCONF = (TACLSNFCONT = (1bd->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,启动,便可以引导内核了。
[color="#ff0000"]


[color="#ff0000"]
               
               
               
               



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74310/showart_1135068.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP