我正在尝试编译第三方专有驱动程序模块,但失败了。我已经安装了该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
看起来像一个可以创建它的 makefile,尽管我不知道如何调用这个 makefile。
我该怎么做?安装后我需要运行命令linux-headers-*
来填充generated
文件夹吗?网上有这方面的指南吗?
答案1
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)
是您要构建的内核的版本号。如果您好奇,可以尝试追溯那里的 Makefile 网格的作用以及它最终调用了哪些选项集gcc
。