【问题标题】:Compiling Linux kernel module using gcc with kernel header files使用带有内核头文件的 gcc 编译 Linux 内核模块
【发布时间】:2017-01-18 23:04:59
【问题描述】:

我有一台带有内核 A 头文件的 Linux 机器。 我想在内核 B 当前运行时使用带有内核 A 的 GCC 编译 C 程序。

我该怎么做?如何检查它是否有效?

【问题讨论】:

  • 你的 C 程序是内核模块还是用户空间程序?您可以使用gcc-I 选项。
  • 内核模块。我将'-I/usr/src/linux-headers-2.6.32-38-server/include/'选项添加到我的Makefile中,但之后系统继续编译过程,这个更改是否足够?
  • 如果它是一个内核模块,您必须使用内核源目录中的内核 Makefile。你为什么使用gcc?发布您用于构建内核模块的 Makefile。
  • 我的项目中还有用户空间程序。 iqstatic 解决了我的问题。

标签: gcc linux-kernel


【解决方案1】:

这是需要深入研究的附加信息。发布 2.6 版本,正如其他回复中提到的,Makefile 负责大部分 Linux 内核模块编译步骤。然而,它的核心仍然是 GCC,它就是这样做的:(你也可以在没有 Makefile 的情况下编译它)

以下 GCC 选项是必要的:

  1. -isystem /lib/modules/`uname -r`/build/include:您必须使用正在编译的内核的内核头文件。使用 默认的 /usr/include/linux 不起作用。

  2. -D__KERNEL__:定义此符号告诉头文件代码将在内核模式下运行,而不是作为用户进程。

  3. -DMODULE:此符号告诉头文件为内核模块提供适当的定义。

gcc -DMODULE -D__KERNEL__ -isystem /lib/modules/$(uname -r)/build/include -c hello.c -o hello.ko

【讨论】:

  • 我有linkage.h:8:10: fatal error: asm/linkage.h: No such file or directory
【解决方案2】:

为了编译内核模块,最好使用驻留在内核源目录中的内核 Makefile。您可以使用以下 make 命令:

make -C $(KERNEL_SOURCE_DIR) M=`pwd` modules

否则,您可以选择像这样编写自己的 Makefile:

KERNEL_DIR := /lib/modules/$(shell uname -r)/build

obj-m := test.o

driver:
    make -C $(KERNEL_DIR) M=`pwd` modules

clean:
    make -C $(KERNEL_DIR) M=`pwd` clean

在这里,我使用了 KERNEL_DIR 作为/lib/modules/$(shell uname -r)/build,它使用了当前正在运行的内核的内核头文件。但是,您可以使用要编译模块的内核源目录的路径。

This 展示了如何使用 gcc 来实现。

【讨论】:

    猜你喜欢
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2011-01-21
    相关资源
    最近更新 更多