Chinaunix首页 | 论坛 | 博客
  • 博客访问: 80913
  • 博文数量: 14
  • 博客积分: 386
  • 博客等级: 一等列兵
  • 技术积分: 208
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-06 10:48
文章分类

全部博文(14)

文章存档

2011年(6)

2010年(8)

我的朋友

分类: LINUX

2011-01-05 19:23:09

wiki中关于mtd的说明
Memory technology devices (MTD) are a new type of device file in for interacting with . The MTD subsystem was created to provide an between the hardware-specific device drivers and higher-level applications.

Hardware drivers need to know nothing about the storage formats used, such as FTL, FFS2, etc., but will only need to provide simple routines for read, write and erase

It makes it possible to use the same API when working with different flash types and technologies, e.g. NAND, OneNAND, NOR, AG-AND, ECC'd NOR, etc
Flash doesn't match the desciption of either block or character devices.
mtd只是针对于flash memory的,而且提供了很好的抽象层次
在linux 系統中提供了MTD (memory technolog device)來建立flash針對linux 統一,抽象的接口,
好處有以下兩點:
1.我們要做Mtd設備的驅動模塊,所要做的事情就是去實現公共接口函數的實際內容.再設級模塊是不用理會字符還是塊設備的驅動設計標準,因為所有這些接口的機制,mtd已經為我們做好了
2.上层应用只需要访问mtd抽象层提供的字符设备方式或者块设备方式来访问mtd设备,因此具体驱动对于上层应用来说是具有独立性的,即使底层驱动修改了,上层拥有也不需要改动。并且由于mtd抽象层,上层应用就可以避免直接对具体硬件操作,而是对mtd操作,这样的话这些应用就不是建立在某个具体的设备上,更好的实现了通用性和兼容性
2.

有了MTD 之後,linux系統中的flash可分為4層:
硬件驅動層,MTD原始設備層,MTD設備層還有設備節點.

CFI:Common Flash Interface 通用的Falsh接口
OOB:out of band 某些内存技术支持out-of-band 数据用于纠错

一个mtd 原始设备可以通过mtd_part分隔成为数个mtd 原始的设备注册进mtd_table, mtd_table 中的每个mtd原始设备都可以被注册成一个mtd设备
mtd_info用於描述MTD的設備,定義了關於mtd設備的數據和操作函數,每個分區也被認為一個mtd_info.而mtd_info的指針北存放在mtd_table的數組里.

  1. 101struct mtd_info {
  2.  102 u_char type;
  3.  103 uint32_t flags;
  4.  104 uint64_t size; // Total size of the MTD
  5.  105
  6.  106 /* "Major" erase size for the device. Nave users may take this
  7.  107 * to be the only erase size available, or may use the more detailed
  8.  108 * information below if they desire
  9.  109 */
  10.  110 uint32_t erasesize;
  11.  111 /* Minimal writable flash unit size. In case of NOR flash it is 1 (even
  12.  112 * though individual bits can be cleared), in case of NAND flash it is
  13.  113 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
  14.  114 * it is of ECC block size, etc. It is illegal to have writesize = 0.
  15.  115 * Any driver registering a struct mtd_info must ensure a writesize of
  16.  116 * 1 or larger.
  17.  117 */
  18.  118 uint32_t writesize;
  19.  119
  20.  120 uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
  21.  121 uint32_t oobavail; // Available OOB bytes per block
  22.  122
  23.  123 /*
  24.  124 * If erasesize is a power of 2 then the shift is stored in
  25.  125 * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.
  26.  126 */
  27.  127 unsigned int erasesize_shift;
  28.  128 unsigned int writesize_shift;
  29.  129 /* Masks based on erasesize_shift and writesize_shift */
  30.  130 unsigned int erasesize_mask;
  31.  131 unsigned int writesize_mask;
  32.  132
  33.  133 // Kernel-only stuff starts here.
  34.  134 const char *name;
  35.  135 int index;
  36.  136
  37.  137 /* ecc layout structure pointer - read only ! */
  38.  138 struct nand_ecclayout *ecclayout;
  39.  139
  40.  140 /* Data for variable erase regions. If numeraseregions is zero,
  41.  141 * it means that the whole device has erasesize as given above.
  42.  142 */
  43.  143 int numeraseregions;
  44.  144 struct mtd_erase_region_info *eraseregions;
  45.  145
  46.  146 /*
  47.  147 * Erase is an asynchronous operation. Device drivers are supposed
  48.  148 * to call instr->callback() whenever the operation completes, even
  49.  149 * if it completes with a failure.
  50.  150 * Callers are supposed to pass a callback function and wait for it
  51.  151 * to be called before writing to the block.
  52.  152 */
  53.  153 int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
  54.  154
  55.  155 /* This stuff for eXecute-In-Place */
  56.  156 /* phys is optional and may be set to NULL */
  57.  157 int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
  58.  158 size_t *retlen, void **virt, resource_size_t *phys);
  59.  159
  60.  160 /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
  61.  161 void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
  62.  162
  63.  163 /* Allow NOMMU mmap() to directly map the device (if not NULL)
  64.  164 * - return the address to which the offset maps
  65.  165 * - return -ENOSYS to indicate refusal to do the mapping
  66.  166 */
  67.  167 unsigned long (*get_unmapped_area) (struct mtd_info *mtd,
  68.  168 unsigned long len,
  69.  169 unsigned long offset,
  70.  170 unsigned long flags);
  71.  171
  72.  172 /* Backing device capabilities for this device
  73.  173 * - provides mmap capabilities
  74.  174 */
  75.  175 struct backing_dev_info *backing_dev_info;
  76.  176
  77.  177
  78.  178 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
  79.  179 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
  80.  180
  81.  181 /* In blackbox flight recorder like scenarios we want to make successful
  82.  182 writes in interrupt context. panic_write() is only intended to be
  83.  183 called when its known the kernel is about to panic and we need the
  84.  184 write to succeed. Since the kernel is not going to be running for much
  85.  185 longer, this function can break locks and delay to ensure the write
  86.  186 succeeds (but not sleep). */
  87.  187
  88.  188 int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
  89.  189
  90.  190 int (*read_oob) (struct mtd_info *mtd, loff_t from,
  91.  191 struct mtd_oob_ops *ops);
  92.  192 int (*write_oob) (struct mtd_info *mtd, loff_t to,
  93.  193 struct mtd_oob_ops *ops);
  94.  194
  95.  195 /*
  96.  196 * Methods to access the protection register area, present in some
  97.  197 * flash devices. The user data is one time programmable but the
  98.  198 * factory data is read only.
  99.  199 */
  100.  200 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
  101.  201 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
  102.  202 int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
  103.  203 int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
  104.  204 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
  105.  205 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
  106.  206
  107.  207 /* kvec-based read/write methods.
  108.  208 NB: The 'count' parameter is the number of _vectors_, each of
  109.  209 which contains an (ofs, len) tuple.
  110.  210 */
  111.  211 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,size_t *retlen);
  112.  212
  113.  213 /* Sync */
  114.  214 void (*sync) (struct mtd_info *mtd);
  115.  215
  116.  216 /* Chip-supported device locking */
  117.  217 int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
  118.  218 int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
  119.  219
  120.  220 /* Power Management functions */
  121.  221 int (*suspend) (struct mtd_info *mtd);
  122.  222 void (*resume) (struct mtd_info *mtd);
  123.  223
  124.  224 /* Bad block management functions */
  125.  225 int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
  126.  226 int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
  127.  227
  128.  228 struct notifier_block reboot_notifier; /* default mode before reboot */
  129.  229
  130.  230 /* ECC status information */
  131.  231 struct mtd_ecc_stats ecc_stats;
  132.  232 /* Subpage shift (NAND) */
  133.  233 int subpage_sft;
  134.  234
  135.  235 void *priv;
  136.  236
  137.  237 struct module *owner;
  138.  238 struct device dev;
  139.  239 int usecount;
  140.  240
  141.  241 /* If the driver is something smart, like UBI, it may need to maintain
  142.  242 * its own reference counting. The below functions are only for driver.
  143.  243 * The driver may register its callbacks. These callbacks are not
  144.  244 * supposed to be called by MTD users */
  145.  245 int (*get_device) (struct mtd_info *mtd);
  146.  246 void (*put_device) (struct mtd_info *mtd);
  147.  247};
  148.  248
