前面我们详细介绍了如何实现内核链表,实际上内核中已经为我们实现了内核链表,给我提供了一些操作内核链表的API,接下来我们将在驱动模块中使用内核链表。
首先我们了解几个常用的API:
以下是代码实例(由于前面已经对内核链表做了详解,在此不再赘述):
#include <linux/init.h>
#include <linux/module.h>
#include <asm/current.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/slab.h>
#define N 32
struct student{ //学生信息结构体
char name[N];
int id;
float score;
struct list_head list; //内核链表字段
};
struct student *stup;
struct student *tmp_stup;
struct list_head stu_list;
struct list_head *pos;
static __init int hello_init(void)//模块加载入口
{
int i,ret;
printk("%s:%d pid=%d\n",__func__,__LINE__,current->pid);//打印函数信息用于调试
//初始化内核链表 学生表
INIT_LIST_HEAD(&stu_list);
//为学生信息结构体分配空间
stup=kmalloc(sizeof(struct student)*5,GFP_KERNEL);
if(IS_ERR(stup)){ //判断是否为NULL
printk("fail to kmalloc");
ret=PTR_ERR(stup); //得到错误信息返回
goto ERR1;
};
memset(stup,0,sizeof(struct student)*5);//清空结构体
for(i=0;i<5;i++){ //赋值 并插入链表
sprintf(stup[i].name,"stuent%d",i);
stup[i].id=i;
//stup[i].score=i*10;
//list_add(&(stup[i].list),&stu_list);
list_add_tail(&(stup[i].list),&stu_list);
};
list_for_each(pos,&stu_list){ //遍历学生信息
tmp_stup=list_entry(pos,struct student,list);//链接因子得到对象
printk("id=%d name=%s \n",tmp_stup->id,tmp_stup->name);
};
return 0;
ERR1:
return ret;
}
static __exit void hello_exit(void)//模块卸载入口
{ int i;
printk("%s:%d pid=%d\n",__func__,__LINE__,current->pid);
for(i=0;i<5;i++){
list_del(&(stup[i].list)); //删除节点
};
kfree(stup);//释放分配的学生结构体空间
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");