Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1151074
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2279
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(241)

文章存档

2023年(8)

2022年(2)

2021年(3)

2020年(30)

2019年(11)

2018年(27)

2017年(54)

2016年(83)

2015年(23)

我的朋友

分类: LINUX

2016-09-17 15:30:27

//////////////////////include/linux/mtd/partitions.h
/*
 * Partition definition structure:
 *
 * An array of struct partition is passed along with a MTD object to
 * add_mtd_partitions() to create them.
 *
 * For each partition, these fields are available:
 * name: string that will be used to label the partition's MTD device.
 * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition
 *     will extend to the end of the master MTD device.
 * offset: absolute starting position within the master MTD device; if
 *     defined as MTDPART_OFS_APPEND, the partition will start where the
 *     previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
 * mask_flags: contains flags that have to be masked (removed) from the
 *     master MTD flag set for the corresponding MTD partition.
 *     For example, to force a read-only partition, simply adding
 *     MTD_WRITEABLE to the mask_flags will do the trick.
 *
 * Note: writeable partitions require their size and offset be
 * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
 */
//描述MTD分区
struct mtd_partition {
 /* 分区名,如TQ2440_Board_uboot、TQ2440_Board_kernel、TQ2440_Board_yaffs2 */ 
    char *name;            /* identifier string */ 识别 字符串
    u_int32_t size;            /* partition size */ 分区 大小
    u_int32_t offset;        /* offset within the master MTD space */ /* 分区偏移值 */ 
    u_int32_t mask_flags;        /* master MTD flags to mask out for this partition *//* 掩码标识,不重要 */
    struct nand_ecclayout *ecclayout;    /* out of band layout for this partition (NAND only)*//* OOB布局 */
    struct mtd_info **mtdp;        /* pointer to store the MTD object */ 
};

///////////////include/mtd/mtd-abi.h
/*
 * ECC layout control structure. Exported to userspace for
 * diagnosis and to allow creation of raw images
 */
struct nand_ecclayout {
    uint32_t eccbytes; /* ECC字节数 */ 
    uint32_t eccpos[64];/* ECC校验码在OOB区域存放位置 */
    uint32_t oobavail;
    /* 除了ECC校验码之外可用的OOB字节数 */ 
    struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
};
/////////////////////////////////////////////////include/linux/mtd/mtd.h
Linux内核使用mtd_info结构体表示MTD原始设备,这其中定义了大量关于MTD的数据和操作函数(后面将会看到),所有的mtd_info结构体存放在mtd_table结构体数据里
struct mtd_info {
    u_char type;/* MTD类型,包括MTD_NORFLASH,MTD_NANDFLASH等(可参考mtd-abi.h) */ 
    u_int32_t flags; /* MTD属性标志,MTD_WRITEABLE,MTD_NO_ERASE等(可参考mtd-abi.h) */ 
    u_int32_t size;     // Total size of the MTD/* mtd设备的大小 */ 

    /* "Major" erase size for the device. Na茂ve 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;/* MTD设备的擦除单元大小,对于NandFlash来说就是Block的大小 */ 
    /* 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.
     */* 写大小, 对于norFlash是字节,对nandFlash为一页 */ 
    u_int32_t writesize;

    u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)/* OOB字节数 */ 
    u_int32_t oobavail;  // Available OOB bytes per block/* 可用的OOB字节数 */

    // Kernel-only stuff starts here.
    const 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;/*/* 通常为1 */
    struct mtd_erase_region_info *eraseregions;/* 可变擦除区域 */ 

    /*
     * Erase is an asynchronous operation.  Device drivers are supposed
     * to call instr->callback() whenever the operation completes, even
     * if it completes with a failure.
     * Callers are supposed to pass a callback function and wait for it
     * to be called before writing to the block.
     *//* 擦除函数 */ 
    int (*erase) (struct mtd_info *mtd, struct erase_info *instr);

    /* This stuff for eXecute-In-Place */
    /* phys is optional and may be set to NULL */
    int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
            size_t *retlen, void **virt, resource_size_t *phys);

    /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
    void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);

 /* 读写flash函数 */ 
    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);

    /* In blackbox flight recorder like scenarios we want to make successful
       writes in interrupt context. panic_write() is only intended to be
       called when its known the kernel is about to panic and we need the
       write to succeed. Since the kernel is not going to be running for much
       longer, this function can break locks and delay to ensure the write
       succeeds (but not sleep). */

    int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
  /* 带oob读写Flash函数 */
    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; /* 设备私有数据指针,对于NandFlash来说指nand_chip结构体 */

    struct module *owner;/* 一般设置为THIS_MODULE */ 
    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);
};
////////////////drivers/mtd/mtdcore.c
所有的mtd_info结构体存放在mtd_table结构体数据里
struct mtd_info *mtd_table[MAX_MTD_DEVICES];
//////////////////////////////drivers/mtd/mtdpart.c
Linux内核使用mtd_part结构体表示分区,其中mtd_info结构体成员用于描述该分区,大部分成员由其主分区mtd_part->master决定,各种函数也指向主分区的相应函数。
/* Our partition node structure */
struct mtd_part {
    struct mtd_info mtd;
/* 分区信息, 大部分由master决定 */ 
    struct mtd_info *master;/* 分区的主分区 */
    u_int32_t offset;/* 分区的偏移地址 */
    int index; /* 分区号 (Linux3.0后不存在该字段) */
    struct list_head list;/* 将mtd_part链成一个链表mtd_partitons */
    int registered;
};
阅读(1237) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~