内核模块简介
In computing, a loadable kernel module (LKM) is an object file that contains code to extend the running kernel, or so-called base kernel, of an operating system. --wiki
通俗来讲,内核模块就是一个.ko文件,它调用内核API,可以动态加载(即内核运行时加载)进Linux内核,实现部分功能,或提供部分接口函数,常用于驱动注册。
在Linux内核中,内核模块分为不同种类,在不同目录中:
pcmcia - PCMCIA Drivers, for laptops.
kernel/net - network-related Modules (firewall, extra protocols support, etc.)
kernel/drivers - Drivers for various types of Hardware (including network Drivers).
kernel/fs - file-systems support (ext3, vfat, etc.)
kernel/arch - Architecture-specific support (e.g. Drivers to handle features of a a specific CPU or motherboard).
以下介绍Linux内核中最简单的模块编写,内核代码树中的模块编写。
最简单的内核模块编写
(1)准备环境
# 下载头文件 uname -r返回操作系统发行编号
sudo apt-get install build-essential linux-headers-$(uname -r)
# 创建文件夹和所需文件
mkdir work
cd work
touch hello_world.c Makefile
(2)编写hello_world.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void) //模块初始化函数
{
printk(KERN_INFO "hello world!\n");
return 0;
}
module_init(hello_init);
static void __exit hello_exit(void) //模块清理函数
{
printk(KERN_INFO "bye!\n");
}
module_exit(hello_exit);
MODULE_AUTHOR("plot");//作者
MODULE_LICENSE("GPL v2");//模块许可证声明,一般用GPL v2
MODULE_ALIAS("plot_test"); //别名
模块中的init函数和exit函数分别作为模块的入口和出口。在模块装载时的最后阶段,就会调用init函数,用于注册资源,初始化硬件,分配数据结构等。exit函数同理,用于清理操作。
hello_world模块的功能:在模块装载和卸载时,分别打印"hello world!"和"bye!"
(3)编写Makefile
KVERS = $(shell uname -r)
obj-m := helloworld.o
all:
make -C /lib/modules/$(KVERS)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERS)/build M=$(PWD) clean
rm -rf *.ko;
(4)make
make
make过程:
进入/usr/src/linux-headers-xxx(版本号), 通过hello_world.c生成hello_world.o, 通过helloworld.mod.c生成helloworld.mod.o.
链接hello_world.o和helloworld.mod.o生成helloworld.ko. 离开/usr/src/linux-headers-xxx(版本号).
make结果:生成helloworld.ko文件
(5)检验ko文件正确性(option)
file helloworld.ko
# 查看输出的文件为x86-64的ELF文件即成功
modinfo helloworld.ko
# 用于查看ko文件信息
(6)加载模块
sudo insmod helloworld.ko
# insmod xxx.ko 装载xxx.ko模块
(7)查看模块是否被加载
lsmod | grep helloworld
# lsmod 查看当前内核已装载的模块
(8)查看内核日志
sudo dmesg
# 模块装载成功,就可以在内核日志中看到hello world!
(9)卸载模块
sudo rmmod helloworld.ko
内核代码树中的模块编写
待写