UBOOT_NAND驱动分析

本文档详细分析了U-BOOT中的NAND驱动,包括驱动入口、NAND相关的结构体、初始化过程及操作函数。从start_armboot()调用nand_init()开始,介绍了NAND设备参数描述表、mtd_info和nand_chip结构体,以及nand_init_chip、board_nand_init和nand_scan等关键函数的功能和作用。
摘要由CSDN通过智能技术生成

一、编写目的

        在《NAND_FLASH(K9F1208U0C)驱动分析》一文中,通过分析AT91SAM9260EK开发板Bootstrap中的NAND驱动时,发现该代码为了优化代码体积(4KB限制),没有实现nand的擦写驱动,因此现重新对U-BOOT的代码的NAND驱动进行分析。以加强对NAND的理解。

本文档用于记录NAND FLASH驱动分析的过程。所使用的代码为以前开发过的一个U-BOOT(64MB版本)。


二、驱动分析

1. 驱动入口

        U-BOOT的C语言入口位于./lib_arm/board.c的start_armboot()中。在该函数中有调用NAND的初始化函数nand_init()。

start_armboot()中的代码片段(./lib_arm/board.c)

#if defined(CONFIG_CMD_NAND)

puts ("NAND:  ");

nand_init(); /* go init the NAND */

#endif

 

#if defined(CONFIG_CMD_ONENAND)

onenand_init();

#endif

 

2. NAND相关的结构体

a) NAND设备参数描述表

./include/linux/mtd/nand_ids.h中的结构定义

static struct nand_flash_dev nand_flash_ids[] = {

{"Toshiba TC5816BDC",     NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0},

{"Toshiba TC5832DC",      NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0},

{"Toshiba TH58V128DC",    NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000, 0},

{"Toshiba TC58256FT/DC",  NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000, 0},

{"Toshiba TH58512FT",     NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000, 0},

{"Toshiba TC58V32DC",     NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000, 0},

{"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000, 0},

{"Toshiba TC58V16BDC",    NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000, 0},

{"Toshiba TH58100FT",     NAND_MFR_TOSHIBA, 0x79, 27, 0, 3, 0x4000, 0},

{"Samsung KM29N16000",    NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0},

{"Samsung unknown 4Mb",   NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0},

{"Samsung KM29U128T",     NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000, 0},

{"Samsung KM29U256T",     NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000, 0},

{"Samsung unknown 64Mb",  NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},  // 本核心板使用的NAND

{"Samsung KM29W32000",    NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000, 0},   // NAND_MFR_SAMSUNG = 0xEC

{"Samsung unknown 4Mb",   NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000, 0},

{"Samsung KM29U64000",    NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000, 0},

{"Samsung KM29W16000",    NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000, 0},

{"Samsung K9F5616Q0C",    NAND_MFR_SAMSUNG, 0x45, 25, 0, 2, 0x4000, 1},

{"Samsung K9K1216Q0C",    NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1},

{"Samsung K9F1G08U0M",    NAND_MFR_SAMSUNG, 0xf1, 27, 0, 2, 0, 0},

{NULL,}

};

 

        该表记录着UBOOT所支持的NAND型号列表,软件读取NAND的ID值后,与该表中的ID值(K9F1208U0C的ID等于0xEC76)进行比较,如ID相等,则说明UBOOT目前支持该NAND芯片,则从该表中获取NAND的信息(BLOCK SIZE、PAGE SIZE等)。

 

b) MTD设备信息结构体typedef struct mtd_info nand_info_t

./include/linux/mtd/mtd.h中的结构定义

struct mtd_info {

u_char type;

u_int32_t flags;

u_int32_t size;  /* Total size of the MTD */

 

/* "Major" erase size for the device. Na飗e users may take this

 * to be the only erase size available, or may use the more detailed

 * information below if they desire

 */

u_int32_t erasesize;

 

u_int32_t oobblock;  /* Size of OOB blocks (e.g. 512) */

u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */

u_int32_t oobavail;  /* Number of bytes in OOB area available for fs  */

u_int32_t ecctype;

u_int32_t eccsize;

 

 

/* Kernel-only stuff starts here. */

char *name;

int index;

 

/* oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) */

struct nand_oobinfo oobinfo;

 

/* Data for variable erase regions. If numeraseregions is zero,

 * it means that the whole device has erasesize as given above.

 */

int numeraseregions;

struct mtd_erase_region_info *eraseregions;

 

/* This really shouldn't be here. It can go away in 2.5 */

u_int32_t bank_size;

 

int (*erase) (struct mtd_info *mtd, struct erase_info *instr);

 

/* This stuff for eXecute-In-Place */

int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);

 

/* We probably shouldn't allow XIP if the unpoint isn't a NULL */

void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);

 

 

int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);

int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);

 

int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);

int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);

 

int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);

int (*write_oob) (struct mtd_info *mtd, loff_t to, si

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值