Реализация драйвера устройства в виде набора модулей ядра - PullRequest
0 голосов
/ 14 января 2012

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

Я бы хотел переместить эту библиотеку в пространство ядра и собираюсь разбить библиотеку на несколько четко определенных модулей ядра, чтобы

  • Я могу оставить дверь открытой, чтобы в будущем поменять слои (например, поменять слой USART на слой SPI).
  • Разработка будет проще. Если бы это было разделено, я мог бы перенести библиотеку в пространство ядра по частям.

Кто-нибудь когда-нибудь делал что-то подобное раньше? Каковы наилучшие (с точки зрения эффективности) способы связи между модулями ядра? Есть ли подводные камни, которых мне следует избегать?

Наконец, есть ли хорошие примеры драйверов, которые реализованы в виде набора модулей ядра?

Ответы [ 2 ]

0 голосов
/ 14 января 2012

Все модули ядра работают в одном и том же адресном пространстве.Чтобы вызвать один модуль из другого, вам необходимо экспортировать некоторые символы: функции или глобальные переменные.Хотя, вероятно, использование глобальных переменных в этом случае - плохой стиль.Обратите внимание, что ваши экспортированные символы будут в том же пространстве имен, что и все другие символы ядра.Чтобы избежать конфликтов имен, вы должны использовать для них какой-то четко определенный префикс, обычно это имя модуля и подчеркивание.Поэтому, если один из ваших модулей называется foo, и вы хотите экспортировать функцию bar(), вы можете использовать такой код в модуле foo:

void foo_bar(const char *prm) {
  printk (KERN_INFO "foo_bar(%s) was called\n", prm);
}
EXPORT_SYMBOL(foo_bar);

В другом модуле, скажем, buz,просто вызовите эту функцию:

foo_bar("qux");

Обратите внимание , что в модуле ядра вы не можете использовать функции libc (или других библиотек) и многие обычные вещи, такие как управление памятью, файл I/ O, работа в сети и так далее, может быть очень сложной.Также обратите внимание, что отладка модуля ядра не является тривиальной задачей, и многие ошибки вызовут панику ядра вместо безвредной ошибки сегментации.

Так что подумайте трижды, прежде чем перемещать какую-то рабочую библиотеку в пространство ядра.Возможно, было бы лучше разбить вашу библиотеку на те же «модули», но оставить ее (или большую ее часть) в пространстве пользователя.

0 голосов
/ 14 января 2012

Не уверен, поможет ли это, но ALSA состоит из множества отдельных модулей для каждого отдельного звукового чипа и нескольких общих, от которых зависят другие:

$ lsmod | grep snd
snd_hrtimer            12744  1 
snd_hda_codec_realtek   330769  1 
snd_hda_intel          33390  2 
snd_usb_audio         118064  0 
snd_hda_codec         104802  2 snd_hda_codec_realtek,snd_hda_intel
snd_pcm                96714  3 snd_hda_intel,snd_usb_audio,snd_hda_codec
snd_hwdep              13668  2 snd_usb_audio,snd_hda_codec
snd_usbmidi_lib        25371  1 snd_usb_audio
snd_seq_midi           13324  0 
snd_rawmidi            30547  2 snd_usbmidi_lib,snd_seq_midi
snd_seq_midi_event     14899  1 snd_seq_midi
snd_seq                61896  3 snd_seq_midi,snd_seq_midi_event
snd_timer              29991  3 snd_hrtimer,snd_pcm,snd_seq
snd_seq_device         14540  3 snd_seq_midi,snd_rawmidi,snd_seq
snd                    68266  16 snd_hda_codec_realtek,snd_hda_intel,snd_usb_audio,snd_hda_codec,snd_pcm,snd_hwdep,snd_usbmidi_lib,snd_rawmidi,snd_seq,snd_timer,snd_seq_device
soundcore              12680  1 snd
snd_page_alloc         18529  2 snd_hda_intel,snd_pcm

Восстановление графа зависимостей оставлено в качестве упражнениячитателю.

...