Was ist Linux MTD?

青灯夜游
青灯夜游Original
2022-05-11 17:22:484692Durchsuche

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.

Was ist Linux MTD?

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:

Was ist Linux MTD?

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.

Was ist Linux MTD?

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.ubi

Die 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"

Dies ist die intuitivste Darstellungsform, die uns MTD bietet Die verschiedenen Partitionen im Speicher sind die Partitionsstruktur des Moduls, aber wie werden diese Partitionen implementiert? Es gibt mehrere Möglichkeiten, die Partitionstabelle zu implementieren, die im Folgenden erläutert werden:

Hinweis: Voraussetzung für die Implementierung der Partitionstabelle ist, dass der MTD-Gerätetreiber erfolgreich war, andernfalls gibt es auch dann keine Partition, über die man sprechen könnte Der Treiber ist nicht erfolgreich.

1. Hinzufügen zum Kernel

Das Hinzufügen zum Kernel sollte in jedem Treiber-Transplantationsbuch zu finden sein Folgendes. Informationen, ich werde es hier nicht zu sehr beschreibenrrreeDa unser MTD-Treiber fertig ist, wird die Sondenschnittstellenfunktion im Treiber aufgerufen add_mtd_partitions(s3c_mtd, setzt in der Probe-Funktion ->partitions, sets->nr_partitions);Partitionstabellen hinzufügen.

2. U-Boot-Parameterübertragung

add_mtd_partitions(s3c_mtd, sets->partitions, sets->nr_partitions);实现分区表的添加。

2.u-boot传参

在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)

Unter U-Boot können Sie mtdparts-Informationen zu Bootargs hinzufügen. Nach dem Start von U-Boot werden die Informationen in Bootargs an den Kernel übertragen und der Kernel analysiert sie es beginnt. Der mtdparts-Teil von bootargs, hier ist ein Beispiel:

mtdparts=nand.0:1M(Bootloader)ro,31M(Kernel)ro,16M(User),96M(File System), 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. 🎜

在内核中添加分区表的时候,我们是在平台设备里面加入mtd_partition信息。这边通过u-boot传参则取消平台设备里面的partition信息,那我们需要怎样解析u-boot的传过来的mtdparts呢。

u-boot传参过来后,cmdlinepart.c中会将这些参数解析好,存在里面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参数的解析。

3.dts传参

在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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn