久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

linux mtd的概念是什么

281次閱讀
沒有評論

共計 5975 個字符,預計需要花費 15 分鐘才能閱讀完成。

本篇內容主要講解“linux mtd 的概念是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“linux mtd 的概念是什么”吧!

在 linux 中,mtd 是指“內存技術設備”,是存儲設備中的一個子系統。linux 引入 MTD 系統是為了給 NOR FLASH 和 NAND FLASH 設備提供統一接口。MTD 設備通常可分為四層:設備節點、MTD 設備層、MTD 原始設備層、硬件驅動層。

本教程操作環境:linux5.9.8 系統、Dell G3 電腦。

Linux MTD 是什么?

MTD 全稱“Memory Technology Device”,意思為“內存技術設備”,是 Linux 的存儲設備中的一個子系統。

在 Linux 內核中,引入 MTD 層為 NOR FLASH 和 NAND FLASH 設備提供統一接口。MTD 將文件系統與底層 FLASH 存儲器進行了隔離。

設計此 MTD 系統的目的是,對于內存類的設備,提供一個抽象層,一個接口,使得對于硬件驅動設計者來說,只需要去提供最簡單的底層硬件設備的讀 / 寫 / 擦除函數就可以了,數據對于上層使用者來說是如何表示的,可以不關心,因為 MTD 存儲設備子系統都幫你做好了。

MTD 框架

Linux 的 MTD 設備位于 drivers/mtd/ 下面。

MTD 文件下的內容如下:

MTD 設備通常可分為四層

上到下依次是:設備節點、MTD 設備層、MTD 原始設備層和硬件驅動層。

1.cmdlinepart.c

當 mtd 分區表由 u -boot 通過 cmd 參數傳輸給 linux 時,linux 內核可以不用對 mtdparts 進行注冊添加,只需要將 MTD 中的 command line partition 選項開啟即可。使用這種的方法 u -boot 下需要對 MTD 進行支持,且所傳輸的 mtd 分區參數要符合格式要求。

2.devices 文件夾

當我們有一個 spi flash 設備時且要使用 mtd 進行管理,我們一般會將其放在 devices 文件夾下,如 devices 文件夾下面的 m25p80.c 就是一個典型的 spi flash 設備。

3.chips/nand/onenand 文件夾

nand flash 驅動在 nand 文件夾下;

onenand flash 驅動在 onenand 文件夾下;

nor flash 比較雜,下面幾個文件下都會有:

chips:cfi/jedec 接口通用驅動

devices:nor flash 底層驅動 (spi flash)

maps:nor flash 映射關系相關函數

4. 核心文件

mtdchar.c : MTD 字符設備接口相關實現, 設備號 31;

mtdblock.c : MTD 塊設備接口相關實現,設備號 90,;

mtdcore.c: MTD 原始設備接口相關實現;

mtdpart.c : MTD 分區接口相關實現。

5.ubi

ubifs 文件的支持層,當使用 ubifs 文件系統時,需要將 Device Drivers – Memory Technology Device (MTD) support – UBI -Unsorted block image 中的 Enable UBI 選中。

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

MTD 分區表的實現

在開機過程從 console 經常可以看到類似以下信息,

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

這就是 MTD 給我們一種最直觀的表示形式,給我們展示了內存中各模塊的分區結構,但這些分區是怎樣實現的呢?分區表的實現方式有幾種,下面進行分別說明:

注:分區表實現的前提是 MTD 設備驅動已經成功了,否則連驅動都沒成功就無分區可說了。

1. 內核中添加

在內核中添加這是一個比較經常使用的方法,隨便一本驅動移植的書上應該都有,主要就是在平臺設備里面添加 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); 
}

因為我們的 MTD 驅動已經完成了,當 device 和 driver 匹配后會調用驅動中的 probe 接口函數,我們需要在 probe 函數里面調用 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),更具體的 mtdparts 格式可以查閱下相關資料。

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

在內核中添加分區表的時候,我們是在平臺設備里面加入 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 的概念是什么”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-03發表,共計5975字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 嘉荫县| 云和县| 元江| 浙江省| 定兴县| 平江县| 乐都县| 鄂尔多斯市| 沅陵县| 临朐县| 岳西县| 沧源| 洞口县| 澄城县| 申扎县| 光山县| 涿鹿县| 敦化市| 和田县| 会同县| 海林市| 伊宁市| 溆浦县| 宜良县| 民勤县| 大名县| 通许县| 台北县| 丹巴县| 昌宁县| 曲周县| 拜城县| 荆门市| 泗水县| 富裕县| 玉山县| 汾西县| 大邑县| 文登市| 奇台县| 新巴尔虎左旗|