今天在看mtd驅動的時候發現idr, 之後網上找了很多資料, 其中我覺得這份參考資料比較好:
idr主要是實現id與資料結構位址的繫結, 一般是結構體的位址. 如果位址比較少的情況下, 可以直接定義乙個全域性的指標陣列, 以陣列的下標作為id與位址對應. 但是當位址數量很大的時候, 固定的指標陣列無法滿足我們的需求, 而且由於用下標作為id的原因使得id無法根據使用者的需求改變. 那這個時候一般會想到用鍊錶儲存, 這樣id就可以很大, 但是鍊錶很長時, 查詢時間變慢了. idr就是將陣列與鍊錶的優點結合起來. 它利用1個4位元組的32位來對應32個位址, 用1個位圖和32個位址作為1組結構體. 看起來1個結構體只能存放32個資料, 其實結構體裡的32個位址除了可以存放你想放的資料, 也可以分別指向另乙個結構體位址, 這樣就相當於存放32^2個資料了, 如果繼續這樣下去, 就是可以存放32^3, 32^4, 32^5...個資料, 達到32^7個資料就已經超過4位元組可以表示的最大數了. 所以只要7層這樣的結構就足夠了. 然後idr查詢就是按照層索引的方式, 前面說過32個位址作為1組, 每一層的索引只需要5位2進製就可以了, 將4位元組按5位拆開, 得到這樣:
31 30 | 29 28 27 26 25 | 24 23 22 21 20 | 19 18 17 16 15 | 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
比如要查詢id為0x12345678, 分開後就是00 | 01001 | 00011 | 01000 | 10101 | 10011 | 11000, 高層向底層索引, 核心**就寫好的, 不用自己算.
idr的優勢還有, 它有效的利用記憶體, 可以用下面的圖來說明, a是頂層, b與c是下一層, b負責存放0-31的id對應的資料, c負責存放64-95的id對應的資料,而a的ary[1]並沒有開闢空間, 因為並沒有申請32-63的id, 所有不必申請這樣的空間.
linux 核心原始碼中的idr機制
原文 idr在linux核心中指的就是整數id管理機制,從本質上來說,這就是一種將整數id號和特定指標關聯在一起的機制。這個機制最早是在2003年2月加入核心的,當時是作為posix定時器的乙個補丁。現在,在核心的很多地方都可以找到idr的身影。idr機制適用在那些需要把某個整數和特定指標關聯在一起...
Linux 核心list head 學習(一)
在linux核心中,提供了乙個用來建立雙向迴圈鍊錶的結構 list head。雖然linux核心是用c語言寫的,但是list head的引入,使得核心資料結構也可以擁有物件導向的特性,通過使用操作list head 的通用介面很容易實現 的重用,有點類似於c 的繼承機制 希望有機會寫篇文章研究一下c...
Linux核心 驅動學習筆記 一
今天討論到核心啟動階段對外部裝置初始化的過程,於是粗略的看了一下相關 得到以下一些印象 未必正確,希望大家指正 1.對外部裝置初始化 出現的地方應該是 init 程序 bootloader start 彙編 decompress start kernel rest init kernel threa...