如何针对内核头进行编译?

如何针对内核头进行编译?

我正在尝试编译第三方专有驱动程序模块,但失败了。我已经安装了该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.hinclude/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

相关内容