Intereting Posts
Могу ли я заставить 7z пропускать сжатие (но не включать) определенных файлов при сжатии каталога с его подсистемами? HSTSpreload, www субдомен и проблемы с перенаправлением Некоторые пакеты не могут быть установлены с использованием multi-arch (возьмите два) Как проверить, используется ли звуковая карта и, если возможно, какой процесс ее использует? как я могу запустить интерактивную систему systemd Крепление только для чтения ZFS на Linux + одновременное крепление для чтения и записи на Solaris отправка электронной почты на IP-адрес через постфикс Что делает мой курсор «случайным образом» исчезающим при использовании gnome-teminal? Как получить byobu для запуска при запуске с выполненной командой, как root? Установка программного обеспечения при первой загрузке системы после установки CentOS crontab error (без установки MTA), но я использую> / dev / null 2> & 1 grub2 отсутствуют окна, манджаро cp: не может статировать ошибку – когда имя файла имеет азиатские символы Как я могу использовать Linux Mint 15 Olivia всегда в консольном режиме Как отсоединить диск в Linux (имитировать сбой раздела / диска)?

Когда использовать / dev и / sys для взаимодействия с userpace-kernel?

Я только начинаю разработку драйверов для Linux, и у меня есть концептуальный вопрос, который, я думаю, поможет другим новичкам в разработке ядра.

Я читаю книгу «Драйверы устройств для Linux» и дошёл до гл. 3 книги. До сих пор я видел, что, выполняя команды open , close и другие для файлов в папке /dev , пользовательское пространство может получить доступ к функциям ядра.

Другой способ совместного управления – через файлы в /sys , где чтение или запись из файлов sys могут связываться с драйвером.

Я хотел знать, какие будут варианты использования для каждого метода? Это 2 подхода к одной и той же задаче? Есть ли у кого-то ограничения по сравнению с другим? Может кто-нибудь поделиться практическими примерами, где один может быть полезен над другим?

Я прочитал другие вопросы здесь, и они объясняют dev и sys . Хотя это полезно, я хотел бы получить немного более глубокие знания о том, как они различаются и должны использоваться.

Очень грубо

/dev содержит узлы устройств, которые в более ранних системах Unix были единственным способом взаимодействия с kernelм. Существует два типа таких устройств: блочные устройства и символьные устройства. Соответствующий API предназначен для чего-то, что будет позволять ввод / вывод на основе блоков (некоторый тип диска) или ввод / вывод на основе символов (например, serial port).

/sys/proc ) были добавлены позже, возможно, под влиянием ОС Plan 9 . Они предоставляют полные поддеревья каталогов, а записи файла в этих поддеревьях содержат текст, который описывает внутреннее состояние модуля ядра при чтении или, когда записано, задание внутреннего состояния.

Таким образом, типичное приложение будет:

Вы хотите написать драйвер ядра для какого-либо устройства хранения? Используйте узел /dev для доступа к самому устройству и записи /sys (или /proc ) для точной настройки доступа к хранилищу.

Описание /sys приведено в главе 14 «Модель устройства Linux». Он предоставляет еще несколько примеров кода для игры. Но я полагаю, что книга представляет собой более управляемый кодом подход, и полезно спросить, как выглядят принципы проектирования.

Когда использовать / dev и / sys для взаимодействия с userpace-kernel?

Самый первый ответ, что вы не выбираете себя. Когда вы пишете драйвер для устройства определенного типа, в ядре уже есть много примеров устройств такого же типа. Вы используете эквивалентные шаблоны кода для существующих устройств. (Самая свежая документация – это сам код. Многие интерфейсы ядра не имеют полной или актуальной документации, извините!)

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

Это отменяет любой более общий совет. Если подсистема Linux (то есть тип устройства) использует метод, который кажется «неправильным», но делает это последовательно, вы также должны быть последовательными и «неправильными», когда вы пишете драйвер для этой подсистемы.

/ DEV

/ dev / должен использоваться для пути к данным. За исключением сетевых устройств, о которых пойдет речь в другом разделе книги.