flash驅動註冊和註銷mtd設備函數

  1. int add_mtd_device(struct mtd_info *mtd);
  2. int del_mtd_device (struct *);
  3. /////

mtd_part結構體用於表示分區,是已經分好了的分區,一个MTD原始

设备可以通过mtd_part分割成数个MTD原始设备注册进

mtd_table,mtd_table中的 每个MTD原始设备都可以被注册成一

个MTD设备,其中字符设备的主设备号为90,次设备号为0、2、

4、6…(奇数次设备号为只读设备),块设备的主设 备号为31,次

设备号为0、1、2、3


  1. 26struct mtd_part {
  2.   27 struct mtd_info mtd; /* 分區的信息*/
  3.   28 struct mtd_info *master; /* 該分區的主分區*/
  4.   29 uint64_t offset; /* 該分區的偏移地址*/
  5.   30 struct list_head list;
  6.   31};

  7. ///

上面是2.6.35的了,已經與之前的結構體的內容不同.

mtd_partiton會在mtd原始設備層調用add_mtd_partions()是傳遞分區信息
  1. 15/*
  2.   16 * Partition definition structure:
  3.   17 *
  4.   18 * An array of struct partition is passed along with a MTD object to
  5.   19 * add_mtd_partitions() to create them.
  6.   20 *
  7.   21 * For each partition, these fields are available:
  8.   22 * name: string that will be used to label the partition's MTD device.
  9.   23 * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition
  10.   24 * will extend to the end of the master MTD device.
  11.   25 * offset: absolute starting position within the master MTD device; if
  12.   26 * defined as MTDPART_OFS_APPEND, the partition will start where the
  13.   27 * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
  14.   28 * mask_flags: contains flags that have to be masked (removed) from the
  15.   29 * master MTD flag set for the corresponding MTD partition.
  16.   30 * For example, to force a read-only partition, simply adding
  17.   31 * MTD_WRITEABLE to the mask_flags will do the trick.
  18.   32 *
  19.   33 * Note: writeable partitions require their size and offset be
  20.   34 * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
  21.   35 */
  22.   36
  23.   37struct mtd_partition {
  24.   38 char *name; /* identifier string */
  25.   39 uint64_t size; /* partition size */
  26.   40 uint64_t offset; /* offset within the master MTD space */
  27.   41 uint32_t mask_flags; /* master MTD flags to mask out for this partition */
  28.   42 struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/
  29.   43};
mtdcore.c  主要实现了MTD原始设备层的数据结构mtd_table 和对其的操作函数
阅读(2513) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~