Linux記憶體布局執行個體講解,linux布局執行個體講解
現在,我們就來看看記憶體這座巨大的城市史如何布局的。在系統初始化階段,核心首先在實模式下建立一個物理地址映射來指定哪些物理位址範圍對核心可用而哪些不可用(主要是根據映射硬體裝置I/O的共用記憶體,或者根據相應的頁框含有的BIOS資料)。
記憶體的某些部分將永久地分配給BOIS或核心,用來存放BIOS資訊、核心代碼以及靜態核心資料結構。所以核心將下列頁框記為保留:
在停用物理位址範圍內的頁框,一般用來存放BIOS資訊。
含有核心代碼和已初始化的資料結構的頁框。
標記為保留頁框中的頁,絕不能被動態分配或交換到磁碟上。
一般來說,Linux核心安裝在RAM中從物理地址0x00100000開始的地方,也就是說,從第二個MB開始。所需頁框總數依賴於核心的配置方案:典型的配置所得到的核心可以完全被安裝在小於3MB的RAM中。
為什麼核心沒有安裝在RAM第一個MB開始的地方?主要是為具體的PC體繫結構所考慮。例如:
頁框0由BIOS使用,存放加電自檢(Power-On Self-Test,POST)期間檢查到的硬體設定。因此,很多膝上型電腦的BIOS甚至在系統初始化後還將資料寫到該頁框。
物理地址從0x000a0000 到 0x000fffff的範圍通常留給BIOS常式,並且映射ISA圖形卡上的內部儲存空間。這個地區就是所有IBM相容PC上從640KB到1MB之間著名的洞:物理地址存在但被保留,對應的頁框不能由作業系統使用。
前1MB內的其他頁框可能由特定電腦模型保留。例如,IBM 膝上型電腦把0x0a頁框映射到0x9f頁框。
在啟動過程的早期階段,核心詢問BIOS並瞭解實體記憶體的大小,並調用machine_specific_memory_setup()函數建立物理地址映射。假設我們的記憶體是128MB,那麼,第一個MB就給BIOS了。整個128MB的記憶體被物理映射成以下布局:
0x00000000 - 0x0009ffff 除第一個頁框外的640K空間可用
0x000a0000 - 0x000effff 保留
0x000f0000 - 0x000fffff 保留給BIOS常式
0x00100000 - 0x07feffff 126.9MB可用空間
0x07ff0000 - 0x07ff2fff ACPI data
0x07ff3000 - 0x07ffffff ACPI NVS
0xffff0000 - 0xffffffff 保留
這裡簡單介紹一下128MB記憶體的末尾,從0x07ff0000 到0x07ff2fff的物理位址範圍中存有加電自測(POST)階段由BIOS寫入的系統硬體裝置資訊;在初始化階段,核心把這些資訊拷貝到一個合適的核心資料結構中,然後認為這些頁框是可用的。相反,從0x07ff3000到0x07ffffff的物理位址範圍被映射到硬體裝置的ROM晶片。從0xffff0000開始的物理位址範圍標記為保留,因為它由硬體映射到了BIOS的ROM晶片。注意BIOS也許並不提供一些物理位址範圍的資訊(在上述圖中,範圍是0x000a0000到 0x000effff)。為安全可靠起見,Linux假定這樣的範圍是停用。
雖然,我們看到第一個MB裡,BIOS並沒有用完,但是為了避免把核心裝入一組不連續的頁框裡,影響效能,Linux便跳過第1MB的RAM,之間從第2個MB開始載入。其實一般來說,對於兩個MB,也就是512個頁框,對初始化時的核心代碼及一些待用資料,已經足夠了。
核心可能不會見到BIOS報告的所有實體記憶體:例如,如果未使用PAE支援來編譯,即使有更大的實體記憶體可供使用,核心也只能定址4GB大小的RAM。setup_memory()函數在machine_specific_memory_setup()執行後被調用:它分析實體記憶體地區表並初始化一些變數來描述核心的實體記憶體布局,這些變數如下表所示:
變數名稱 |
說明 |
num_physpages |
最高可用頁框的頁框號 |
totalram_pages |
可用頁框的總數量 |
min_low_pfn |
RAM 中在核心映像後第一個可用頁框的頁框號 |
max_pfn |
最後一個可用頁框的頁框號 |
max_low_pfn |
被核心直接映射的最後一個頁框的頁框號(低地址記憶體) |
totalhigh_pages |
核心非直接映射的頁框的總數(高地址記憶體) |
highstart_pfn |
核心非直接映射的第一個頁框的頁框號 |
highend_pfn |
核心非直接映射的最後一個頁框的頁框號 |