文章目录
1.1什么是Kernel Module?
内核模块是可以按需加载或卸载的内核代码,可以不重启系统就扩充内核的功能。例如,一种内核模块叫做设备驱动程序(Device driver),它允许内核访问连接到系统的硬件。如果没有内核模块,我们将必须构建整体内核,并将新功能直接添加到内核映像中。除了具有更大的内核之外,这还有一个缺点,即每次我们想要新功能时都要求我们重建并重新启动内核。
1.2关于Kernel的基本操作
- 显示当前装入的内核模块:
$ lsmod
- 显示模块信息:
$ modinfo module_name
- 显示所有模块的配置信息
$ modprobe -c | less
- 显示某个模块的配置信息:
$ modprobe -c | grep module_name
2.1 Hello World (part1): 最简单的Module
/*
* hello-1.c - The simplest kernel module.
*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void)
{
printk(KERN_INFO "Hello world 1.\n");
/*
* A non 0 return means init_module failed; module can't be loaded.
*/
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
- 头文件中的
#include <linux/module.h> 和 #include <linux/kernel.h>
是所有module都需要添加的头文件。 - Kernel modules必须包含至少两个函数:初始化函数init_module() 和 结束函数cleanup_module()。
- 初始化函数init_module()作用是将module写入kernel。
- 结束函数cleanup_module()作用是清理内存结束module。
- printk()函数:用来记录信息或给出warning,该函数有8个优先级,其中第一个就是KERN_ALERT,如果你不写优先级会被默认为DEFAULT_MESSAGE_LOGLEVEL (在后文中会具体讲解printk函数)
2.2 编译Kernel Modules
- 编写makefile文件 (下文中讲解如何编写makefile文件)
- 在相应的文件目录下使用
make
命令来编译module,如果编译成功,则resulting module code 包含在 <module_name>.ko 文件中 - 通过输入
su -
变成superuser,因此你必须输入密码来操作下一步 - 通过输入
insmod <module_name>.ko
命令,将module插入到Kernel中,任何通过printk()函数将会显示在 /var/log/messages 文件中。查看输出的最好方法是通过输入tail -f /var/log/messages
命令。 - 你可以删除掉已存在的module,通过输入
rmmod <module_name>
命令。
2.2.1如何编写makefile文件
一个基础的makefile文件:
obj-m += hello-1.o
all:
make -C /lib