内核模块的结构:
头文件声明。头文件module.h和init.h是必不可少的。module.h是加载模块所需要的函数和符号定义;init.h中包含初始化和清楚函数的定义。如果加载是允许用
户传递参数,模块还应包括moduleparam.h。
模块许可声明。用MODULE_LICENSE宏声明此模块的许可证。
初始化和清理函数声明。内核模块必须调用module_init和module_exit去注册和清理函数。
内核的添加删除:
insmod:该命令调用insmod程序,把需要加载的模块以目标代码形式加载进内核中。 sudo insmod modulename
rmmod:调用rmmod命令,将已经加载到内核的模块从内核中卸载。 sudo rmmod modulename
dmesg:查看内核系统日志
lsmod:该命令显示已加载到内核的所有模块信息
内核模块的编译与加载:
头文件声明。头文件module.h和init.h是必不可少的。module.h是加载模块所需要的函数和符号定义;init.h中包含初始化和清楚函数的定义。如果加载是允许用
户传递参数,模块还应包括moduleparam.h。
模块许可声明。用MODULE_LICENSE宏声明此模块的许可证。
初始化和清理函数声明。内核模块必须调用module_init和module_exit去注册和清理函数。
内核的添加删除:
insmod:该命令调用insmod程序,把需要加载的模块以目标代码形式加载进内核中。 sudo insmod modulename
rmmod:调用rmmod命令,将已经加载到内核的模块从内核中卸载。 sudo rmmod modulename
dmesg:查看内核系统日志
lsmod:该命令显示已加载到内核的所有模块信息
内核模块的编译与加载:
首先写一个Makefile文件。代码如下
obj-m += hello.o #由此目标文件生成模块
CURRENT_PATH := $(shell pwd) #当前所在的路径
LINUX_KERNEL := $(shell uname -r) #内核的版本号
#内核代码所在的路径
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)
#编译
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
#清除编译生成的文件
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
通过内核模块显示进程控制块信息
代码如下
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/proc_fs.h>
#include<asm/uaccess.h>
#include<linux/moduleparam.h>
#include<linux/sched.h>
MODULE_LICENSE("GPL");
static int num = -1;
module_param(num, int,S_IRUGO);
static int __init exp_init(void)
{
struct task_struct *p = NULL;
for_each_process(p){
if(num == 0)
break;
printk("pid = %d, path = %s\n", p->pid, p->comm);
num--;
}
return 0;
}
static void __exit exp_exit(void)
{
printk("clear\n");
}
module_init(exp_init); /*进入内核的时候,调用exp_init */
module_exit(exp_exit); /*离开内核的时候,调用exp_exit */
操作指令如下:
$make //编译
$sudo insmod hello.ko //添加内核模块
$dmesg //显示内核系统日志信息
$lsmod // 显示已加载到内核的模块信息
$sudo rmmod hello //删除内核模块