Как написать драйвер блочного устройства 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)


arrow_upward
13
arrow_downward

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

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

person MarkR    schedule 16.02.2010

arrow_upward
7
arrow_downward

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

person hillu    schedule 14.10.2010

arrow_upward
4
arrow_downward

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

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

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

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

person Ofir    schedule 15.02.2010

arrow_upward
4
arrow_downward

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

person schoppenhauer    schedule 17.11.2013

arrow_upward
1
arrow_downward

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

person Rich    schedule 13.04.2019