linux使用内核创建链表代码示例(完整代码)

该博客展示了如何在Linux内核环境中使用链表数据结构。作者创建了一个生日结构体链表,包含了五个元素,并通过内核日志输出其内容。在模块退出时,链表被反向遍历并逐个删除,释放内存。这演示了Linux内核模块的生命周期管理和链表操作技巧。

操作系统使用linux的内核代码的具体例子
目标:创建一个birthday结构体,以链表形式连起来,顺序输出并倒置后删除
注:没有使用for结构体是不支持普通for循环结构,会自动报错出来的

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/types.h>
/*
In the module entry point, create a linked list containing five struct birthday
elements. Traverse the linked list and output its contents to the kernel log buffer.
Invoke the dmesg command to ensure the list is properly constructed once the
kernel module has been loaded.
In the module exit point, delete the elements from the linked list and return
the free memory back to the kernel. Again, invoke the dmesg command to check
that the list has been removed once the kernel module has been unloaded.
*/

struct birthday{
       int day;
       int month;
       int year;
       struct list_head list;
};


int my_init(void)
{
       printk(KERN_INFO "Loading Module\n");

       static LIST_HEAD(birthday_list);
       struct birthday *person;

       
       person = kmalloc(sizeof(*person),GFP_KERNEL);
       person->day=2;
       person->month=1;
       person->year=1995;
       INIT_LIST_HEAD(&person->list);
       list_add_tail(&person->list,&birthday_list);
       
       person = kmalloc(sizeof(*person),GFP_KERNEL);
              person->day=2;
              person->month=2;
              person->year=1995;
              INIT_LIST_HEAD(&person->list);
              list_add_tail(&person->list,&birthday_list);

	person = kmalloc(sizeof(*person),GFP_KERNEL);
              person->day=2;
              person->month=3;
              person->year=1995;
              INIT_LIST_HEAD(&person->list);
              list_add_tail(&person->list,&birthday_list);
            
       person = kmalloc(sizeof(*person),GFP_KERNEL);
              person->day=2;
              person->month=4;
              person->year=1995;
              INIT_LIST_HEAD(&person->list);
              list_add_tail(&person->list,&birthday_list);
              
              person = kmalloc(sizeof(*person),GFP_KERNEL);
              person->day=2;
              person->month=4;
              person->year=1995;
              INIT_LIST_HEAD(&person->list);
              list_add_tail(&person->list,&birthday_list);
       struct birthday *ptr;

       list_for_each_entry(ptr,&birthday_list,list){

              printk(KERN_INFO "year:%d month:%d day:%d\n",ptr->year,ptr->month,ptr->day);
       }
       return 0;
}


void my_exit(void) {

       printk(KERN_INFO "Removing Module\n");

       static LIST_HEAD(birthday_list);
       struct birthday *ptr, *next;
       list_for_each_entry_safe(ptr, next, &birthday_list, list){

              list_del(&ptr->list);
              kfree(ptr);
   }
}


module_init( my_init );
module_exit( my_exit );

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("My Module");
MODULE_AUTHOR("SGG");
一、linux内核链表 1、普通链表的数据区域的局限性 之前定义数据区域时直接int data,我们认为我们的链表中需要存储的是一个int类型的数。但是实际上现实编程中链接中的节点不可能这么简单,而是多种多样的。 一般实际项目中的链表,节点中存储的数据其实是一个结构体,这个结构体中包含若干的成员,这些成员加起来构成了我们的节点数据区域。 2、一般性解决思路:即把数据区封装为一个结构体 (1)因为链表实际解决的问题是多种多样的,所以内部数据区域的结构体构成也是多种多样的。 这样也导致了不同程序当中的链表总体构成是多种多样的。 我们无法通过一套泛性的、普遍适用的操作函数来访问所有的链表,意味着我们设计一个链表就得写一套链表的操作函数(节点创建、插入、删除、遍历……)。 (2)实际上深层次分析会发现 不同的链表虽然这些方法不能通用需要单独写,但是实际上内部的思路和方法是相同的,只是函数的局部地区有不同。 实际上链表操作是相同的,而涉及到数据区域的操作就有不同 (3)问题 能不能有一种办法把所有链表中操作方法里共同的部分提取出来用一套标准方法实现,然后把不同的部分留着让具体链表的实现者自己去处理。 3、内核链表的设计思路 (1)内核链表中实现一个纯链表的封装,以及纯链表的各种操作函数 纯链表就是没有数据区域,只有前后向指针; 各种操作函数是节点创建、插入、删除、遍历。 这个纯链表本身自己没有任何用处,它的用法是给我们具体链表作为核心来调用。 4、list.h文件简介 (1)内核中核心纯链表的实现在include/linux/list.h文件中 (2)list.h中就是一个纯链表完整封装,包含节点定义和各种链表操作方法。 二、内核链表的基本算法和使用简介 1、内核链表的节点创建、删除、遍历等 2、内核链表使用实践 (1)问题:内核链表只有纯链表,没有数据区域,怎么使用使用方法是将内核链表作为将来整个数据结构的结构体的一个成员内嵌进去。类似于公司收购,实现被收购公司的功能。 这里面要借助container_of宏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值