Linux 核心雙向連結串列遍歷
阿新 • • 發佈:2020-12-17
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/