本文主要介紹linux核心初始化時,對物理記憶體的使用結構,以及如何從實模式轉換成保護模式,即如何開啟記憶體分頁。
我們知道,程序分為核心態和使用者態,其中重要的乙個區別就是執行於使用者態的程序線性位址小於0xc0000000,核心態程序大於0xc0000000,因此0xc0000000就是核心態和使用者態的分界線。線性位址是核心使用的邏輯位址,在真正訪存時需要對映成實體地址,如果開啟分頁功能,則進行分頁下的二級(**)對映。
核心開啟分頁功能,只需要一條指令,因此在開啟前就需要完成頁面表的設定,比如全域性目錄表,以及頁面表,在目錄表每項中填充指向頁面表的實體地址。
為簡單起見,我們假設核心使用的段、臨時頁表、及核心本身能容納與ram的前8m空間,按照每頁4k大小,分頁模式需要2個頁表才能對映8m的大小。
臨時頁面表被安排在上圖中_end之後,即核心未初始化的資料段後面,2個頁面大小,一共4k*2。
既然全域性目錄和臨時頁表的都已經清楚了,接下來將臨時頁表的實體地址填入全域性目錄表的相應表項中即可。但是需要注意的是需要同時保證在實模式下和保護模式下都能對這8m實體地址進行定址。實模式對應線性位址0x00000000,保護模式,即核心態則對應的執行緒位址為0xc0000000。因此從
0x00000000到0x007fffff 和
0xc0000000到0xc07fffff的線性位址
都要對映物理記憶體的前8m,這樣只需在全域性目錄表相應的表項中填上臨時頁表的實體地址即可。具體填什麼,我們可以算一算。
首先,線性位址0x00000000起始的頁面的頁表的實體地址,毫無疑問填到目錄表的第0項,對應著實模式。那麼保護模式下的起始線性位址0xc0000000開始的頁面的頁表的實體地址對應到目錄表中的那一項呢? 0xc00000000>>22=0x300(十進位制768),即線性位址0xc0000000對應的頁面的頁表的實體地址應該填到目錄表的第768位。
目錄表的第1項和第769項填第二個臨時頁表的實體地址。設定完成後具體結構如下圖所示
}//設定目錄表的表項為新申請的頁面表的實體地址
pte = (pte_t *) alloc_bootmem_low_pages(page_size);
set_pmd(pmd, __pmd(_kernpg_table + __pa(pte)));
if (pte != pte_offset(pmd, 0))
bug();
//設定頁面表的每個表項內容為對應的實體地址
//可以看出,核心態的分頁模式下的記憶體對映為固定的對映,
//具體表現為頁面表項的實體地址固定不變
for (k = 0; k < ptrs_per_pte; pte++, k++)
}
}還是省略了許多細節,所以歡迎互相交流討論。
記憶體初始化
電容的分類 dram 基本原件是電容,需要定時重新整理,儲存速度較慢 dram又分為 sram 同步動態隨機儲存器 synchronous dynamic random access memory ddr 雙倍速率同步動態隨機儲存器 double data rate sdram ddr2 在 ddr...
記憶體初始化過程
1,物理記憶體資訊的獲取 0x15中斷,功能號 e820h,e801h,e88h 見檔案 linux arch i386 boot setup.s 執行完上面的 後,記憶體資訊被分為多條資訊放在e820map位置處,每個資訊條目長20位元組,包含乙個記憶體區間的資訊,條目數放在e820nr處。即實際...
記憶體初始化檔案 ISE Quartus
1.quartus mif file demo multiple line comment multiple line comment single line comment depth 32 the size of data in bits width 8 the size of memory i...