链表数据结构的定义非常简洁:
struct list_head { struct list_head *next, *prev; };
list_head结构包括两个指向list_head结构的指针prev和next。该内核链表具备双链表功能。通常它都组织成双循环链表,这里的list_head没有数据域。在Linux内核链表中,不是在链表结构中包括数据,而是在数据结构中包括链表节点。以下是一个简单的内核模块的样例。包括了对链表进行插入、删除、遍历的一些函数:
list.c:
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/string.h> #include <linux/spinlock.h> #include <linux/list.h> typedef struct list_test_struct { int num; struct list_head list; }test; struct list_head head_list; rwlock_t list_lock = RW_LOCK_UNLOCKED; //定义读写锁,操作前加锁,操作后解锁 void creat_list(void) { test *s = NULL; int i = 0; for (i = 0; i < 10; i++) { s = (test *)kmalloc(sizeof(test), GFP_ATOMIC); if (!s) return ; s->num = i; write_lock(&list_lock); list_add_tail(&(s->list), &head_list); //加入节点 write_unlock(&list_lock); } } void del_data(void) { test *s; struct list_head *p; write_lock(&list_lock); list_for_each(p, &head_list) //遍历链表 { s = list_entry(p, test, list); if (s->num == 4) { list_del(p); //删除节点 write_unlock(&list_lock); return ; } } write_unlock(&list_lock); } void print_list(void) { test *s; struct list_head *p; read_lock(&list_lock); list_for_each(p, &head_list) { s = list_entry(p, test, list); printk(KERN_INFO"%d ", s->num); } read_unlock(&list_lock); } int list_test_init(void) { INIT_LIST_HEAD(&head_list); creat_list(); print_list(); del_data(); print_list(); return 0; } void list_test_exit(void) { return; } MODULE_LICENSE("GPL"); module_init(list_test_init); module_exit(list_test_exit);Makefile:
obj-m += list.o KERN_DIR = /usr/src/linux-headers-2.6.32-33-generic all: make -C $(KERN_DIR) M=`pwd` modules clean: make -C $(KERN_DIR) M=`pwd` modules clean rm -rf modules.order
make后生成module,获取超级用户权限后
insmod list.ko
然后输入命令:cat var/log/messages
printk信息打印:
Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274551] 0 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274553] 1 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274555] 2 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274555] 3 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274556] 4 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274557] 5 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274558] 6 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274559] 7 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274559] 8 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274560] 9 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274561] 0 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274562] 1 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274563] 2 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274564] 3 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274564] 5 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274565] 6 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274566] 7 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274567] 8 Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274568] 9第二次输出发现节点4被删除。在这里实现:
list_for_each(p, &head_list) //遍历链表 { s = list_entry(p, test, list); if (s->num == 4) { list_del(p); //删除节点 write_unlock(&list_lock); return ; } }