回到
mm_init()
函式,繼續走,下乙個函式
pgtable_cache_init ()
,不知道咋的,是個空函式,也許是保留著以後開發吧。最後乙個函式是
vmalloc_init()
,來自mm/vmalloc.c
:1088void __init vmalloc_init(void)
1089
1101
1102/* import existing vmlist entries. */
1103for (tmp = vmlist; tmp; tmp = tmp->next)
1110
1111vmap_area_pcpu_hole = vmalloc_end;
1112
1113vmap_initialized = true;
1114}
1090
行,vmap_area
結構,線性區描述符,就是以前的
vm_area_struct
結構,它的字段如下所示:
struct vmap_area ;
核心記憶體管理初始化至此,已經接近尾聲了,回憶一下:(1
)記憶體區的開始部分包含的是對前
896mb ram
進行對映的線性位址。直接對映的物理記憶體末尾所對應的線性位址儲存在
high_memory
全域性變數中。當物理記憶體小於
896mb
,則線性位址
0xc0000000
以後的896mb
與其一一對應;當物理記憶體大於
896mb
而小於4gb
時,只直接對映前
896mb
的位址到
0xc0000000
以後的線性空間,然後把線性空間的其他部分與
896mb
和4gb
物理空間對映起來,稱為動態重對映,這是本博的重點;當物理記憶體大於
4gb,則需要考慮
pae的情況,其他的東東沒什麼區別,我們不做過多的回憶了。(2
)核心的頁表由核心頁全域性目錄變數
維護;pagetable_init()
建立核心頁表項。(3
)記憶體區的結尾部分包含的是固定對映的線性位址,主要用於存放一些常量線性位址,具體檢視「高階記憶體對映
」博文。(4
)從pkmap_base
開始,我們查詢用於高階記憶體頁框的永久核心對映的線性位址,具體檢視「高階記憶體對映
」博文。(5
)其餘的線性位址可以用於非連續記憶體區。在物理記憶體對映的末尾與第乙個記憶體區之間插入乙個大小為
8mb(巨集
vmalloc_offset
)的安全區,目的是為了「捕獲」對記憶體的越界訪問。出於同樣的理由,插入其他
4kb
大小的安全區來隔離非連續的記憶體區。
那麼,vmalloc_init
函式就是為第(5
)項——非連續記憶體區管理進行初始化。非連續記憶體區保留的線性位址空間的起始位址由
vmalloc_start
巨集定義,而末尾位址由
vmalloc_end
巨集定義:
#define vmalloc_start((unsigned long)high_memory + vmalloc_offset)
# define vmalloc_end(pkmap_base - 2 * page_size)
關於非連續記憶體區的相關知識,請查閱部落格「非連續記憶體區」
非連續記憶體區
從前面的博文中我們已經知道,把一塊存放slab結構的記憶體區對映到一組連續的物理頁是最好的選擇,這樣會充分利用快取記憶體並獲得較低的平均訪問時間。不過,上面的方式主要是針對那些使用非常頻繁的核心資料結構 如task struct inode來設計的。如果對記憶體區的請求不是很頻繁,那麼,通過連續的線...
記憶體初始化
電容的分類 dram 基本原件是電容,需要定時重新整理,儲存速度較慢 dram又分為 sram 同步動態隨機儲存器 synchronous dynamic random access memory ddr 雙倍速率同步動態隨機儲存器 double data rate sdram ddr2 在 ddr...
處理非連續記憶體區訪問
回憶一下 缺頁異常處理程式 當出現缺頁異常,並且是程序處於核心態,即do page fault 中的那個if unlikely address task size 分支語句後,將通過vmalloc fault address 判斷該發生缺頁異常的位址address是否處於非連續記憶體區 arch i...