高階記憶體是linux中乙個重要的概念,初涉linux時曾經對這個概念非常迷惑。實際上這個概念比較簡單,理解這個概念,需要追溯一下linux的記憶體管理。
從前,cpu的位址匯流排只有32位,再早的就不再追溯了。32的位址匯流排無論是從邏輯上還是從物理上都只能描述4g的位址空間,在物理上理論上最多擁有4g記憶體(除了io位址空間,實際記憶體容量小於4g),邏輯空間也只能描述4g的線性位址空間。為了合理的利用4g空間,linux採用了3:1的策略,即核心占用1g的線性位址空間,使用者占用3g的線性位址空間。所以使用者程序的位址範圍從0~3g,核心位址範圍從3g~4g,也就是說,核心空間只能管理1g的記憶體。
對於如此緊張的線性位址資源,核心空間與使用者空間的肆意瓜分,導致了記憶體管理上的問題:當物理記憶體大於1g時,核心線性位址空間小於實際的物理記憶體容量,核心如何實現對大於1g記憶體的管理呢?說到這裡,需要提一下核心空間對記憶體的管理方法。一方面為了提高核心空間對記憶體的管理效率;另一方面,為了簡化核心空間對記憶體的管理方法,核心採用線性對映的方法實現對記憶體的管理,從linux實現的方法來看,實體地址與核心的虛擬位址只差乙個偏移量。所以,當物理記憶體大於1g時,物理記憶體無法全部對映到核心線性位址空間,這就產生了上述問題。
從上述描述可以看出,位址空間大於1g的記憶體區域稱之為高階記憶體,同理,小於1g的記憶體區域稱之為低端記憶體。高階記憶體的管理需要進行非線性對映,為此,在核心線性位址空間預留了128m的空間,位於線性位址空間的高階。如今,cpu的位址匯流排都擴大到64位了,線性位址資源非常豐富,所以,可以給核心空間預留足夠的線性位址資源,在最近一段時間內,核心線性位址資源與物理記憶體容量之間的矛盾將不再突出,高階記憶體的概念也就在64位cpu上消失了。
原先一直都對linux高階記憶體的管理認識模模糊糊的,可能主要是初次接觸linux kernel 是0.11版吧,當初的記憶體設計是16m,linus對擁有32m的記憶體都是覬覦萬分,1g記憶體恐怕是天方夜譚了。16m記憶體**還顧得上高階記憶體,腦子就一直沒有這種概念。先我們還是來看看為什麼要有高階記憶體?
80386的線性定址空間是4g,核心空間從3g開始,如果全部採用"線性對映"(實體地址和邏輯位址只差乙個常量 page_offset ),最多管理1g物理記憶體,也就是1g的物理記憶體挨著挨著對應的是虛擬位址的3g到4g的位置。你想想如果多於1g的記憶體,我們用什麼線性位址來裝下這些多出的位址呢?我朋友的機器有2g,據說玩遊戲巨爽(amd64300+).顯然如果線性對映我的朋友就會浪費1g記憶體.為了使核心能夠訪問這些"高階記憶體",核心使用highmem.做法是不將核心1g的虛擬位址空間全部對映成物理記憶體,而是預留一部分給高階記憶體做臨時對映使用.
其實核心不僅僅預留了highmem的位址空間,還給fixmap,vmalloc預留了虛存空間.實際上,系統初始化的時候預留128m虛存,896m用於"直接"對映物理記憶體。下面我們先貼上一幅圖,摘自《understand linux kernel 》
高階記憶體對映有三種方式:
1、對映到「核心動態對映空間」
這種方式很簡單,因為通過 vmalloc() ,在"核心動態對映空間"(上圖的vmalloc_start到vmalloc_end)申請記憶體的時候,就可能從高階記憶體獲得頁面(參看 vmalloc 的實現),因此說高階記憶體有可能對映到"核心動態對映空間" 中。
3、臨時對映
核心在 fixaddr_start 到 fixaddr_top 之間保留了一些線性空間用於特殊需求。這個空間稱為「固定對映空間」
在這個空間中,有一部分用於高階記憶體的臨時對映。
這塊空間具有如下特點:
1、每個 cpu 占用一塊空間
2、在每個 cpu 占用的那塊空間中,又分為多個小空間,每個小空間大小是 1 個 page,每個小空間用於乙個目的,這些目的定義在 kmap_types.h 中的 km_type 中。
當要進行一次臨時對映的時候,需要指定對映的目的,根據對映目的,可以找到對應的小空間,然後把這個空間的位址作為對映位址。這意味著一次臨時對映會導致以前的對映被覆蓋。
通過 kmap_atomic() 可實現臨時對映。
高階記憶體與低端記憶體
高階記憶體是 linux 中乙個重要的概念,初涉 linux 時曾經對這個概念非常迷惑。實際上這個概念比較簡單,理解這個概念,需要追溯一下 linux 的記憶體管理。從前,cpu的位址匯流排只有 32位,再早的就不再追溯了。32的位址匯流排無論是從邏輯上還是從物理上都只能描述 4g的位址空間,在物理...
高階記憶體和低端記憶體
高階記憶體是linux中乙個重要的概念,初涉linux時曾經對這個概念非常迷惑。實際上這個概念比較簡單,理解這個概念,需要追溯一下linux的記憶體管理。從前,cpu的位址匯流排只有32位,再早的就不再追溯了。32的位址匯流排無論是從邏輯上還是從物理上都只能描述4g的位址空間,在物理上理論上最多擁有...
高階記憶體和低端記憶體
高階 記憶體是linux中乙個重要的概念,初涉linux時曾經對這個概念非常迷惑。實際上這個概念比較簡單,理解這個概念,需要追溯一下linux的記憶體管理。從前,cpu的位址匯流排只有32位,再早的就不再追溯了。32的位址匯流排無論是從邏輯上還是從物理上都只能描述4g的位址空間,在物理上理論上最多擁...