您的位置:首页 > 运维架构 > Linux

Linux内核N日游之内核链表

2010-11-16 13:21 246 查看
内核N日游之内核链表

#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("Jackhenry");
MODULE_DESCRIPTION("List module");
MODULE_ALIAS("a kernel list sample");

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(void)
{
int i = 0;

INIT_LIST_HEAD(&student_list);

pstudent = kmalloc(sizeof(struct student)*5,GFP_KERNEL);
memset(pstudent,0,sizeof(struct student)*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: %s/n",tmp_student->num,tmp_student->name);
}

return 0;
}

void mylist_exit(void)
{
int i ;
for(i=0;i<5;i++)
{
list_del(&(pstudent[i].list));
}

kfree(pstudent);
}

module_init(mylist_init);
module_exit(mylist_exit);


在内核中加载insmod&查看模块lsmod&卸载模块rmmod:



附加实验:在mylist_exit函数中,将for(i=0;i<5;i++)换成 list_for_each来遍历删除结点,观察要发生的现象,并考虑解决办法?

修改后的模块为kernel_list.ko

先加载insmod kernel_list.ko:



加载SUCCESS!

然后卸载rmmod kernel_list



如上图所示,出现段错误.加载失败!用lsmod查看,发现该内核模块未被卸载!

附上include/linux/list.h头文件中的部分定义:

list_head结构体的定义:

struct list_head
{
struct list_head *next, *prev;
};


list_entry的定义:

/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) /
container_of(ptr, type, member)


container_of在内核中的定义:

#ifndef container_of
#define container_of(obj, type, memb) /
((type *)(((char *)obj) - offset_of(type, memb)))
#endif


思考:将内核链表在应用程序中实现?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: