Pull to refresh

Comments 16

Вообще, в Линуксе есть системный вызов ioctl(), которым можно передавать параметры и менять режим работы модуля ядра.

Если у вас есть внешнее устройство на какой-то шине вроде I2C, то самое логичное вообще сделать универсальный драйвер для этой шины, который позволяет задавать адрес устройства из программы в userspace. Так как чем меньше кода в ядре, тем меньше шанс уронить его в панику.

То есть драйвер делает доступным специальный файл устройства вроде /dev/i2c, а дальше userspace-программа открывает его, с помощью ioctl задает адрес устройства на шине, пишет данные в файл и они шлются в устройство. Или же драйвер сам находит устройства и для каждого создает отдельный файл.

Этот подход имеет то преимущество, что мы минимизируем объем кода в ядре, а с помощью файловой системы можем гибко настраивать права доступа к устройству. И один экземпляр драйвера обеспечивает доступ к неограниченному числу устройств. Вы же любите экономить память, вот вам экономия.

Также, я подозреваю, что для такой популярной шины драйвер уже существует.

Тут вы можете заметить, что предложенное мной решение просто дает доступ к шине i2c, но никак не помогает нам вывести информацию на индикатор, так как мы должны знать протокол обмена данными с ним. Эту проблему обычно решают с помощью динамической библиотеки, условно liblcd, которая в себе содержит процедуры управления индикатором вроде display_text(string text), и соответственно, функцию для задания адреса индикатора на шине. И если вам нужно что-то вывести, то вы пишете программу, которая линкуется с этой библиотекой и вызывает ее API. В этой программе вы задаете адрес устройства любым удобным вам способом. А библиотека уже взаимодействует с драйвером шины I2C. В идеале такую библиотеку в виде исходных кодов предоставляет разработчик устройства.

А командная строка для модулей используется не так часто, обычно для задания каких-то редко меняющихся параметров, включения каких-то хаков. В линуксе модули ядра часто подгружаются автоматически, а не вручную, например, при обнаружении какого-то устройства или попытке его задействовать. Ваш же подход предполагает ручную загрузку модуля с ручным указанием параметров.

Ну и стиль написания текста у вас конечно своеобразный и витиеватый — приходится по 2 раза перечитывать, чтобы понять. Было бы хорошо, если бы вы меньше «растекались мыслью по древу».

> Вторая удивительная вещь заключается в том, что данная утилита формируется из пакета, название которого никоим образом с ее названием не связано, таких пакетов более, чем один, и каждый назван по своему в разных местах — забавно, если не сказать больше.

А вам и не нужен код утилиты insmod. Ведь то, что она делает — это выполнение системного вызова init_module, который описан в документации.

> Что же такое забористое курят разработчики Л, уж больно извилист ход их мыслей, воплощенный в коде. Я знаю, что можно применять обе формы записи атрибута, но зачем это делать в одной строке — не понимаю.

Да, интересно. Анализ истории в git мог бы пролить свет на эту загадку.

> Итак, имеется возможность создания модуля — некоей специальным образом оформленной программной единицы, которая может быть загружена в память для исполнения при помощи некоторой системной утилиты

Не просто в память, а в память ядра. Код драйвера выполняется в привилегированном режиме процессора. Также, драйвер напоминает не утилиту, которую вы запускаете сколько угодно раз, а постоянно работающий сервис, обслуживающий запросы от приложений.

> Второе решение — собственно парсер переносим в И, который передает модулю (его инициализационной части) извлеченные данные — номер параметра и значение.

Этим вы ограничиваете возможности, так как разработчик обязан использовать только синтаксис, который поддерживает insmod. Также, вы усложняете передачу данных, так как передать в ядро строку проще, чем сложную структуру данных со ссылками внутри. Ведь области памяти пользовательского процесса и ядра изолированы, и код ядра должен будет при загрузке модуля обходить переданную ему структуру данных, проверять корректность каждой ссылки и копировать каждый элемент в память ядра. Одну строку скопировать гораздо проще.

> почему необходимую информацию (я не имею в виду внутреннюю кухню, а внешнее представление) приходится искать по различных источникам, которые не имеют статуса официальных, где документ, аналогичный книге «Программное обеспечение СМ ЭВМ. Операционная система с разделением функций. РАФОС. Руководство системного программиста.»

Написание документа и поддержание его в актуальном состоянии требует времени. Все исходные данные — доступны, значит проблема в том, что никто не хочет сделать или заказать кому-то эту работу.

