http://hi.baidu.com/designhouse/item/f778bc1658b038dcbf9042d8
通过/proc虚拟文件系统读取MTD分区表:cat /proc/mtd
具体由linux/drivers/mtd下的mtdcore.c文件中的mtd_read_proc函数来实现:
static inline int mtd_proc_info (char *buf,int i)
{
struct mtd_info *this = mtd_table[i];
if (!this)
return 0;
return sprintf(buf,"mtd%d: %8.8x %8.8x "%s"n",i,this->size,
this->erasesize,this->name);
}
static int mtd_read_proc (char *page,char **start,off_t off,int count,
int *eof,void *data_unused)
{
int len,l,i;
off_t begin = 0;
mutex_lock(&mtd_table_mutex);
len = sprintf(page,"dev: size erasesize namen");
for (i=0; i< MAX_MTD_DEVICES; i++) {
l = mtd_proc_info(page + len,i);
len += l;
if (len+begin > off+count)
goto done;
if (len+begin < off) {
begin += len;
len = 0;
}
}
*eof = 1;
done:
mutex_unlock(&mtd_table_mutex);
if (off >= len+begin)
return 0;
*start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
读出来的结果如下:
dev: size erasesize name
mtd0: 01000000 00020000 "boot"
mtd1: 01000000 00020000 "setting"
mtd2: 02000000 00020000 "rootfs"
mtd3: 0be00000 00020000 "home"
mtd4: 00200000 00020000 "storage"
mtd5: 00040000 00010000 "u-boot"
mtd6: 00040000 00010000 "others"
其中size和erasesize的定义在linux/include/linux/mtd下mtd.h文件中的struct mtd_info结构体定义:
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. 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;
/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
* though individual bits can be cleared),in case of NAND flash it is
* one NAND page (or half,or one-fourths of it),in case of ECC-ed NOR
* it is of ECC block size,etc. It is illegal to have writesize = 0.
* Any driver registering a struct mtd_info must ensure a writesize of
* 1 or larger.
*/
u_int32_t writesize;
u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
u_int32_t oobavail; // Available OOB bytes per block
// Kernel-only stuff starts here.
char *name;
int index;
/* ecc layout structure pointer - read only ! */
struct nand_ecclayout *ecclayout;
/* 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;
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,size_t len);
int (*read) (struct mtd_info *mtd,u_char *buf);
int (*write) (struct mtd_info *mtd,loff_t to,const u_char *buf);
int (*read_oob) (struct mtd_info *mtd,
struct mtd_oob_ops *ops);
int (*write_oob) (struct mtd_info *mtd,
struct mtd_oob_ops *ops);
/*
* Methods to access the protection register area,present in some
* flash devices. The user data is one time programmable but the
* factory data is read only.
*/
int (*get_fact_prot_info) (struct mtd_info *mtd,struct otp_info *buf,size_t len);
int (*read_fact_prot_reg) (struct mtd_info *mtd,u_char *buf);
int (*get_user_prot_info) (struct mtd_info *mtd,size_t len);
int (*read_user_prot_reg) (struct mtd_info *mtd,u_char *buf);
int (*write_user_prot_reg) (struct mtd_info *mtd,u_char *buf);
int (*lock_user_prot_reg) (struct mtd_info *mtd,size_t len);
/* kvec-based read/write methods.
NB: The 'count' parameter is the number of _vectors_,each of
which contains an (ofs,len) tuple.
*/
int (*writev) (struct mtd_info *mtd,const struct kvec *vecs,unsigned long count,size_t *retlen);
/* Sync */
void (*sync) (struct mtd_info *mtd);
/* Chip-supported device locking */
int (*lock) (struct mtd_info *mtd,loff_t ofs,size_t len);
int (*unlock) (struct mtd_info *mtd,size_t len);
/* Power Management functions */
int (*suspend) (struct mtd_info *mtd);
void (*resume) (struct mtd_info *mtd);
/* Bad block management functions */
int (*block_isbad) (struct mtd_info *mtd,loff_t ofs);
int (*block_markbad) (struct mtd_info *mtd,loff_t ofs);
struct notifier_block reboot_notifier; /* default mode before reboot */
/* ECC status information */
struct mtd_ecc_stats ecc_stats;
/* Subpage shift (NAND) */
int subpage_sft;
void *priv;
struct module *owner;
int usecount;
/* If the driver is something smart,like UBI,it may need to maintain
* its own reference counting. The below functions are only for driver.
* The driver may register its callbacks. These callbacks are not
* supposed to be called by MTD users */
int (*get_device) (struct mtd_info *mtd);
void (*put_device) (struct mtd_info *mtd);
}
通过这个结构体可知size是本mtd分区的最大字节数空间 ,erasesize是本分区的最小擦除字节数空间,读出来的信息显示这个erasesize就是一个nand block 。
0x00020000 换算为10进制就是 131072,也就是128K(1 block)。