Linux内核模块
在这一部分中,我学会了如何创建,加载与卸载内核模块,首先根据书上的代码编写好simple.c文件和Makefile文件,接着使用make编译,产生如下文件:
接着使用加载模块命令:sudo insmod simple.ko 将simple模块加载,并使用lsmod检查确定simple已经被加载:
使用dmesg命令检查模块中的“Loading Module”消息是否被输出。
使用命令sudo rmmod simple删除刚刚加载的模块并检查日志缓冲区:
及时使用sudo dmesg -c命令清理缓冲区:
第二部分
创建birthday结构体并创建第一个元素将其内容输出到内核日志缓冲区中。
添加其他的四个元素并使用list_for_each_entry()输出:
在模块退出时,删除链表元素,并返回之前分配的内存,以防止内存泄漏。其中使用list_empty()函数判断是否将链表元素删除。
源代码如下
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/slab.h>
typedef struct birthday{
int day;
int month;
int year;
struct list_head list;
}birthday;
static LIST_HEAD(birthday_list);
/*This function is called to create a new node*/
birthday* list_cret(int day,int month,int year)
{
//printk("The list_cret function has been used.");
struct birthday *person;
person=kmalloc(sizeof(*person),GFP_KERNEL);
person->day=day;
person->month=month;
person->year=year;
INIT_LIST_HEAD(&person->list);
return person;
}
/*This function is called when the module is loaded.*/
int simple_init(void)
{
printk(KERN_INFO "Loading Module\n");
//test for list
birthday *p1=list_cret(2,8,1995);
list_add_tail(&p1->list,&birthday_list);//add to the list
birthday *p2=list_cret(3,9,1996);
list_add_tail(&p2->list,&birthday_list);//add to the list
birthday *p3=list_cret(4,10,1997);
list_add_tail(&p3->list,&birthday_list);//add to the list
birthday *p4=list_cret(5,11,1998);
list_add_tail(&p4->list,&birthday_list);//add to the list
birthday *p5=list_cret(6,12,1999);
list_add_tail(&p5->list,&birthday_list);//add to the list
//Traversal list
struct birthday *ptr;
list_for_each_entry(ptr,&birthday_list,list){
printk(KERN_INFO "%d--%d--%d\n",ptr->year,ptr->month,ptr->day);
}
return 0;
}
/*This function is called when the module is removed.*/
void simple_exit(void)
{
printk(KERN_INFO "Removing Module\n");
//delete the list node
struct birthday *ptr,*next;
list_for_each_entry_safe(ptr,next,&birthday_list,list){
list_del(&ptr->list);
kfree(ptr);//free the memeory
}
//the list is empty,the action is success
if(list_empty(&birthday_list)) printk(KERN_INFO "delete success\n");
}
/*Macros for registering module entry and exit points.*/
module_init(simple_init);
module_exit(simple_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("SGG");