Unter Linux bezieht sich mtd auf „Speichertechnologiegerät“ und ist ein Subsystem im Speichergerät. Das MTD-System wurde in Linux eingeführt, um eine einheitliche Schnittstelle für NOR FLASH- und NAND FLASH-Geräte bereitzustellen. MTD-Geräte können normalerweise in vier Schichten unterteilt werden: Geräteknoten, MTD-Geräteschicht, MTD-Originalgeräteschicht und Hardwaretreiberschicht.
Die Betriebsumgebung dieses Tutorials: Linux5.9.8-System, Dell G3-Computer.
Was ist Linux MTD?
MTD steht für „Memory Technology Device“, was „Speichertechnologiegerät“ bedeutet und ein Subsystem von Linux-Speichergeräten ist.
Im Linux-Kernel wird die MTD-Schicht eingeführt, um eine einheitliche Schnittstelle für NOR FLASH- und NAND FLASH-Geräte bereitzustellen. MTD isoliert das Dateisystem vom zugrunde liegenden FLASH-Speicher.
Der Zweck des Entwurfs dieses MTD-Systems besteht darin, eine Abstraktionsschicht und eine Schnittstelle für Speichergeräte bereitzustellen, sodass Hardwaretreiber-Designer nur die einfachste Lese-/Schreib-/Löschfunktion für zugrunde liegende Hardwaregeräte bereitstellen müssen Sie müssen sich nicht darum kümmern, wie die Daten den Benutzern der oberen Schicht dargestellt werden, da das MTD-Speichergeräte-Subsystem dies für Sie erledigt.
MTD-Framework
Das MTD-Gerät von Linux befindet sich unter drivers/mtd/.
Der Inhalt unter der MTD-Datei lautet wie folgt:
MTD-Geräte können normalerweise in vier Schichten unterteilt werden
Von oben nach unten: Geräteknoten, MTD-Geräteschicht, MTD-Originalgeräteschicht und Hardwaretreiberschicht.
1.cmdlinepart.c
Wenn die MTD-Partitionstabelle von U-Boot über den CMD-Parameter an Linux übertragen wird, muss der Linux-Kernel mtdparts nicht registrieren und hinzufügen, sondern nur festlegen Befehlszeilenpartitionsoption in MTD. Schalten Sie sie einfach ein. Um diese Methode verwenden zu können, muss U-Boot MTD unterstützen und die übertragenen MTD-Partitionsparameter müssen den Formatanforderungen entsprechen.
2.Geräteordner
Wenn wir ein SPI-Flash-Gerät haben und mtd zur Verwaltung verwenden möchten, legen wir es normalerweise im Geräteordner ab, z. B. m25p80.c im Geräteordner ist ein typisches Beispiel für SPI-Flash Gerät.
3.chips/nand/onenand-Ordner
nand-Flash-Treiber befindet sich im NAND-Ordner;
onenand-Flash-Treiber befindet sich im Onenand-Ordner;
Nor-Flash-Treiber ist ziemlich kompliziert und befindet sich im Folgenden Dateien:
Chips: CFI/JEDEC-Schnittstellen-Universaltreiber
Geräte: noch Flash-unterliegender Treiber (SPI-Flash)
Karten: noch Flash-Mapping-Beziehungsbezogene Funktionen
4. Kerndatei
mtdchar.c: MTD-Zeichen Geräteschnittstelle Relevante Implementierung, Gerätenummer 31;
mtdblock.c: MTD-Blockgeräteschnittstellenbezogene Implementierung, Gerätenummer 90; Durchführung.
5.ubiDie Unterstützungsschicht von ubifs-Dateien muss unter Gerätetreiber -> UBI-Unsortiertes Blockbild aktiviert werden. Wählen Sie UBIFS-Dateisystemunterstützung unter Dateisysteme -> Verschiedene Dateisysteme.
Implementierung der MTD-Partitionstabelle
Während des Startvorgangs können Sie in der Konsole häufig Informationen wie die folgenden sehen:
0x000000000000-0x000000100000 : "Bootloade" 0x000000100000-0x000002000000 : "Kernel" 0x000002000000-0x000003000000 : "User" 0x000003000000-0x000008000000 : "File System"
1. Hinzufügen zum Kernel
add_mtd_partitions(s3c_mtd, sets->partitions, sets->nr_partitions);
实现分区表的添加。
在u-boot下可以通过添加mtdparts信息到bootargs中,u-boot启动后会将bootargs中的信息传送给kernel,,kernel在启动的时候会解析bootargs中mtdparts的部分,这边举个例子:
mtdparts=nand.0:1M(Bootloader)ro,31M(Kernel)ro,16M(User),96M(File System)
mtdparts=nand.0:1M(Bootloader)ro,31M(Kernel)ro,16M(User),96M(File System)</code >, Weitere Informationen zum spezifischeren mtdparts-Format finden Sie in den entsprechenden Informationen. 🎜🎜Damit der Kernel mtdparts-Informationen analysieren kann, müssen wir die Option „Gerätetreiber –> Memory Technology Device (MTD)-Unterstützung –>Befehlszeilen-Partitionstabellen-Analyseoption im Kernel aktivieren, wie oben erwähnt. 🎜<p>在内核中添加分区表的时候,我们是在平台设备里面加入mtd_partition信息。这边通过u-boot传参则取消平台设备里面的partition信息,那我们需要怎样解析u-boot的传过来的mtdparts呢。</p><p>u-boot传参过来后,cmdlinepart.c中会将这些参数解析好,存在里面<code>LIST_HEAD(part_parsers)
链表里面,然后我们在驱动的probe函数中,通过调用mtd_device_parse_register(mtd, probe_types,&ppdata, NULL, 0);
函数。mtd_device_parse_register()
函数位于drivers/mtd/mtdcore.c 中,内容如下:
int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, struct mtd_part_parser_data *parser_data, const struct mtd_partition *parts, int nr_parts) { int err; struct mtd_partition *real_parts; err = parse_mtd_partitions(mtd, types, &real_parts, parser_data); if (err <= 0 && nr_parts && parts) { real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, GFP_KERNEL); if (!real_parts) err = -ENOMEM; else err = nr_parts; } if (err > 0) { err = add_mtd_partitions(mtd, real_parts, err); kfree(real_parts); } else if (err == 0) { err = add_mtd_device(mtd); if (err == 1) err = -ENODEV; } return err; }
可以看到该函数会先执行parse_mtd_partitions(mtd, types, &real_parts, parser_data);
函数,后面还是通过add_mtd_partitions()
函数来实现分区表的添加。
parse_mtd_partitions()
函数位于drivers/mtd/mtdpart.c中,内容如下:
int parse_mtd_partitions(struct mtd_info *master, const char *const *types, struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct mtd_part_parser *parser; int ret = 0; if (!types) types = default_mtd_part_types; for ( ; ret <= 0 && *types; types++) { parser = get_partition_parser(*types); if (!parser && !request_module("%s", *types)) parser = get_partition_parser(*types); if (!parser) continue; ret = (*parser->parse_fn)(master, pparts, data); put_partition_parser(parser); if (ret > 0) { printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", ret, parser->name, master->name); break; } } return ret; }
进入parse_mtd_partitions()
函数会先判断types的类型,如果为空则给默认值,types的类型一般就两种,如下:
static const char * const default_mtd_part_types[] = { "cmdlinepart", "ofpart", NULL };
第一个"cmdlinepart"即u-boot传参的方式,第二个"ofpart"即下面要讲到的使用dts传参的方式,判断完类型后,就通过get_partition_parser
去解析part_parsers
链表里面的数据,这样就完成u-boot参数的解析。
在Linux3.14以后的linux版本中,加入一个新的知识DTS(Device tree),dts其实就是为了解决ARM Linux中的冗余代码,在Linux2.6版本的arch/arm/plat.xxx和arch/arm/mach.xxx中充斥着大量的垃圾代码,采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码,关于dts可以自行查阅资料。
dts传参的原理其实和u-boot一样,区别在于:u-boot的时候是通过cmdlinepart.c文件实现分区信息写入LIST_HEAD(part_parsers)
链表,dts则是用过ofpart.c文件实现分区信息写入LIST_HEAD(part_parsers)
链表,所以同样要把ofpart.c文件的宏打开,在调用mtd_device_parse_register(mtd, probe_types,&ppdata, NULL, 0);
函数的时候types要设置成ofpart。
如果去对比Linux2.6版本和Linux3.14版本,会发现drivers/mtd/ofpart.c和drivers/mtd/mtdpart.c文件有所不同,Linux3.8版本里面多了Device tree这一部分的内容,感兴趣的可以自己深究下。
这边举个dts的例子:
pinctrl-0 = <&s3c_nand_flash>; ranges = <0 0 0x000000000000 0x000008000000>; /* CS0: NAND */ nand@0,0 { partition@1 { label = "Bootloader"; reg = <0x000000000000 0x000000100000>; }; partition@2 { label = "Kernel"; reg = <0x000000100000 0x000002000000>; }; partition@3 { label = "User"; reg = <0x000002000000 0x000003000000>; }; partition@4 { label = "File System"; reg = <0x000003000000 0x000008000000>; }; };
Linux mtd system的分析就到这边,有感悟时会持续会更新。
相关推荐:《Linux视频教程》
Das obige ist der detaillierte Inhalt vonWas ist Linux MTD?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!