加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱故事小小网_铜陵站长网 (http://www.0562zz.com/)- 视频终端、云渲染、应用安全、数据安全、安全管理!
当前位置: 首页 > 教程 > 正文

Linux设备驱动工程师之路——内核链表的实施

发布时间:2021-11-25 16:21:23 所属栏目:教程 来源:互联网
导读:一、重要知识点 1.内核链表和普通链表的区别 内核链表是一个双向链表,但是与普通的双向链表又有所区别。内核链表中的链表元素不与特定类型相关,具有通用性。 我们先来看一幅图 kernel list展示的是内核链表的结构,normallist展示的是普通链表的结构。head

一、重要知识点
 
1.内核链表和普通链表的区别
 
内核链表是一个双向链表,但是与普通的双向链表又有所区别。内核链表中的链表元素不与特定类型相关,具有通用性。
 
我们先来看一幅图
 
        
 
kernel list展示的是内核链表的结构,normallist展示的是普通链表的结构。head是链表头,p1,p2,p3是链表节点。从图中可以看出普通链表的p1的next指针是指向的结构体p2的地址,p2的pre指针指向p1结构体的地址。而内核链表的p1的next指向的是p2结构体中包含pre和next部分的地址,的p2的pre指向的是p1结构体中包含pre和next部分的地址。依此类推,这就是区别。内核结构元素不与特定类型结构相关,任何结构体都可通过内核的添加成为链表中的节点。
 
2.内核链表的具体操作
 
         链表数据结构的定义
 
         structlist_head
 
         {
 
struct list_head *next, *prev;
}
 
         初始化链表头
 
         INIT_LIST_HEAD(list_head*head)
 
         插入节点
 
         list_add(structlist_head *new, struct list_head *head)
 
         list_add_tail(structlist_head *new, sturct list_head *head)
 
第一个函数在head后面插入一个节点
 
第二个函数在链表尾部插入一个节点
 
删除节点:
 
list_del(structlist_head *entry)
 
提取数据结构:
 
list_entry(ptr,type, member)
 
ptr为已知节点指针ptr,type为节点结构体类型,member为节点指针的type结构体中的名字。返回type结构体的指针。
 
遍历:
 
list for each(structlist_head *ops, struct list_head *head)
 
从head开始遍历每个节点,节点指针保存在ops里面。
 
二、实例
 
#include <linux/kernel.h>  
#include <linux/module.h>  
#include <linux/init.h>  
#include <linux/slab.h>  
#include <linux/list.h>  
   
MODULE_LICENSE("GPL");  
MODULE_AUTHOR("David Xie");  
MODULE_DESCRIPTION("ListModule");  
MODULE_ALIAS("List module");  
   
struct student  
{  
   char name[100];  
   int num;  
   struct list_head list;  
};  
   
struct student *pstudent;  
struct student *tmp_student;  
struct list_head student_list;  
struct list_head *pos;  
   
int mylist_init()  
{  
         inti = 0;  
          
         INIT_LIST_HEAD(&student_list);  
          
         pstudent= kmalloc(sizeof(struct student)*5,GFP_KERNEL);  
         memset(pstudent,0,sizeof(structstudent)*5);  
          
         for(i=0;i<5;i++)  
         {  
                sprintf(pstudent[i].name,"Student%d",i+1);  
                   pstudent[i].num= i+1;  
                   list_add(&(pstudent[i].list), &student_list);  
         }  
          
          
         list_for_each(pos,&student_list)  
         {  
                   tmp_student= list_entry(pos,struct student,list);  
                   printk("<0>student%d name: %sn",tmp_student->num,tmp_student->name);  
         }  
          
         return0;  
}  
   
   
void mylist_exit()  
{         
         inti ;  
         for(i=0;i<5;i++)  
         {  
                   list_del(&(pstudent[i].list));      
         }  
          
         kfree(pstudent);  
}  
   
module_init(mylist_init);  
module_exit(mylist_exit);  

(编辑:我爱故事小小网_铜陵站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读