Русские Блоги
MTD (Memory Technology Device), устройство с технологией памяти, является подсистемой устройств хранения Linux. Целью разработки этой системы является предоставление уровня абстракции и интерфейса для запоминающих устройств, так что разработчикам драйверов аппаратного обеспечения необходимо предоставить только простейшую функцию чтения / записи / стирания базового аппаратного устройства. Да, вам не нужно заботиться о том, как данные представляются верхним пользователям, потому что подсистема устройства хранения MTD сделала это за вас.
Рамки 1.MTD
Устройство Linux MTD находится в каталоге drivers / mtd /, здесь приведен только приблизительный анализ его структуры каталогов. Если вы хотите узнать конкретные детали, вы можете проверитьблог Крифана, Есть много ссылок и статей для справки, и анализ очень тщательный. Содержимое файла MTD выглядит следующим образом:
Оборудование MTD обычно можно разделить на четыре уровня
Сверху вниз находятся: узел устройства, уровень устройства MTD, уровень исходного устройства MTD и уровень драйвера оборудования.
1.cmdlinepart.c
Когда таблица разделов mtd переносится из u-boot в linux через параметры cmd, ядру linux не нужно регистрироваться и добавлять mtdparts, просто включите параметр разделения командной строки в MTD. Используя этот метод, u-boot должен поддерживать MTD, а передаваемые параметры раздела mtd должны соответствовать требованиям формата.
Папка 2.devices
Когда у нас есть устройство spi flash и нам нужно использовать mtd для управления, мы обычно помещаем его в папку устройств, например, m25p80.c в папке устройств — это типичное устройство spi flash.
Папка 3.chips / nand / onenand
Флеш-драйвер nand находится в папке nand;
Flash-драйвер onenand находится в папке onenand;
И флэш не сложнее, там будут все следующие файлы:
- фишки: универсальный драйвер интерфейса cfi / jedec
- устройства: ни флэш нижний драйвер (spi flash)
- карты: ни функции, связанные с отображением флэш-карт
4. Основные файлы
mtdchar.c: реализация интерфейса с символьным устройством MTD, номер устройства 31;
mtdblock.c: реализация, связанная с интерфейсом блочного устройства MTD, номер устройства 90;
mtdcore.c: реализация, связанная с оригинальным интерфейсом устройства MTD;
mtdpart.c: реализация интерфейса раздела MTD.
5.ubi
Слой поддержки файла ubifs. При использовании файловой системы ubifs необходимо выбрать «Включить UBI» в разделе «Драйверы устройств» -> «Поддержка устройств с технологией памяти (MTD)» -> UBI — Несортированный образ блока.
Выберите поддержку файловой системы UBIFS в Файловые системы -> Другие файловые системы.
2. Реализация таблицы разделов MTD
Во время процесса загрузки вы часто можете увидеть информацию, похожую на следующую из консоли,
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, .twrph1 = 40, .nr_sets = ARRAY_SIZE(s3c_nand_sets), .sets = ok6410_nand_sets, >; static void __init s3c_machine_init(void)
Поскольку наш драйвер MTD завершен, при совпадении устройства и драйвера будет вызвана функция интерфейса датчика в драйвере, и нам нужно вызвать его в функции датчика add_mtd_partitions(s3c_mtd, sets->partitions, sets->nr_partitions); Реализуйте добавление таблицы разделов.
2.u-boot параметры передачи
Под u-boot вы можете добавить информацию mtdparts в bootargs.После запуска u-boot информация из bootargs будет передаваться ядру, и ядро будет анализировать часть bootargs mtdparts при запуске. Вот пример:
mtdparts=nand.0:1M(Bootloader)ro,31M(Kernel)ro,16M(User),96M(File System) Более конкретный формат mtdparts можно найти в соответствующей информации.
Чтобы ядро могло анализировать информацию mtdparts, нам нужно включить опцию «Драйверы устройств -> Поддержка устройств с памятью (MTD)» -> «Разбор таблицы разделов командной строки» в ядре, как было упомянуто выше.
При добавлении таблицы разделов в ядро мы добавляем информацию mtd_partition на устройство платформы. Передача параметров через u-boot здесь отменяет информацию о разделах в устройстве платформы, а затем, как нам нужно проанализировать mtdparts, переданные u-boot.
После того, как u-boot передаст параметры, эти параметры будут проанализированы в cmdlinepart.c и сохранены внутри LIST_HEAD(part_parsers) В связанном списке мы затем в функции зонда драйвера, вызывая 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 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 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() Функция сначала определит тип типа, и если он будет пустым, он даст значение по умолчанию. Обычно существует два типа типов:
static const char * const default_mtd_part_types[] = < "cmdlinepart", "ofpart", NULL >;
Первый «cmdlinepart» — это способ передачи параметров в u-boot, а второй «ofpart» — это способ передачи параметров с использованием dts, как указано ниже. После оценки типа pass get_partition_parser Разобрать part_parsers Данные в связанном списке завершат анализ параметров загрузки.
Передача параметров 3.dts
В версии Linux после Linux3.14 добавлено новое знание DTS (Дерево устройств). Фактически, DTS решает избыточный код в ARM Linux. В Linux2.6 версии arch / arm / plat.xxx и arch / Файл Arm / mach.xxx заполнен большим количеством мусорного кода. После принятия дерева устройств многие детали аппаратного обеспечения могут напрямую передаваться в Linux через Linux вместо большого количества избыточного кодирования в ядре. Вы можете обращаться к 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); Тип функции должен быть установлен на ofpart.
Если вы сравните версию для Linux 2.6 и версию для Linux 3.14, вы обнаружите, что файлы drivers / mtd / ofpart.c и drivers / mtd / mtdpart.c отличаются. Версия Linux 3.8 включает дерево устройств. Те, кто заинтересован, могут вникать в это самостоятельно.
pinctrl-0 = ; ranges = ; /* CS0: NAND */ [email protected],0 < [email protected] < label = "Bootloader"; reg = ; >; [email protected] < label = "Kernel"; reg = ; >; [email protected] < label = "User"; reg = ; >; [email protected] < label = "File System"; reg = ; >; >;
Анализ системы Linux Mtd здесь, и она будет обновляться, когда у вас есть чувства.
Примечание. Приведенное выше содержание является частью моего опыта, накопленного в процессе обучения. Это неизбежно, что я буду ссылаться на некоторые знания других статей. Если есть какие-либо нарушения, пожалуйста, сообщите мне вовремя. Я буду удалять или отмечать источник контента в срок. Пожалуйста, укажите, обсудите и изучите. Эта статья является лишь руководством. Для подробного анализа данных, пожалуйста, ознакомьтесь с руководствами по Linux. Спасибо за чтение.