原文:
idr在linux核心中指的就是整數id管理機制,從本質上來說,這就是一種將整數id號和特定指標關聯在一起的機制。這個機制最早是在2023年2月加入核心的,當時是作為posix定時器的乙個補丁。現在,在核心的很多地方都可以找到idr的身影。
idr機制適用在那些需要把某個整數和特定指標關聯在一起的地方。舉個例子,在i2c匯流排中,每個裝置都有自己的位址,要想在匯流排上找到特定的裝置,就必須要先傳送該裝置的位址。如果我們的pc是乙個i2c匯流排上的主節點,那麼要訪問匯流排上的其他裝置,首先要知道他們的id號,同時要在pc的驅動程式中建立乙個用於描述該裝置的結構體。
此時,問題來了,我們怎麼才能將這個裝置的id號和他的裝置結構體聯絡起來呢?最簡單的方法當然是通過陣列進行索引,但如果id號的範圍很大(比如32位的id號),則用陣列索引顯然不可能;第二種方法是用鍊錶,但如果網路中實際存在的裝置較多,則鍊錶的查詢效率會很低。遇到這種清況,我們就可以採用idr機制,該機制內部採用radix樹實現,可以很方便地將整數和指標關聯起來,並且具有很高的搜尋效率。
(1)獲得idr
要在**中使用idr,首先要包括。接下來,我們要在**中分配idr結構體,並初始化:
void idr_init(struct idr *idp);
其中idr定義如下:
struct idr ;
/* idr是idr機制的核心結構體 */
(2)為idr分配記憶體
int idr_pre_get(struct idr *idp, unsigned int gfp_mask);
每次通過idr獲得id號之前,需要先分配記憶體。
返回0表示錯誤,非零值代表正常
(3)分配id號並將id號和指標關聯
int idr_get_new(struct idr *idp, void *ptr, int *id);
int idr_get_new_above(struct idr *idp, void *ptr, int start_id, int *id);
idp: 之前通過idr_init初始化的idr指標
id: 由核心自動分配的id號
ptr: 和id號相關聯的指標
start_id: 起始id號。核心在分配id號時,會從start_id開始。如果為i2c節點分配id號,可以將裝置位址作為start_id
函式呼叫正常返回0,如果沒有id可以分配,則返回-enospc
在實際中,上述函式常常採用如下方式使用:
again:
if (idr_pre_get(&my_idr, gfp_kernel) == 0)
spin_lock(&my_lock);
result = idr_get_new(&my_idr, &target, &id);
if (result == -eagain)
(4)通過id號搜尋對應的指標
void *idr_find(struct idr *idp, int id);
返回值是和給定id相關聯的指標,如果沒有,則返回null
(5)刪除id
要刪除乙個id,使用:
void idr_remove(struct idr *idp, int id);
通過上面這些方法,核心**可以為子裝置,inode生成對應的id號。這些函式都定義在中
下面,我們通過分析i2c協議的核心**,來看一看idr機制的實際應用:
.../* idr標頭檔案 */
...static define_idr(i2c_adapter_idr); /* 宣告idr */
.../*
採用動態匯流排號宣告並註冊乙個i2c介面卡(adapter),可睡眠
針對匯流排號可動態指定的裝置,如基於usb的i2c裝置或pci卡
*/int i2c_add_adapter(struct i2c_adapter *adapter)
adapter->nr = id;
return i2c_register_adapter(adapter);
}export_symbol(i2c_add_adapter);
/* 採用靜態匯流排號宣告並註冊乙個i2c介面卡(adapter)
*/int i2c_add_numbered_adapter(struct i2c_adapter *adap)
mutex_unlock(&core_lists);
if (status == -eagain)
goto retry;
if (status == 0)
status = i2c_register_adapter(adap);
return status;
}export_symbol_gpl(i2c_add_numbered_adapter);
/* 登出乙個i2c介面卡 */
int i2c_del_adapter(struct i2c_adapter *adap)
export_symbol(i2c_del_adapter);
/* 通過id號獲得i2c_adapter裝置結構體 */
struct i2c_adapter* i2c_get_adapter(int id)
export_symbol(i2c_get_adapter);
linux核心原始碼
1.機器當前使用的核心版本 apuser jianzhangubtnb uname a linux jianzhangubtnb 3.2.0 23 generic 36 ubuntu smp tue apr 10 20 39 51 utc 2012 x86 64 x86 64 x86 64 gnu ...
linux核心的idr學習 一
今天在看mtd驅動的時候發現idr,之後網上找了很多資料,其中我覺得這份參考資料比較好 idr主要是實現id與資料結構位址的繫結,一般是結構體的位址.如果位址比較少的情況下,可以直接定義乙個全域性的指標陣列,以陣列的下標作為id與位址對應.但是當位址數量很大的時候,固定的指標陣列無法滿足我們的需求,...
Linux核心原始碼目錄
linux核心原始碼目錄 1 arch architecture的縮寫,意思是架構,九鼎在做移植的時候就刪掉了。其他的目錄都跟你沒有任何的關係,所以你完全可以把他們刪除。2 block 英文是塊的意思,表示是塊裝置。以塊 多個位元組組成的整體,以塊為單位來整體訪問 比如說我們的sd卡,inand n...