1、工具准备
(1) 编译器:GCC 编译器。
(2) 程序调试工具:GDB。
(3) 内核开发文件库:kernel-devel。应当安装与当前系统内核版本一致的 kernel-devel 文件库。可通过 uname -r 指令查看当前系统内核版本。
(4) 编译管理工具:GNU make。
2、示例程序:hello.c
/* hello.c - The simplest kernel module.
*
* Copyright (C) 2001 by Peter Jay Salzman
*
* 08/02/2006 - Updated by Rodrigo Rubira Branco */
/* Kernel Programming */
#define MODULE
#define LINUX
#define __KERNEL__
#include /* Needed by all modules */
#include /* Needed for KERN_ALERT */
int init_module(void)
{
printk("<1>Hello world.\n");
// A non 0 return means init_module failed; module can&#39;t be loaded.
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "Goodbye world.\n");
}
MODULE_LICENSE("GPL");
将上述代码保存为 hello.c。
3、Make
Makefile 文件如下&#xff1a;
obj-m :&#61; hello.o
all :
$(MAKE) -C /lib/modules/3.7.10-1.28-default/build M&#61;$(PWD) modules
clean:
$(MAKE) -C /lib/modules/3.7.10-1.28-default/build M&#61;$(PWD) clean注意上述脚本中的 /lib/modules/3.7.10-1.28-default/build&#xff0c;需要根据 kernel-devel 安装后生成的实际目录名进行更改。将上述脚本保存在 hello.c 同一目录下&#xff0c;文件名为 Makefile。然后在该目录下执行 make 指令&#xff0c;将在当前目录下生成 hello.ko 文件。
4、向内核插入、删除模块
(1) 插入模块
在 root 权限下执行如下指令&#xff1a;insmod ./hello.ko
上述指令将触发 hello.c 文件中的 init_module 函数&#xff0c;通过 printk 函数打印字符串 "Hello world."
(2) 删除模块
在 root 权限下执行如下指令&#xff1a;rmmod ./hello.ko
上述指令将触发 hello.c 文件中的 clean_module 函数&#xff0c;通过 printk 函数打印字符串 "Goodbye world."
5、为何插入、删除模块时&#xff0c;未在终端上打印字符串&#xff1f;
(1) 可能与 printk 的日志级别设置有关&#xff0c;请查询 printk 的相关文档。可在 root 权限下执行如下指令&#xff1a;
echo 8 > /proc/sys/kernel/printk
将终端日志级别设为最低&#xff0c;然后重新进行内核模块的插入、删除操作。
(2) printk 函数可能无法打印到 konsole 等虚拟终端。可尝试通过 dmesg 指令查询日志&#xff0c;或者查看 /var/log/messages 文件中的日志记录。
(3) 尝试 Ctrl-Alt-F2 进入 TTY 终端&#xff0c;在 root 权限下重新进行内核模块的插入、删除操作。