/ dev / специальные файлы должны использоваться для стандартизированных операций Unix: read() , write() , poll() / select() , mmap() . Также желательно, чтобы ioctl() были эффективно стандартизированы в Unix или Linux. Эти несколько системных вызовов (и несколько производных вариантов) используются практически во всех случаях. Начните знакомиться с ними :). ioctl() – это аварийный штрих, который можно использовать, чтобы ваш драйвер мог определять любое количество других операций.

/ SYS

Записи sysfs должны использоваться в гораздо меньшем числе случаев для параметров конфигурации. Они должны быть в текстовом формате и содержать только одно значение. [*] Вам не нужно иметь слишком много разных файлов sysfs. Вы можете начать видеть их ограничения довольно быстро.

Можно также сказать, что файлы sysfs должны в основном читать переменную (которая может или не может быть доступна для записи). Я думаю, что их чтение не должно вызывать никаких аппаратных операций. Я ожидаю, что вы уже думали в этом направлении, хотя.

Преимущество файлов sysfs заключается в том, что с ними очень удобно экспериментировать. Вы можете легко использовать команды оболочки для их enums, чтения и записи. Это также опасно: вы должны позаботиться о том, чтобы не публиковать файлы sysfs в экспериментальном состоянии. Когда другие люди начнут полагаться на ваш файл sysfs, сопровождающие ядра будут крайне недовольны, если вы захотите что-то изменить, что нарушает пользовательские сценарии.

Обход sysfs – иерархии каталогов и символических ссылок – также может быть полезен для просмотра организации устройств.

Кроме того, концептуально следя за изменениями в sysfs, можно узнать, как программы могут обнаруживать новые устройства (например, при подключении). Технически эти события не доставляются через саму файловую систему, но каждое событие указывает на определенный каталог sysfs.

Демон udev слушает эти события; нормальные программы должны иметь тенденцию полагаться на udev / libudev, если это необходимо. Например, правила udev могут читать или записывать некоторые файлы в каталоге sysfs при получении события, например, для изменения настроек на вновь обнаруженных устройствах.

Глядя на примеры

Просмотр существующих примеров – очень хорошая идея. Хотя вам, вероятно, не стоит рассматривать только один пример, и предполагать, что он везде работает одинаково :-).

Как говорит Диркт, доступ к блочным устройствам хранения, таким как /dev/sda является очень стандартизированным использованием /dev . Несколько параметров, таких как максимальный физический размер ввода-вывода, выставляемый в /sys/class/block/sda/ можно найти в подкаталоге queue .

Многие файлы sysfs описаны в дереве ядра, Documentation/ABI/*/sysfs-* . Например: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block

Обратите внимание, что «символьное устройство» не очень специфично. Он используется в основном для любого устройства, которое не является ни блочным устройством, ни сетевым устройством :-). Если вам когда-либо приходилось реализовывать какой-то совершенно новый class устройств, вам, вероятно, пришлось бы определять совершенно новый тип символьных устройств, и у вас была бы ужасная работа по определению некоторого нового набора операций ioctl() .

Вы можете начать поиск в /sys/class/ , чтобы посмотреть, какие другие типы устройств определены в вашей собственной системе.

/sys/ также содержит список устройств /dev/ , но он указан по номеру устройства, а не по имени. Смотрите ls -l /sys/dev/char/ и ls -l /sys/dev/block/ . Это помогает объяснить, как udev может управлять /dev : каждое устройство, отображаемое в /dev , указывается как объект в /sys . [**]


[*] Файлы uevent sysfs содержат несколько значений и фактически являются основной функцией. но файл uevent нельзя использовать для изменения значений внутри. Так что это просто сказать: не смотрите на uevent и думайте, что мой совет неверен; Вы не должны определять файл как этот самостоятельно. Драйвер устройства может добавлять строки в свой файл uevent ; Я думаю, что хорошим примером будет, если у вас есть несколько очень полезных идентифицирующих свойств, которые хочет проверить правило udev .

[**] За исключением того, что /dev/pts/0 и т. Д. Не перечислены в /sys , поскольку /dev/pts/0 фактически реализована отдельной файловой системой “devpts”. Пожалуйста, игнорируйте /dev/pts/0 как очень, очень особый случай. Есть ответ, в котором я пришел к выводу, но я действительно не думаю, что это что-то добавляет к тому, что я только что сказал. Это здесь: TTY всегда привыкает, когда мы открываем какой-либо терминал? ,