转载请注明来自:http://blog.csdn.net/xgbing
(1)add_mtd_partitions
[cpp]
view plain
copy
- int add_mtd_partitions(struct mtd_info *master, 在flash驱动中已经初始化
- const struct mtd_partition *parts,
- int nbparts)
- {
- struct mtd_part *slave;
- uint64_t cur_offset = 0;
- int i;
-
- printk(KERN_NOTICE "Creating %d MTD partitions on "%s":
", nbparts, master->name);
-
-
- for (i = 0; i < nbparts; i++) {
- slave = add_one_partition(master, parts + i, i, cur_offset);
- if (!slave)
- return -ENOMEM;
- cur_offset = slave->offset + slave->mtd.size;
- }
-
- return 0;
- }
(2)add_one_partition
[cpp]
view plain
copy
- static struct mtd_part *add_one_partition(struct mtd_info *master, 从mtd外部FLASH驱动已经初始化,是一个输入参数。
- const struct mtd_partition *part, int partno,
- uint64_t cur_offset)
- {
- struct mtd_part *slave;
-
-
- slave = kzalloc(sizeof(*slave), GFP_KERNEL);
- if (!slave) {
- printk(KERN_ERR"memory allocation error while creating partitions for "%s"
",
- master->name);
- del_mtd_partitions(master);
- return NULL;
- }
-
-
-
- list_add(&slave->list, &mtd_partitions); #<1>
-
- 将master的一大部分属性赋给slave
- slave->mtd.type = master->type;
- slave->mtd.flags = master->flags & ~part->mask_flags;
- slave->mtd.size = part->size;
- slave->mtd.writesize = master->writesize;
- slave->mtd.oobsize = master->oobsize;
- slave->mtd.oobavail = master->oobavail;
- slave->mtd.subpage_sft = master->subpage_sft;
-
- slave->mtd.name = part->name;
- slave->mtd.owner = master->owner;
- slave->mtd.backing_dev_info = master->backing_dev_info;
-
-
-
-
- slave->mtd.dev.parent = master->dev.parent;
-
- slave->mtd.read = part_read;
- slave->mtd.write = part_write;
-
- if (master->panic_write)
- slave->mtd.panic_write = part_panic_write;
-
- if (master->point && master->unpoint) {
- slave->mtd.point = part_point;
- slave->mtd.unpoint = part_unpoint;
- }
-
- if (master->get_unmapped_area)
- slave->mtd.get_unmapped_area = part_get_unmapped_area;
- if (master->read_oob)
- slave->mtd.read_oob = part_read_oob;
- if (master->write_oob)
- slave->mtd.write_oob = part_write_oob;
- if (master->read_user_prot_reg)
- slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
- if (master->read_fact_prot_reg)
- slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
- if (master->write_user_prot_reg)
- slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
- if (master->lock_user_prot_reg)
- slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
- if (master->get_user_prot_info)
- slave->mtd.get_user_prot_info = part_get_user_prot_info;
- if (master->get_fact_prot_info)
- slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
- if (master->sync)
- slave->mtd.sync = part_sync;
- if (!partno && master->suspend && master->resume) {
- slave->mtd.suspend = part_suspend;
- slave->mtd.resume = part_resume;
- }
- if (master->writev)
- slave->mtd.writev = part_writev;
- if (master->lock)
- slave->mtd.lock = part_lock;
- if (master->unlock)
- slave->mtd.unlock = part_unlock;
- if (master->block_isbad)
- slave->mtd.block_isbad = part_block_isbad;
- if (master->block_markbad)
- slave->mtd.block_markbad = part_block_markbad;
- slave->mtd.erase = part_erase;
- slave->master = master;
- slave->offset = part->offset;
- slave->index = partno;
-
- if (slave->offset == MTDPART_OFS_APPEND)
- slave->offset = cur_offset;
- if (slave->offset == MTDPART_OFS_NXTBLK) {
- slave->offset = cur_offset;
- if (mtd_mod_by_eb(cur_offset, master) != 0) {
-
- slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize;
- printk(KERN_NOTICE "Moving partition %d: "
- "0x%012llx -> 0x%012llx
", partno,
- (unsigned long long)cur_offset, (unsigned long long)slave->offset);
- }
- }
- if (slave->mtd.size == MTDPART_SIZ_FULL)
- slave->mtd.size = master->size - slave->offset;
-
- printk(KERN_NOTICE "0x%012llx-0x%012llx : "%s"
", (unsigned long long)slave->offset,
- (unsigned long long)(slave->offset + slave->mtd.size), slave->mtd.name);
-
-
- if (slave->offset >= master->size) {
-
- slave->offset = 0;
- slave->mtd.size = 0;
- printk(KERN_ERR"mtd: partition "%s" is out of reach -- disabled
",
- part->name);
- goto out_register;
- }
- if (slave->offset + slave->mtd.size > master->size) {
- slave->mtd.size = master->size - slave->offset;
- printk(KERN_WARNING"mtd: partition "%s" extends beyond the end of device "%s" -- size truncated to %#llx
",
- part->name, master->name, (unsigned long long)slave->mtd.size);
- }
- if (master->numeraseregions > 1) {
-
- int i, max = master->numeraseregions;
- u64 end = slave->offset + slave->mtd.size;
- struct mtd_erase_region_info *regions = master->eraseregions;
-
-
-
- for (i = 0; i < max && regions[i].offset <= slave->offset; i++)
- ;
-
- i--;
-
-
- for (; i < max && regions[i].offset < end; i++) {
- if (slave->mtd.erasesize < regions[i].erasesize) {
- slave->mtd.erasesize = regions[i].erasesize;
- }
- }
- BUG_ON(slave->mtd.erasesize == 0);
- } else {
-
- slave->mtd.erasesize = master->erasesize;
- }
-
- if ((slave->mtd.flags & MTD_WRITEABLE) &&
- mtd_mod_by_eb(slave->offset, &slave->mtd)) {
-
-
-
- slave->mtd.flags &= ~MTD_WRITEABLE;
- printk(KERN_WARNING"mtd: partition "%s" doesn't start on an erase block boundary -- force read-only
",
- part->name);
- }
- if ((slave->mtd.flags & MTD_WRITEABLE) &&
- mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) {
- slave->mtd.flags &= ~MTD_WRITEABLE;
- printk(KERN_WARNING"mtd: partition "%s" doesn't end on an erase block -- force read-only
",
- part->name);
- }
-
- slave->mtd.ecclayout = master->ecclayout;
- if (master->block_isbad) {
- uint64_t offs = 0;
-
- while (offs < slave->mtd.size) {
- if (master->block_isbad(master,
- offs + slave->offset))
- slave->mtd.ecc_stats.badblocks++;
- offs += slave->mtd.erasesize;
- }
- }
-
- out_register:
- if (part->mtdp) {
-
- *part->mtdp = &slave->mtd;
- slave->registered = 0;
- } else {
-
- add_mtd_device(&slave->mtd);
- slave->registered = 1;
- }
- return slave;
- }
#<1>
Struct list_head list是一个双向链表,注意它没有数据区域
[cpp]
view plain
copy
- struct list_head {
- struct list_head *next, *prev;
- };
[cpp]
view plain
copy
- struct mtd_part {
- struct mtd_info mtd;
- struct mtd_info *master;
- uint64_t offset;
- int index;
- struct list_head list; 包含了一个双向链表
- int registered;
- };
在mtdpar.c的头部定义了:
[cpp]
view plain
copy
- static LIST_HEAD(mtd_partitions);
parse_mtd_partitions是解析FLASH中的分区信息