Di Linux, mtd merujuk kepada "peranti teknologi memori" dan merupakan subsistem dalam peranti storan. Linux memperkenalkan sistem MTD untuk menyediakan antara muka bersatu untuk peranti NOR FLASH dan NAND FLASH. Peranti MTD biasanya boleh dibahagikan kepada empat lapisan: nod peranti, lapisan peranti MTD, lapisan peranti asal MTD dan lapisan pemacu perkakasan.
Persekitaran pengendalian tutorial ini: sistem linux5.9.8, komputer Dell G3.
Apakah Linux MTD?
MTD bermaksud "Peranti Teknologi Memori", yang bermaksud "peranti teknologi memori" dan merupakan subsistem peranti storan Linux.
Dalam kernel Linux, lapisan MTD diperkenalkan untuk menyediakan antara muka bersatu untuk peranti NOR FLASH dan NAND FLASH. MTD mengasingkan sistem fail daripada memori FLASH yang mendasari.
Tujuan mereka bentuk sistem MTD ini adalah untuk menyediakan lapisan abstraksi dan antara muka untuk peranti jenis memori, supaya pereka bentuk pemacu perkakasan hanya perlu menyediakan peranti perkakasan asas yang paling mudah iaitu baca/tulis Fungsi /erase sudah mencukupi Bagaimana data diwakili kepada pengguna peringkat atas tidak penting, kerana subsistem peranti storan MTD telah melakukannya untuk anda.
Rangka kerja MTD
Peranti MTD Linux terletak di bawah pemacu/mtd/.
Kandungan di bawah fail MTD adalah seperti berikut:
Peralatan MTD biasanya boleh dibahagikan kepada empat lapisan
Dari atas ke bawah ialah: nod peranti , lapisan peranti MTD, lapisan peranti asal MTD dan lapisan pemacu perkakasan.
1.cmdlinepart.c
Apabila jadual partition mtd dihantar ke linux oleh u-boot melalui parameter cmd, kernel linux Tidak perlu mendaftar dan menambah mtdparts Anda hanya perlu menghidupkan pilihan partition baris arahan dalam MTD. Untuk menggunakan kaedah ini, u-boot perlu menyokong MTD, dan parameter partition mtd yang dihantar mesti memenuhi keperluan format.
folder 2.devices
Apabila kami mempunyai peranti kilat spi dan ingin menggunakan mtd untuk mengurusnya, kami biasanya meletakkannya di bawah folder peranti, Contohnya, m25p80.c di bawah folder peranti ialah peranti kilat spi biasa.
3.chips/nand/onenand folder
nand flash driver berada di bawah folder nand
onenand flash driver berada di bawah folder onenand ;
atau denyar adalah lebih rumit, dan ia akan ditemui dalam fail berikut:
cip:cfi/jedec antara muka pemacu universal
peranti: mahupun pemacu bawah denyar (spi kilat)
peta: mahupun fungsi berkaitan pemetaan kilat
4 Fail teras
mtdchar.c: pelaksanaan berkaitan antara muka peranti aksara MTD, peranti. nombor 31 ;
mtdblock.c: pelaksanaan berkaitan antara muka peranti blok MTD, nombor peranti 90,;
mtdcore.c: pelaksanaan berkaitan antara muka peranti asal MTD;
mtdpart. c: pelaksanaan berkaitan antara muka partition MTD.
5.ubi
Lapisan sokongan fail ubifs, anda perlu menukar sokongan Peranti Teknologi Memori (MTD). -> ; Dayakan UBI dalam UBI -Imej blok yang tidak diisih dipilih.
Pilih sokongan sistem fail UBIFS dalam sistem Fail -> Pelbagai sistem fail.
Pelaksanaan jadual partition MTD
Anda selalunya boleh melihat maklumat yang serupa dengan yang berikut daripada konsol semasa proses but,
0x000000000000-0x000000100000 : "Bootloade" 0x000000100000-0x000002000000 : "Kernel" 0x000002000000-0x000003000000 : "User" 0x000003000000-0x000008000000 : "File System"
Ini adalah perwakilan paling intuitif yang MTD berikan kepada kami, menunjukkan kepada kami struktur partition setiap modul dalam memori, tetapi bagaimanakah partition ini dilaksanakan? Terdapat beberapa cara untuk melaksanakan jadual partition, yang dijelaskan di bawah:
Nota: Prasyarat untuk pelaksanaan jadual partition ialah pemacu peranti MTD telah berjaya, jika tidak, tiada partition untuk bercakap walaupun pemandu tidak berjaya.
Menambah pada kernel ialah kaedah yang kerap digunakan dan harus didapati dalam mana-mana buku mengenai pemindahan pemandu perkaranya ialah menambah mtd_partition dalam peranti platform, tambah maklumat yang serupa dengan yang berikut, tiada lagi penerangan di sini
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, .twrph1 = 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); }
Oleh kerana pemandu MTD kami telah selesai, apabila peranti dan pemandu sepadan, pemandu akan dipanggil Fungsi antara muka probe, kita perlu memanggil add_mtd_partitions(s3c_mtd, sets->partitions, sets->nr_partitions);
dalam fungsi probe untuk menambah jadual partition.
Di bawah u-boot, anda boleh menambah maklumat mtdparts pada bootargs Selepas u-boot dimulakan, maklumat dalam bootargs akan dihantar ke kernel, kernel akan menghuraikan bahagian mtdparts dalam bootargs apabila ia bermula:
mtdparts=nand.0:1M(Bootloader)ro,31M(Kernel)ro,16M(User),96M(File System)
Untuk format mtdparts yang lebih khusus, anda boleh menyemak maklumat yang berkaitan.
Untuk kernel menghuraikan maklumat mtdparts, kami perlu mendayakan Pemacu Peranti -> sokongan Peranti Teknologi Memori (MTD) ->Pilihan penghuraian jadual partition baris arahan dalam kernel, seperti yang dinyatakan di atas.
在内核中添加分区表的时候,我们是在平台设备里面加入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参数的解析。
在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视频教程》
Atas ialah kandungan terperinci apa itu linux mtd. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!