真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

linuxmtd的概念是什么

本篇內(nèi)容主要講解“l(fā)inux mtd的概念是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“l(fā)inux mtd的概念是什么”吧!

天水ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!

在linux中,mtd是指“內(nèi)存技術(shù)設(shè)備”,是存儲(chǔ)設(shè)備中的一個(gè)子系統(tǒng)。linux引入MTD系統(tǒng)是為了給NOR FLASH和NAND FLASH設(shè)備提供統(tǒng)一接口。MTD設(shè)備通??煞譃樗膶樱涸O(shè)備節(jié)點(diǎn)、MTD設(shè)備層、MTD原始設(shè)備層、硬件驅(qū)動(dòng)層。

本教程操作環(huán)境:linux5.9.8系統(tǒng)、Dell G3電腦。

Linux MTD是什么?

MTD全稱“Memory Technology Device”,意思為“內(nèi)存技術(shù)設(shè)備”,是Linux的存儲(chǔ)設(shè)備中的一個(gè)子系統(tǒng)。

在Linux內(nèi)核中,引入MTD層為NOR FLASH和NAND FLASH設(shè)備提供統(tǒng)一接口。MTD將文件系統(tǒng)與底層FLASH存儲(chǔ)器進(jìn)行了隔離。

設(shè)計(jì)此MTD系統(tǒng)的目的是,對(duì)于內(nèi)存類的設(shè)備,提供一個(gè)抽象層,一個(gè)接口,使得對(duì)于硬件驅(qū)動(dòng)設(shè)計(jì)者來說,只需要去提供最簡單的底層硬件設(shè)備的讀/寫/擦除函數(shù)就可以了,數(shù)據(jù)對(duì)于上層使用者來說是如何表示的,可以不關(guān)心,因?yàn)镸TD存儲(chǔ)設(shè)備子系統(tǒng)都幫你做好了。

MTD框架

Linux的MTD設(shè)備位于drivers/mtd/下面。

MTD文件下的內(nèi)容如下:

linux mtd的概念是什么

MTD設(shè)備通??煞譃樗膶?/p>

上到下依次是:設(shè)備節(jié)點(diǎn)、MTD設(shè)備層、MTD原始設(shè)備層和硬件驅(qū)動(dòng)層。

linux mtd的概念是什么

1.cmdlinepart.c

當(dāng)mtd分區(qū)表由u-boot通過cmd參數(shù)傳輸給linux時(shí),linux內(nèi)核可以不用對(duì)mtdparts進(jìn)行注冊添加,只需要將MTD中的command line partition選項(xiàng)開啟即可。使用這種的方法u-boot下需要對(duì)MTD進(jìn)行支持,且所傳輸?shù)膍td分區(qū)參數(shù)要符合格式要求。

2.devices文件夾

當(dāng)我們有一個(gè)spi flash設(shè)備時(shí)且要使用mtd進(jìn)行管理,我們一般會(huì)將其放在devices文件夾下,如devices文件夾下面的m25p80.c就是一個(gè)典型的spi flash設(shè)備。

3.chips/nand/onenand文件夾

nand flash 驅(qū)動(dòng)在nand文件夾下;

onenand flash 驅(qū)動(dòng)在onenand文件夾下;

nor flash比較雜,下面幾個(gè)文件下都會(huì)有:

chips:cfi/jedec接口通用驅(qū)動(dòng)

devices:nor flash底層驅(qū)動(dòng)(spi flash)

maps:nor flash映射關(guān)系相關(guān)函數(shù)

4.核心文件

mtdchar.c : MTD字符設(shè)備接口相關(guān)實(shí)現(xiàn),設(shè)備號(hào)31;

mtdblock.c : MTD塊設(shè)備接口相關(guān)實(shí)現(xiàn),設(shè)備號(hào)90,;

mtdcore.c: MTD原始設(shè)備接口相關(guān)實(shí)現(xiàn);

mtdpart.c : MTD分區(qū)接口相關(guān)實(shí)現(xiàn)。

5.ubi

ubifs文件的支持層,當(dāng)使用ubifs文件系統(tǒng)時(shí),需要將Device Drivers -> Memory Technology Device (MTD) support -> UBI -Unsorted block image 中的Enable UBI選中。

將File systems -> Miscellaneous filesystems中的UBIFS file system support選中。

MTD分區(qū)表的實(shí)現(xiàn)

在開機(jī)過程從console經(jīng)??梢钥吹筋愃埔韵滦畔?,

0x000000000000-0x000000100000 : "Bootloade"
0x000000100000-0x000002000000 : "Kernel"
0x000002000000-0x000003000000 : "User"
0x000003000000-0x000008000000 : "File System"

這就是MTD給我們一種最直觀的表示形式,給我們展示了內(nèi)存中各模塊的分區(qū)結(jié)構(gòu),但這些分區(qū)是怎樣實(shí)現(xiàn)的呢?分區(qū)表的實(shí)現(xiàn)方式有幾種,下面進(jìn)行分別說明:

注:分區(qū)表實(shí)現(xiàn)的前提是MTD設(shè)備驅(qū)動(dòng)已經(jīng)成功了,否則連驅(qū)動(dòng)都沒成功就無分區(qū)可說了。

1.內(nèi)核中添加

在內(nèi)核中添加這是一個(gè)比較經(jīng)常使用的方法,隨便一本驅(qū)動(dòng)移植的書上應(yīng)該都有,主要就是在平臺(tái)設(shè)備里面添加mtd_partition,添加類似下面的信息,這邊就不過多描述

