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, то самое логичное вообще сделать универсальный драйвер для этой шины, который позволяет задавать адрес устройства из программы в 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+ томах, и это при том, что сложность этой ОС на порядок уступает Л.
Я все лишь спросил, почему нет официального документа, и его действительно нет, а есть множество информации, разбросанной по разным сайтам, и кому можно доверять, а кому нельзя, неизвестно.
«Об одном умоляю, друг мой… не говори красиво» — да, вы правы, это совет для меня. Я читал Хема, но не умею пользоваться его рекомендациями «Она сказала», для этого действительно нужен талант, поэтому пишу, как получается, за критику спасибо.
Если Вы решили, что я захотел наехать на Л, то это не так — наезжаю я на них в другом посте, который все никак не закончу, по принципу «критикуешь — предлагай», с критикой у меня все отлично, с предложениями сложнее.
К примеру, как я могу догадаться, чем занимается insmode, не имея его исходников, в некоем официальном релизе.
И системные вызовы действительно документированы неплохо, но… приведенный Вами раздел о передаче параметров из двух строк я иначе, чем отпиской по принципу «да отвалите от меня» назвать не могу. Я не зря упомянул талмуд по РАФОС в 10+ томах, и это при том, что сложность этой ОС на порядок уступает Л.
Я все лишь спросил, почему нет официального документа, и его действительно нет, а есть множество информации, разбросанной по разным сайтам, и кому можно доверять, а кому нельзя, неизвестно.
Также, вы усложняете передачу данных, так как передать в ядро строку проще, чем сложную структуру данных со ссылками внутри.вот да. Пару лет тому назад переписывали код с 32 бита на 64 (который до нас был переписан с 16 на 32) — намаялись, ужас.
Зато строки — на раз-два, поставили только им «utf-8» на будущее и все (потому что латиница и цифры с пробелами).
Атрибут unused про подавление предупреждений компилятора о неиспользуемой переменной. А атрибут used про отключение оптимизации неиспользуемой статической переменной. Так что они не противоположны, как можно предположить из названия, а, наоборот, дополняют друг друга.
Например:
без атрибутов — предупреждение + переменная удалена при компиляции;
unused — предупрежения нет, но переменная всё равно удалена;
used — предупреждение, переменная остаётся в объектном файле;
used unused — предупреждения нет, переменная есть.
Например:
без атрибутов — предупреждение + переменная удалена при компиляции;
unused — предупрежения нет, но переменная всё равно удалена;
used — предупреждение, переменная остаётся в объектном файле;
used unused — предупреждения нет, переменная есть.
А тогда почему так загадочно поменялся смысл __used, непонятно.
Ну и опять вопрос про документацию, на этот раз к gcc — я нашел применение __unused__ к переменным, а про __used__ не нашел и где все таки правильно искать?
Ну и опять вопрос про документацию, на этот раз к gcc — я нашел применение __unused__ к переменным, а про __used__ не нашел и где все таки правильно искать?
Так в документации же всё есть.
UFO just landed and posted this here
Автор, драйвер случайно не для 7" LCD? Можно ссылку на драйвер или на журнал?
Очень тяжелое повестование, осилил дочитать только с третьего подхода.
как в Л действительно реализуется параметризация драйвера
существует набор макросов, которые следует использовать при создании исходного текста модуля, чтобы иметь возможность передавать ему параметры функционирования, например, адрес устройства на шине
По какой-то странной причине встречается такая ошибка у разработчиков (вот я точно по первому времени её совершал, но не помню, по какой причине) — отождествление «драйвера» и «устройства». И, соответственно, попытки параметризовать драйвер параметрами устройства. В мире, где в системе любое физическое устройство присутствует в единственном экземпляре это не имеет значения. Однако, такие драйвера имеют существенные проблемы при необходимости управялть двумя однотипными устройствами. Поэтому параметры драйвера в современных линуксах встречаются всё реже и реже, а устройства параметризуются через Device Tree, таблицы ACPI или через platform data.
Странности, я подозреваю, типа перепаковки в одну строку и обратно — чисто исторические особенности, которые потом никому не нужно было менять. Такое себе безобидное legacy.
Тут были замечания про стиль — не знаю, мне нормально читалось.
Тут были замечания про стиль — не знаю, мне нормально читалось.
Sign up to leave a comment.
К вопросу о параметрах драйвера в Linux, или как я провел выходные