Linuxデバイスドライバエンジニアの道-カーネルチェーンテーブルの使用
Linuxデバイスドライバエンジニアの道-カーネルチェーンテーブルの使用
K-Style
転載は衡陽師範学院08電2 K-Styleからhttp://blog.csdn.net/ayangke,QQ:843308498メールボックス:[email protected]
一、重要な知識点
1.カーネルチェーンテーブルと通常のチェーンテーブルの違い
カーネルチェーンテーブルは双方向チェーンテーブルですが、通常の双方向チェーンテーブルとは異なります.カーネルチェーンテーブルのチェーンテーブル要素は、特定のタイプに関連付けられず、汎用性があります.
まず図を見てみましょう
kernel listはカーネルチェーンテーブルの構造を示し,normallistは通常のチェーンテーブルの構造を示した.headはチェーンテーブルヘッダであり、p 1,p 2,p 3はチェーンテーブルノードである.図から、通常のチェーンテーブルのp 1のnextポインタは、構造体p 2を指すアドレスであり、p 2のpreポインタは、p 1構造体を指すアドレスであることがわかる.カーネルチェーンテーブルのp 1のnextは、p 2構造体にpreおよびnext部分を含むアドレスを指し、p 2のpreは、p 1構造体にpreおよびnext部分を含むアドレスを指す.このように押すと、これが違いです.カーネル構造要素は特定のタイプの構造に関連付けられず、どの構造体もカーネルの追加によってチェーンテーブルのノードになります.
2.カーネルチェーンテーブルの具体的な操作
チェーンテーブルデータ構造の定義
structlist_head
{
struct list_head *next, *prev; }
チェーンヘッダの初期化
INIT_LIST_HEAD(list_head *head)
ノードの挿入
list_add(struct list_head *new, struct list_head *head)
list_add_tail(struct list_head *new, sturct list_head *head)
最初の関数headの後ろにノードを挿入
2番目の関数は、チェーンテーブルの末尾にノードを挿入します.
ノードを削除するには
list_del(struct list_head *entry)
データ構造の抽出:
list_entry(ptr,type, member)
ptrは既知のノードポインタptr,typeはノード構造体タイプ,memberはノードポインタのtype構造体の名前である.type構造体のポインタを返します.
遍歴:
list_for_each(struct list_head *ops, struct list_head *head)
ヘッドから各ノードを巡り、ノードポインタはopsに保存されます.
二、実例
K-Style
転載は衡陽師範学院08電2 K-Styleからhttp://blog.csdn.net/ayangke,QQ:843308498メールボックス:[email protected]
一、重要な知識点
1.カーネルチェーンテーブルと通常のチェーンテーブルの違い
カーネルチェーンテーブルは双方向チェーンテーブルですが、通常の双方向チェーンテーブルとは異なります.カーネルチェーンテーブルのチェーンテーブル要素は、特定のタイプに関連付けられず、汎用性があります.
まず図を見てみましょう
kernel listはカーネルチェーンテーブルの構造を示し,normallistは通常のチェーンテーブルの構造を示した.headはチェーンテーブルヘッダであり、p 1,p 2,p 3はチェーンテーブルノードである.図から、通常のチェーンテーブルのp 1のnextポインタは、構造体p 2を指すアドレスであり、p 2のpreポインタは、p 1構造体を指すアドレスであることがわかる.カーネルチェーンテーブルのp 1のnextは、p 2構造体にpreおよびnext部分を含むアドレスを指し、p 2のpreは、p 1構造体にpreおよびnext部分を含むアドレスを指す.このように押すと、これが違いです.カーネル構造要素は特定のタイプの構造に関連付けられず、どの構造体もカーネルの追加によってチェーンテーブルのノードになります.
2.カーネルチェーンテーブルの具体的な操作
チェーンテーブルデータ構造の定義
structlist_head
{
struct list_head *next, *prev; }
チェーンヘッダの初期化
INIT_LIST_HEAD(list_head *head)
ノードの挿入
list_add(struct list_head *new, struct list_head *head)
list_add_tail(struct list_head *new, sturct list_head *head)
最初の関数headの後ろにノードを挿入
2番目の関数は、チェーンテーブルの末尾にノードを挿入します.
ノードを削除するには
list_del(struct list_head *entry)
データ構造の抽出:
list_entry(ptr,type, member)
ptrは既知のノードポインタptr,typeはノード構造体タイプ,memberはノードポインタのtype構造体の名前である.type構造体のポインタを返します.
遍歴:
list_for_each(struct list_head *ops, struct list_head *head)
ヘッドから各ノードを巡り、ノードポインタはopsに保存されます.
二、実例
#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("David Xie");
MODULE_DESCRIPTION("ListModule");
MODULE_ALIAS("List module");
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()
{
inti = 0;
INIT_LIST_HEAD(&student_list);
pstudent= kmalloc(sizeof(struct student)*5,GFP_KERNEL);
memset(pstudent,0,sizeof(structstudent)*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
",tmp_student->num,tmp_student->name);
}
return0;
}
void mylist_exit()
{
inti ;
for(i=0;i<5;i++)
{
list_del(&(pstudent[i].list));
}
kfree(pstudent);
}
module_init(mylist_init);
module_exit(mylist_exit);