使用带有内核头文件的gcc编译Linux内核模块

8

我有一台Linux机器,它的内核是A版本,并且有相应的头文件。

我想使用GCC编译一个C程序,该程序需要在内核A下运行,但是当前正在运行的是内核B。

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


你的C程序是内核模块还是用户空间程序?你可以使用gcc-I选项。 - iqstatic
内核模块。我在我的Makefile中添加了“-I /usr/src/linux-headers-2.6.32-38-server/include/”选项,但是之后系统继续进行编译过程,这个更改足够吗? - kobi
如果它是内核模块,你必须使用内核源目录中存在的内核Makefile。为什么要使用gcc?发布你正在使用的构建内核模块的Makefile。 - iqstatic
我在项目中还有一个用户空间程序。 iqstatic解决了我的问题。 - kobi
2个回答

10

这是进一步了解的补充信息。在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


1
我遇到了 linkage.h:8:10: 致命错误: asm/linkage.h: 没有那个文件或目录 的问题。 - TigerTV.ru
这里也是。有人想出了解决方案吗? - zakaria amine

5
为了编译内核模块,最好使用驻留在内核源目录中的内核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

在这里,我使用了/lib/modules/$(shell uname -r)/build作为KERNEL_DIR,它使用当前正在运行的内核的内核头文件。但是,您可以使用要编译模块的内核源目录的路径。 这个链接展示了如何使用gcc来完成此操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接