OS之内核简单链表

昨天看完操作系统教材的第二章,今天抽了一点空余时间做一做课后的编程习题。

主要是简单练习一下Linux内核数据结构的链表。

问题非常简单,就是在模块加载的时候生成包含5个节点的双链表,然后,在模块卸载的时候,遍历5个节点,然后释放。

但是之前没怎么接触这类问题,刚开始的时候还是僵持了一下。好在链表管理的接口函数能够找见,对于解决问题真是帮助不小。
/usr/src/linux-2.6.39.4/include/linux/list.h


#include<linux/init.h>
#include<linux/kernel.h>
#include<list.h>
#include<linux/types.h>

#define NODE_NUM 5
#define _FL_ __FILE__, __LINE__

/*
** define the structure
*/
typedef struct birthday
{
	int day;
	int month;
	int year;
	struct list_head list;
} Birthday;

/*
** operation: generate a node
*/
Birthday* generate_node(void);

/*
** initialize a list named birthday_list
** note: the macro function is in linux/list.h
*/
LIST__HEAD(birthday_list);

/*
** This function is called when the module is loaded
*/
int simple_init(void)
{
	long i = 0;
	Birthday *person;
	
	 printk(KERN_INFO "Loading Module\n");
	 
	 for(i = 0; i < NODE_NUM; i++)
	 {
	 	/*
	 	** generate a node firstly
	 	*/
	 	person = generate_node();
	 	
	 	if(NULL == person)
	 		return -1;
	 		
	 	printk(KERN_INFO "person %02ld: born on %4d-%02d-%02d\n",
	 	  (i + 1), person->year, person->month, person->day);
	 	  
	 	/*
	 	** append the node to the list birthday_list
	 	** note: this function is in linux/list.h
	 	*/
	 	list_add_tail(&person->list, &birthday_list);
	}
	
	return 0;
}

/*
** This function is called when the module is removed
*/
void simple_exit(void)
{
	Birthday *ptr, *next;
	long i = 0;
	
	printk(KERN_INFO "Removing Module\n");
	
	list_for_each_entry_safe(ptr, next, &birthday_list, list)
	{
		printk(KERN_INFO "Removing person %02ld: %4d-%02d-%02d\n",
		  (i + 1), ptr->year, ptr->month, ptr->day);
		list_del(&ptr->list);
		kfree(ptr);
		i++;
	}
}

/*
** operation: generate a node
** input:     nothing
** output:   pointer to the struct birthday
*/
Birthday*
generate_node(void)
{
	Birthday *ptr_birth;
	
	ptr_birth = kmalloc(sizeof(*ptr_birth), GFP_KERNEL);
	if(NULL == ptr_birth)
	{
		printk(KERN_INFO "[%s:%d]kmalloc error!\n", _FL_)
		return ptr_birth;
	}
	
	ptr_birth->month = 8;
	ptr_birth->year     = 1995;
	ptr_birth->day      =2;
	
	INIT_LIST_HEAD(&ptr_birth->list);
	
	return ptr_birth;
}

/*
** registering module entry and exit points
*/
module_init(simple_init);
module_exit(simple_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("Jack Liu");

验证:

1.清空系统日志

sudo dmesg -c

2.加载模块

sudo insmod simple.ko


3.卸载模块

sudo rmmod simple



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值