Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1230158
  • 博文数量: 479
  • 博客积分: 12240
  • 博客等级: 上将
  • 技术积分: 4999
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-24 17:12
文章分类

全部博文(479)

文章存档

2014年(1)

2013年(1)

2012年(1)

2011年(95)

2010年(177)

2009年(167)

2008年(16)

2007年(21)

分类: 嵌入式

2009-10-14 21:29:36

U-Boot中的NAND FLASH

以ARM为例,简要分析u-boot中的NAND FLASH。

初始化

    进入初始化

    U-Boot在lib_arm/board.c中调用nand_init函数开始对NAND FLASH进行初始化。
    lib_arm/board.c:      nand_init();            /* go init the NAND */

#if defined(CONFIG_CMD_NAND)
        puts ("NAND:  ");            //打印NAND FLASH提示信息

        nand_init();            /* go init the NAND */
        WATCHDOG_RESET();
#endif

    nand_init函数

    而nand_init的具体实现,则在drivers/mtd/nand/nand.c中实现,代码如下:
void nand_init(void)
{
        int i;
        unsigned int size = 0;

        for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
                nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
                size += nand_info[i].size;
                if (nand_curr_device == -1)
                        nand_curr_device = i;
        }
        printf("%lu MiB\n", size / (1024 * 1024));

#ifdef CFG_NAND_SELECT_DEVICE
        /*
         * Select the chip in the board/cpu specific driver
         */
        board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
#endif
}

    nand_init_chip函数

    nand_init中的nand_init_chip函数,具体实现代码如下:
static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
                           ulong base_addr)
{
        mtd->priv = nand;

        /* 
          * 设定了NAND FLASH(控制器)的基地址,base_addr的具体值将在后面介绍
          */
        nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr; 
        if (board_nand_init(nand) == 0) {
                if (nand_scan(mtd, 1) == 0) {
                        if (!mtd->name)
                                mtd->name = (char *)default_nand_name;
                } else
                        mtd->name = NULL;
        } else {
                mtd->name = NULL;
                mtd->size = 0;
        }

}

    其中的nand_info、base_address等都在文件开始处定义。
int nand_curr_device = -1;
nand_info_t nand_info[CFG_MAX_NAND_DEVICE];

static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE];

static const char default_nand_name[] = "nand";

extern int board_nand_init(struct nand_chip *nand);

    NAND FLASH(控制器)基地址

    CFG_NAND_BASE_LIST和CFG_NAND_BASE:
#ifndef CFG_NAND_BASE_LIST
#define CFG_NAND_BASE_LIST { CFG_NAND_BASE }
#endif

static ulong base_address[CFG_MAX_NAND_DEVICE] =CFG_N AND_BASE_LIST;
    通常只有一块NAND FLASH,因此只需定义CFG_NAND_BASE即可,一般在include/configs/开发板.h中配置,如:
#define CFG_NAND_BASE           0x05000000


    board_nand_init函数
    nand_init_chip函数调用了board_nand_init函数,board_nand_init函数在./board/开发板名称/nand.c中实现,如下是范例:
int board_nand_init(struct nand_chip *nand)
{
        /* 下面这4行的初始化,并不是每个板子都需要的,有NAND FLASH控制器的一般都通过其他方法实现了 */
        nand->IO_ADDR_R = (void __iomem *)(void *)K9F2G08_DATA;
        nand->IO_ADDR_W = (void __iomem *)(void *)K9F2G08_DATA;
        nand->IO_COMMAND = (void __iomem *)(void *)K9F2G08_CLE;
        nand->IO_ADDRESS = (void __iomem *)(void *)K9F2G08_ALE;

        nand->options    = NAND_SAMSUNG_LP_OPTIONS|NAND_NO_AUTOINCR;
        nand->eccmode    = NAND_ECC_SOFT;
        nand->hwcontrol  = epcm_nand_hwcontrol; //MUST have
        nand->chip_delay = 18;
        return 0;
}

阅读(1703) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~