Например, в TLDP есть руководство по написанию модулей ядра — но для версии 2.6: www.tldp.org/LDP/lkmpg/2.6/html/index.html. В нем есть раздел про передачу аргументов.

Системные вызовы ядра Линукс документированы, на мой взгляд, качественно: описан порядок работы каждого вызова, формат аргументов, возвращаемый результат, возможные ошибки.
Да я как то и не писал модуля для I2C, это просто была отправная точка. Хотя идея с ioctl интересная, но не это тема поста.

«Об одном умоляю, друг мой… не говори красиво» — да, вы правы, это совет для меня. Я читал Хема, но не умею пользоваться его рекомендациями «Она сказала», для этого действительно нужен талант, поэтому пишу, как получается, за критику спасибо.

Если Вы решили, что я захотел наехать на Л, то это не так — наезжаю я на них в другом посте, который все никак не закончу, по принципу «критикуешь — предлагай», с критикой у меня все отлично, с предложениями сложнее.

К примеру, как я могу догадаться, чем занимается insmode, не имея его исходников, в некоем официальном релизе.

И системные вызовы действительно документированы неплохо, но… приведенный Вами раздел о передаче параметров из двух строк я иначе, чем отпиской по принципу «да отвалите от меня» назвать не могу. Я не зря упомянул талмуд по РАФОС в 10+ томах, и это при том, что сложность этой ОС на порядок уступает Л.
Я все лишь спросил, почему нет официального документа, и его действительно нет, а есть множество информации, разбросанной по разным сайтам, и кому можно доверять, а кому нельзя, неизвестно.
Также, вы усложняете передачу данных, так как передать в ядро строку проще, чем сложную структуру данных со ссылками внутри.
вот да. Пару лет тому назад переписывали код с 32 бита на 64 (который до нас был переписан с 16 на 32) — намаялись, ужас.
Зато строки — на раз-два, поставили только им «utf-8» на будущее и все (потому что латиница и цифры с пробелами).
Атрибут unused про подавление предупреждений компилятора о неиспользуемой переменной. А атрибут used про отключение оптимизации неиспользуемой статической переменной. Так что они не противоположны, как можно предположить из названия, а, наоборот, дополняют друг друга.
Например:
без атрибутов — предупреждение + переменная удалена при компиляции;
unused — предупрежения нет, но переменная всё равно удалена;
used — предупреждение, переменная остаётся в объектном файле;
used unused — предупреждения нет, переменная есть.
А тогда почему так загадочно поменялся смысл __used, непонятно.
Ну и опять вопрос про документацию, на этот раз к gcc — я нашел применение __unused__ к переменным, а про __used__ не нашел и где все таки правильно искать?
Да, Вы правы, спасибо, я на другом ресурсе сразу пошел смотреть для переменных и не нашел used, честно говоря, что то подобное и предполагал, хотя история с __used откровенно смущала.
Вот и еще раз аргумент в пользу официальной документации.
UFO just landed and posted this here
Это типа для автозамены? А точно станет понятнее?
А в самом деле, для чего нужны эти замены? Вроде линуксоидам привычны все названия, и insmod-ом поди кого напугай. А так приходится думать, что имелось в виду буквой И — insmod, ioctl или просто И.
Автор, драйвер случайно не для 7" LCD? Можно ссылку на драйвер или на журнал?
Очень тяжелое повестование, осилил дочитать только с третьего подхода.
как в Л действительно реализуется параметризация драйвера


существует набор макросов, которые следует использовать при создании исходного текста модуля, чтобы иметь возможность передавать ему параметры функционирования, например, адрес устройства на шине


По какой-то странной причине встречается такая ошибка у разработчиков (вот я точно по первому времени её совершал, но не помню, по какой причине) — отождествление «драйвера» и «устройства». И, соответственно, попытки параметризовать драйвер параметрами устройства. В мире, где в системе любое физическое устройство присутствует в единственном экземпляре это не имеет значения. Однако, такие драйвера имеют существенные проблемы при необходимости управялть двумя однотипными устройствами. Поэтому параметры драйвера в современных линуксах встречаются всё реже и реже, а устройства параметризуются через Device Tree, таблицы ACPI или через platform data.
Странности, я подозреваю, типа перепаковки в одну строку и обратно — чисто исторические особенности, которые потом никому не нужно было менять. Такое себе безобидное legacy.

Тут были замечания про стиль — не знаю, мне нормально читалось.
Sign up to leave a comment.

Articles