Я пытаюсь скомпилировать сторонний проприетарный модуль драйвера, и терпит неудачу. Я установил пакет linux-headers-5.4.0
, но я не знаю, как написать командную строку gcc, которая будет успешно его использовать.
В качестве минимального примера рассмотрим test.c
, который буквально ничего не делает, кроме включения заголовков ядра.
#include <asm/linkage.h>
#include <linux/module.h>
Поскольку ядро включает оба этих файла и само может быть скомпилировано, безусловно, должна быть какая-то комбинация флагов GCC, которая приведет к компиляции test.c
. Файл проприетарного драйвера .c
включает оба этих файла среди многих других, но их достаточно, чтобы продемонстрировать мою проблему.
eyes=(
-I/usr/src/linux-headers-5.4.0-21/include # for linux/module.h
-I/usr/src/linux-headers-5.4.0-21/arch/x86/include # for asm/linkage.h
)
gcc -c "${eyes[@]}" test.c
приводит к
In file included from /usr/src/linux-headers-5.4.0-21/include/linux/seqlock.h:36,
from /usr/src/linux-headers-5.4.0-21/include/linux/time.h:6,
from /usr/src/linux-headers-5.4.0-21/include/linux/stat.h:19,
from /usr/src/linux-headers-5.4.0-21/include/linux/module.h:10,
from test.c:2:
/usr/src/linux-headers-5.4.0-21/include/linux/spinlock.h:60:10: fatal error: asm/mmiowb.h: No such file or directory
60 | #include <asm/mmiowb.h>
| ^~~~~~~~~~~~~~
dpkg -L linux-headers-5.4.0-21 | grep mmiowb.h
показывает этот файл в include / asm-generic
, а также в arch / {ia64, mips, powerpc, riscv, sh} / include / asm
. Настроив мой -I
, чтобы включить один из них, ошибка переместится в:
In file included from /usr/src/linux-headers-5.4.0-21/include/linux/mmzone.h:19,
from /usr/src/linux-headers-5.4.0-21/include/linux/gfp.h:6,
from /usr/src/linux-headers-5.4.0-21/include/linux/umh.h:4,
from /usr/src/linux-headers-5.4.0-21/include/linux/kmod.h:9,
from /usr/src/linux-headers-5.4.0-21/include/linux/module.h:13,
from test.c:2:
/usr/src/linux-headers-5.4.0-21/include/linux/page-flags-layout.h:6:10: fatal error: generated/bounds.h: No such file or directory
6 | #include <generated/bounds.h>
| ^~~~~~~~~~~~~~~~~~~~
и этот файл просто не существует в моей системе, но есть файл с именем /usr/src/linux-headers-5.4.0-21/KBuild
, который выглядит как make-файл, который его создал, хотя я не могу понять, как вызвать этот make-файл.
Как я могу продолжить? Есть ли команда, которую мне нужно выполнить после установки linux-headers - *
для заполнения сгенерированных
папок? Есть ли где-нибудь в Интернете руководство по подобным вещам?
Ядро Linux имеет собственную систему сборки, основанную на make
, которая генерирует правильные опции gcc
для успешной компиляции компонентов и модулей ядра.
Файл Kbuild
, включенный во внешние модули ядра, предназначен для использования с этой системой сборки ядра. Кроме того, внешние модули ядра также должны включать в себя Makefile
, который вызывает систему сборки ядра. Минимальный Makefile
для внешнего модуля может выглядеть следующим образом:
obj-m = foo.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
Как видите, основной Makefile
системы сборки ядра фактически находится в папке /lib /modules/$(KVERSION)/build
, где $(KVERSION)
— номер версии ядра, для которого вы собираете. Если вам интересно, вы можете попытаться проследить, что делает сетка Makefiles и с каким набором параметров она вызывает gcc
.