最近我通过电子邮件收到一个问题:
如何针对已安装或正在运行的 Linux 内核构建 Linux 内核模块?我需要从 kernel.org 安装新的内核源代码树吗?
坦率地说,您不需要新的完整源代码树来针对正在运行的内核编译或构建模块,即不需要分解的源代码树来构建内核驱动程序或模块。下面概述的说明将使开发人员和高级用户受益匪浅。
Linux 内核头文件
这是至关重要的,因为如果您只想编译和安装新硬件(例如无线卡或 SCSI 设备等)的驱动程序。使用以下方法,您将节省时间,因为您不需要编译整个 Linux 内核。
请注意,要使用此 hack,您只需要 Linux 内核头文件,而不是完整的内核源代码树。安装 linux-kernel-headers 软件包,它提供 Linux 内核的标头。这些头文件由 GNU glibc 和其他系统库以及编译模块的已安装头文件使用。使用以下命令安装内核头文件:
# apt-get install kernel-headers-2.6.xx.xx.xx
将 xx.xx 替换为您实际运行的内核版本(例如 2.6.8.-2)和体系结构名称(例如 686/em64t/amd64)。使用 uname -r 命令获取实际的内核版本名称。请注意,上面的命令只会安装内核头文件,而不是整个内核源代码树。
更通用(推荐)和准确的方法如下:
# apt-get install kernel-headers-$(uname -r)
您需要做的就是更改 Makefile 以使用当前的内核构建目录。您可以通过键入以下命令来获取此目录名称:
$ ls -d /lib/modules/$(uname -r)/build
示例输出:
/lib/modules/2.6.27-7-generic/build
假设您有一个名为 hello.c 的 .c 源代码文件。现在在包含 hello.c 程序/文件的目录中创建如下 Makefile:
$ vi Makefile
附加以下文本:
obj-m := 你好.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell 密码) 默认: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) 模块
保存并关闭文件。键入以下命令来构建 hello.ko 模块:
$ make
要加载 Linux 内核模块,请键入命令:
# modprobe hello
一个完整的例子
创建测试目录(您可以在此处下载以下 Makefile 和 .c 文件):
创建 hello.c 内核模块文件:
$ mkdir ~/test
$ cd ~/test
#include <linux/module.h> #include <linux/kernel.h> int init_module ( void ) { printk ( KERN_INFO "init_module() 调用n " ) ; 返回 0 ; } void cleanup_module ( void ) { printk ( KERN_INFO "cleanup_module() 调用n " ) ; }
创建一个生成文件:
obj-m += 你好.o 全部: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) 模块 干净的: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
要构建内核模块,请输入:
$ make
示例输出:
make -C /lib/modules/2.6.27-7-generic/build M=/tmp/test2 模块 make[1]: 进入目录 `/usr/src/linux-headers-2.6.27-7-generic' 抄送 [M] /tmp/test2/hello.o 构建模块,第 2 阶段。 MODPOST 1 模块 抄送/tmp/test2/hello.mod.o LD [M] /tmp/test2/hello.ko make[1]:离开目录`/usr/src/linux-headers-2.6.27-7-generic'
运行 ls 命令查看新构建的内核模块:
$ ls
示例输出:
hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile Module.markers module.order Module.symvers
hello.ko 是内核模块文件。要查看有关模块的信息,请输入:
$ modinfo hello.ko
示例输出:
文件名: 你好.ko 源版本:4F856ABA1F3290D5F81D961 依靠: vermagic:2.6.27-7-通用 SMP mod_unload modversions 586
要加载内核模块,请输入:
$ sudo insmod hello.ko
或者
$ sudo modprobe hello
要列出已安装的 Linux 内核模块,请输入:
要删除 hello Linux 内核模块,请输入:
此模块仅将消息记录到名为 /var/log/messages (/var/log/syslog) 的日志文件中,输入:
示例输出:
$ lsmod
$ lsmod | grep hello
$ rmmod hello
$ tail -f /var/log/messages
11 月 5 日 00:36:36 vivek-desktop 内核:调用了 [52488.923000] init_module() 11 月 5 日 00:36:50 vivek-desktop 内核:调用了 [52503.065252] cleanup_module()
以 zip 格式下载上述示例
- 下载文件
有关详细信息,请参阅有关编译 Linux 内核模块的详细且完整的C 源代码示例。