1. 程式人生 > 其它 >Linux 核心雙向連結串列遍歷

Linux 核心雙向連結串列遍歷

技術標籤:Linux 核心連結串列核心

0x01:連結串列
連結串列是Linux核心中非常重要的資料結構,在日常核心驅動開發過程中,往往需要遍歷核心的某個連結串列,核心提供了一套完整的雙鏈表機制,使開發者可以在核心私有資料結構中輕鬆構建雙向連結串列,這裡一起學習以下雙向連結串列的構建和遍歷方法,具體連結串列的知識可以參考文末連結;

0x02:雙向連結串列的構建和遍歷
直接給出程式碼:

//list.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>

/* header of list */
#include <linux/list.h> /* private structure */ struct node { const char *name; struct list_head list; }; /* Initialize a group node structure */ static struct node node0 = { .name = "BiscuitOS_node0", }; static struct node node1 = { .name = "BiscuitOS_node1", }; static
struct node node2 = { .name = "BiscuitOS_node2", }; static struct node node3 = { .name = "BiscuitOS_node3", }; static struct node node4 = { .name = "BiscuitOS_node4", }; static struct node node5 = { .name = "BiscuitOS_node5", }; static struct node node6 = { .
name = "BiscuitOS_node6", }; /* Declaration and implement a bindirect-list */ LIST_HEAD(BiscuitOS_list); static __init int list_entry_init(void) { struct node *np; /* add a new entry on special entry */ list_add_tail(&node0.list, &BiscuitOS_list); list_add_tail(&node1.list, &BiscuitOS_list); list_add_tail(&node2.list, &BiscuitOS_list); list_add_tail(&node3.list, &BiscuitOS_list); list_add_tail(&node4.list, &BiscuitOS_list); list_add_tail(&node5.list, &BiscuitOS_list); list_add_tail(&node6.list, &BiscuitOS_list); printk("BiscuitOS_list:\n"); /* Traverser all node on bindirect-list */ list_for_each_entry(np, &BiscuitOS_list, list) printk("%s\n", np->name); /* get the struct for this entry */ np = list_entry(BiscuitOS_list.next, struct node, list); printk("The entry struct node: %s\n", np->name); /* get the first element from a list */ np = list_first_entry(&BiscuitOS_list, struct node, list); printk("The first entry struct node: %s\n", np->name); return -1; } static void __exit list_entry_exit(void) { printk("Bye bye list_entry\n"); } module_init(list_entry_init); module_exit(list_entry_exit); MODULE_LICENSE("GPL");

Makefile:

obj-m += list.o

KBUILD_CFLAGS+= -g

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

0x03:實際效果

[ 2113.170373] BiscuitOS_list:
[ 2113.170374] BiscuitOS_node0
[ 2113.170374] BiscuitOS_node1
[ 2113.170375] BiscuitOS_node2
[ 2113.170375] BiscuitOS_node3
[ 2113.170375] BiscuitOS_node4
[ 2113.170375] BiscuitOS_node5
[ 2113.170375] BiscuitOS_node6
[ 2113.170376] The entry struct node: BiscuitOS_node0
[ 2113.170376] The first entry struct node: BiscuitOS_node0

0x04:程式碼分析
主要程式碼邏輯為:
1.建立私有資料結構體 struct node;
2.初始化資料結構;
3.宣告連結串列頭,用於後續資料訪問;
4.list_for_each_entry()函式遍歷雙向連結串列,引數1為私有資料結構型別,引數2為頭節點,引數3為struct node list_head;

參考連結:
https://biscuitos.github.io/blog/LIST/