struct mtd_partition s3c_nand_part[] = {
    {
        .name       = "Bootloader",
        .offset     = 0,
        .size       = (1 * SZ_1M),
        .mask_flags = MTD_CAP_NANDFLASH,
    },
    {
        .name       = "Kernel",
        .offset     = (1 * SZ_1M),
        .size       = (31 * SZ_1M) ,
        .mask_flags = MTD_CAP_NANDFLASH,
    },
    {
        .name       = "User",
        .offset     = (32 * SZ_1M),
        .size       = (16 * SZ_1M) ,
    },
    {
        .name       = "File System",
        .offset     = (48 * SZ_1M),
        .size       = (96 * SZ_1M),
    }
};

static struct s3c_nand_set s3c_nand_sets[] = {
    [0] = {
        .name       = "nand",
        .nr_chips   = 1,
        .nr_partitions  = ARRAY_SIZE(s3c_nand_part),
        .partitions = ok6410_nand_part,
    },
};

static struct s3c_platform_nand s3c_nand_info = {
    .tacls      = 25,
    .twrph0     = 55,
    .twrph2     = 40,
    .nr_sets    = ARRAY_SIZE(s3c_nand_sets),
    .sets       = ok6410_nand_sets,
};

static void __init s3c_machine_init(void)
{
    s3c_nand_set_platdata(&s3c_nand_info); 
}

因?yàn)槲覀兊腗TD驅(qū)動(dòng)已經(jīng)完成了,當(dāng)device和driver匹配后會(huì)調(diào)用驅(qū)動(dòng)中的probe接口函數(shù),我們需要在probe函數(shù)里面調(diào)用add_mtd_partitions(s3c_mtd, sets->partitions, sets->nr_partitions);實(shí)現(xiàn)分區(qū)表的添加。

2.u-boot傳參

在u-boot下可以通過添加mtdparts信息到bootargs中,u-boot啟動(dòng)后會(huì)將bootargs中的信息傳送給kernel,,kernel在啟動(dòng)的時(shí)候會(huì)解析bootargs中mtdparts的部分,這邊舉個(gè)例子:

mtdparts=nand.0:1M(Bootloader)ro,31M(Kernel)ro,16M(User),96M(File System),更具體的mtdparts格式可以查閱下相關(guān)資料。

為了使kernel能夠解析mtdparts信息,我們需要將內(nèi)核中的Device Drivers -> Memory Technology Device (MTD) support ->Command line partition table parsing選項(xiàng)開啟,這在上面已經(jīng)說過。

在內(nèi)核中添加分區(qū)表的時(shí)候,我們是在平臺(tái)設(shè)備里面加入mtd_partition信息。這邊通過u-boot傳參則取消平臺(tái)設(shè)備里面的partition信息,那我們需要怎樣解析u-boot的傳過來的mtdparts呢。

u-boot傳參過來后,cmdlinepart.c中會(huì)將這些參數(shù)解析好,存在里面LIST_HEAD(part_parsers)鏈表里面,然后我們在驅(qū)動(dòng)的probe函數(shù)中,通過調(diào)用mtd_device_parse_register(mtd, probe_types,&ppdata, NULL, 0);函數(shù)。

mtd_device_parse_register()函數(shù)位于drivers/mtd/mtdcore.c 中,內(nèi)容如下:

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;
}

可以看到該函數(shù)會(huì)先執(zhí)行parse_mtd_partitions(mtd, types, &real_parts, parser_data);函數(shù),后面還是通過add_mtd_partitions()函數(shù)來實(shí)現(xiàn)分區(qū)表的添加。

parse_mtd_partitions()函數(shù)位于drivers/mtd/mtdpart.c中,內(nèi)容如下:

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;
}

進(jìn)入parse_mtd_partitions()函數(shù)會(huì)先判斷types的類型,如果為空則給默認(rèn)值,types的類型一般就兩種,如下:

static const char * const default_mtd_part_types[] = {
    "cmdlinepart",
    "ofpart",
    NULL
};

第一個(gè)"cmdlinepart"即u-boot傳參的方式,第二個(gè)"ofpart"即下面要講到的使用dts傳參的方式,判斷完類型后,就通過get_partition_parser去解析part_parsers鏈表里面的數(shù)據(jù),這樣就完成u-boot參數(shù)的解析。

3.dts傳參

在Linux3.14以后的linux版本中,加入一個(gè)新的知識(shí)DTS(Device tree),dts其實(shí)就是為了解決ARM Linux中的冗余代碼,在Linux2.6版本的arch/arm/plat.xxx和arch/arm/mach.xxx中充斥著大量的垃圾代碼,采用Device Tree后,許多硬件的細(xì)節(jié)可以直接透過它傳遞給Linux,而不再需要在kernel中進(jìn)行大量的冗余編碼,關(guān)于dts可以自行查閱資料。

dts傳參的原理其實(shí)和u-boot一樣,區(qū)別在于:u-boot的時(shí)候是通過cmdlinepart.c文件實(shí)現(xiàn)分區(qū)信息寫入LIST_HEAD(part_parsers)鏈表,dts則是用過ofpart.c文件實(shí)現(xiàn)分區(qū)信息寫入LIST_HEAD(part_parsers)鏈表,所以同樣要把ofpart.c文件的宏打開,在調(diào)用mtd_device_parse_register(mtd, probe_types,&ppdata, NULL, 0);函數(shù)的時(shí)候types要設(shè)置成ofpart。

如果去對(duì)比Linux2.6版本和Linux3.14版本,會(huì)發(fā)現(xiàn)drivers/mtd/ofpart.c和drivers/mtd/mtdpart.c文件有所不同,Linux3.8版本里面多了Device tree這一部分的內(nèi)容,感興趣的可以自己深究下。

這邊舉個(gè)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>;
        };
    };

到此,相信大家對(duì)“l(fā)inux mtd的概念是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


名稱欄目:linuxmtd的概念是什么
本文網(wǎng)址:http://weahome.cn/article/jgdegd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部