本文共 5405 字,大约阅读时间需要 18 分钟。
通过/proc虚拟文件系统读取MTD分区表:cat /proc/mtd
mtd .name = raspi, .size = 0x00400000 (4M) .erasesize = 0x00010000 (64K) .numeraseregions = 0
Creating 6 MTD partitions on "raspi": 0x00000000-0x00400000 : "ALL" 0x00000000-0x00030000 : "Bootloader" 0x00030000-0x00040000 : "Config" 0x00040000-0x00050000 : "Factory" 0x00050000-0x00360000 : "Kernel" 0x00360000-0x003b0000 : "DATA"通过这个结构体可知size是本mtd分区的最大字节数空间 ,erasesize是本分区的最小擦除字节数空间(块大小,linux的flash是以块为擦除单位的) 。
下面是别人的文章:
具体由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 name\n");
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, 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_oob) (struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops); int (*write_oob) (struct mtd_info *mtd, loff_t to, 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, loff_t from, size_t len, size_t *retlen, u_char *buf); int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, 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, loff_t to, 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, loff_t ofs, 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); }转载地址:http://skpgi.baihongyu.com/