(1)add_mtd_partitions

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\":\n", nbparts, master->name);//调用add_one_partition添加每个分区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

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;/* allocate the partition structure */slave = kzalloc(sizeof(*slave), GFP_KERNEL);if (!slave) {printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n",master->name);del_mtd_partitions(master);return NULL;}//将新建的slave加入到mtd_partitions之后list_add(&slave->list, &mtd_partitions);                               #<1>/* set up the MTD object for this partition */将master的一大部分属性赋给slaveslave->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;/* NOTE:  we don't arrange MTDs as a tree; it'd be error-prone* to have the same data be in two different partitions.*/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) {/* Round up to next erasesize */slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize;printk(KERN_NOTICE "Moving partition %d: ""0x%012llx -> 0x%012llx\n", 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\"\n", (unsigned long long)slave->offset,(unsigned long long)(slave->offset + slave->mtd.size), slave->mtd.name);/* let's do some sanity checks */if (slave->offset >= master->size) {/* let's register it anyway to preserve ordering */slave->offset = 0;slave->mtd.size = 0;printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n",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\n",part->name, master->name, (unsigned long long)slave->mtd.size);}if (master->numeraseregions > 1) {/* Deal with variable erase size stuff */int i, max = master->numeraseregions;u64 end = slave->offset + slave->mtd.size;struct mtd_erase_region_info *regions = master->eraseregions;/* Find the first erase regions which is part of this* partition. */for (i = 0; i < max && regions[i].offset <= slave->offset; i++);/* The loop searched for the region _behind_ the first one */i--;/* Pick biggest erasesize */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 {/* Single erase size */slave->mtd.erasesize = master->erasesize;}if ((slave->mtd.flags & MTD_WRITEABLE) &&mtd_mod_by_eb(slave->offset, &slave->mtd)) {/* Doesn't start on a boundary of major erase size *//* FIXME: Let it be writable if it is on a boundary of* _minor_ erase size though */slave->mtd.flags &= ~MTD_WRITEABLE;printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",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\n",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) {/* store the object pointer (caller may or may not register it*/*part->mtdp = &slave->mtd;  slave->registered = 0;} else {/* register our partition */add_mtd_device(&slave->mtd);slave->registered = 1;}return slave;
}

#<1>

Struct list_head list是一个双向链表,注意它没有数据区域

struct list_head {struct list_head *next, *prev;
};
struct mtd_part {struct mtd_info mtd;struct mtd_info *master;uint64_t offset;int index;struct list_head list;  包含了一个双向链表int registered;
};

在mtdpar.c的头部定义了:

static LIST_HEAD(mtd_partitions);     //有关list的代码在include/linux/list.h中

parse_mtd_partitions是解析FLASH中的分区信息

linux mtd - mtdpart.c相关推荐

  1. linux中mtd是什么目录,Linux mtd system

    题图:gratisography Linux mtd system MTD(Memory Technology Device),内存技术设备是Linux的存储设备中的一个子系统.其设计此系统的目的是, ...

  2. 嵌入式linux mtd,嵌入式Linux驱动设备之MTD技术详解

    原标题:嵌入式Linux驱动设备之MTD技术详解 MTD(memory technology device内存技术设备)是用于访问memory设备(ROM.flash)的Linux的子系统. MTD的 ...

  3. Linux MTD架构下的nand flash驱动详解

    转载自:http://blog.csdn.net/wang_zheng_kai/article/details/18988521 有了前面的基础(Nandflash详解:https://blog.cs ...

  4. Linux MTD子系统(1):系统层次分析

    目录 1. MTD子系统简介 2. MTD子系统的框架分层 3. MTD子系统重要的数据结构 3.1 struct mtd_info 3.2 struct mtd_part 3.3 struct mt ...

  5. Linux MTD子系统 _从模型分析到Flash驱动模板

    MTD(Memory Technology Device)即常说的Flash等使用存储芯片的存储设备,MTD子系统对应的是块设备驱动框架中的设备驱动层,可以说,MTD就是针对Flash设备设计的标准化 ...

  6. Linux MTD子系统学习(二)

    Linux MTD spi-nor驱动分析 3.1 spi-nor设备驱动框架 3.2 spi-nor设备注册 如果希望一个spi设备可以在linux系统下很好的工作,除了写驱动,还要向内核申明和注册 ...

  7. flash驱动(一):Linux MTD子系统

    转载:Linux MTD子系统 _从模型分析到Flash驱动模板 MTD(Memory Technology Device)即常说的Flash等使用存储芯片的存储设备,MTD子系统对应的是块设备驱动框 ...

  8. linux mtd 块设备,Linux系统中/dev/mtd与/dev/mtdblock的区别,即MTD字符设备和块设备的区别...

    转:http://www.crifan.com/linux_system_in__dev__mtd_and__dev__mtdblock_distinction_character_devices_a ...

  9. Linux如何获取mtd数据,【转载】上接Linux MTD下获取Nand flash各个参数的过程的详细解析【转】...

    (1)Page Size: 如图,页大小,是bit0和bit1组合起来所表示的. extid & 0x3,就是取得bit0和bit1的值,而左移1024位,是因为上面表中的单位是KB=2^10 ...

最新文章

  1. Kinect开发笔记之三Kinect开发环境配置详解
  2. 用ABP只要加人即可马上加快项目进展(二) - 分工篇 - BDD实战篇 - .NET Core里跑Specflow...
  3. 自己做的一个登录页面,纯代码!
  4. 论文浅尝 | 利用知识-意识阅读器改进的不完整知识图谱问答方法
  5. CSS3 :nth-child() ,nth-of-type(),nth-last-child() ,nth-last-of-type()
  6. Linux-目录和文件管理(二)
  7. FR切换sheet时隐藏参数面板
  8. SPSS Sobel检验(图文+数据集)【SPSS 044期】
  9. 什么是deployment 声明式升级应用
  10. visio2010安装
  11. svn的安装包和中文语言包下载
  12. .Net·使用ILSpy反编译exe或dll文件保存为项目结构
  13. NetVLAD: CNN architecture for weakly supervised place recognition 翻译
  14. 机械类和计算机类哪个累哪个难,这几个大学专业累死人还难学,但是毕业却很好就业...
  15. 论火力发电锅炉之改进
  16. 送你一个目录,一站式学习生信!众多干货,有趣有料!
  17. 液压齿轮泵的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  18. 卷积神经网络学习项目--Kaggle仙人掌识别--基于TensorFlow(未完成)
  19. 联想笔记本进入pe_lenovo怎么进入pe系统?
  20. Windows Phone开发中,减小(改变)Pivot控件PivotItem的Header(标题)字号

热门文章

  1. 9月编程排行榜新鲜出炉霸榜还得是它~
  2. 为什么转置一个512x512的矩阵,会比513x513的矩阵慢很多?
  3. 【学习笔记】正则语言的可检验性(性质检验)
  4. 使用AKO为TKG提供LoadBalancer
  5. 【怎么制作电子画册】云展网教程 | 如何设置默认模版
  6. leetcode 198打家劫舍
  7. 【报错解决】错误代码18456,SQL Server 登录失败
  8. 黑马粉丝感叹:好可呀,好想要!!【最新福利你还没领?】
  9. 快速开发小程序——案例
  10. listview下拉刷新上拉加载扩展(三)-仿最新版美团外卖