Как написать драйвер блочного устройства Linux для пользовательского пространства?

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

Для начала я попытался собрать пример драйвера блочного устройства с помощью этого Makefile:

obj-m = sbd.o
KVERSION = $(shell pwd)
PWD = $(shell pwd)

all:
    make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules

Однако я получаю эти ошибки, которые я не знаю, как исправить. Вот стандартный вывод и стандартный вывод:

make -C /lib/modules/2.6.31-19-generic/build M=/home/andreas/sp/nivoa/src/driver/sbd modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.31-19-generic'
  CC [M]  /home/andreas/sp/nivoa/src/driver/sbd/sbd.o
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:72: error: expected ‘)’ before ‘*’ token
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:128: warning: initialization from incompatible pointer type
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c: In function ‘sbd_init’:
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: ‘sbd_request’ undeclared (first use in this function)
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: (Each undeclared identifier is reported only once
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: for each function it appears in.)
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:146: error: implicit declaration of function ‘blk_queue_hardsect_size’
make[2]: *** [/home/andreas/sp/nivoa/src/driver/sbd/sbd.o] Error 1
make[1]: *** [_module_/home/andreas/sp/nivoa/src/driver/sbd] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.31-19-generic'
make: *** [all] Error 2

Любая помощь по этому вопросу будет принята с благодарностью.

Спасибо, Андреас


person andreasw    schedule 15.02.2010    source источник


Ответы (5)


Не существует «официального» способа создания блочных драйверов в пользовательском пространстве, однако люди часто делают это, используя (ab) драйвер NBD для связи по петлевой сети с демоном, который слушает обычный сокет и говорит по протоколу NBD. См. документы NBD для получения дополнительной информации.

Ваш пример относится к блочному устройству режима ядра, которое необходимо собрать как модуль ядра. И поскольку внутреннее устройство ядра постоянно меняется, теперь оно, по-видимому, несовместимо.

person MarkR    schedule 16.02.2010

Следуя предложению MarkR, можно даже использовать протокол NBD через пару сокетов AF_UNIX, поэтому дополнительный локальный демон не требуется. Программа, реализующая этот протокол, должна будет настроить пару сокетов и разветвить дочерний элемент. И родитель, и потомок закрывают один конец пары сокетов. Один из них начинает принимать запросы на своем конце сокета, а другой подключает драйвер NBD к своему концу сокета.

person hillu    schedule 14.10.2010

Всегда смотрит на первую ошибку:

В вашем случае это похоже на проблему с включенными файлами, например. request_queue_t не определен.

Поскольку это устаревший тип, вы, вероятно, используете более новую версию linux/blkdev.h, чем в примере кода.

Попробуйте добавить typedef struct request_queue request_queue_t;

person Ofir    schedule 15.02.2010

Хотя использование NBD, как было предложено ранее, хорошо, возможно, лучший способ (используемый, например, virtualbox-fuse) — создать файловую систему FUSE, которая экспортирует один файл, который затем можно использовать через lossup.

person schoppenhauer    schedule 17.11.2013

Вы можете использовать НБД. Используя nbdkit, вы даже можете писать виртуальные блочные устройства в скрипт оболочки или другие языки сценариев (однако придерживайтесь C, если хотите добиться максимальной производительности) . Я выступил с докладом на эту тему на FOSDEM 2019, где написал живую демонстрацию блочное устройство ядра Linux в сценарии оболочки.

person Rich    schedule 13.04.2019