初始化非連續記憶體區

2021-05-24 05:37:22 字數 1829 閱讀 1985

回到

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...