內存是linux內核所管理的最重要的資源之一,內存管理子系統是操作系統中最重要的部分之一。對於立志從事內核開發的工程師來說,熟悉linux的內存管理系統是非常重要的。早些年的DOS是直接訪問內存的,這樣不同的應用程序很容易讓系統死機。在現在的linux系統,應用程序會產生一個trap,進入內核,這時內核是安全的。虛擬內存可以使應用程序使用連續。比實際內存更大的內存空間,這些內存空間在物理上可能是離散的,甚至可能是交換到磁盤上的。可以 這麼說現代操作系統的內存管理就是虛擬內存的管理。
一、存儲器地址:
Intel早期的8086/8088處理器只具有實地址模式(real-address-mode)工作方式,不能有效的支持現在多任務操作系統所需的虛擬內存管理功能。Intel從80286開始實現保護模式protected mode該處理器是16位處理器。80386為32處理器。自80386後intel cpu經歷了80486 、pentium等,雖然在速度功能上提高了很多,但其體系結構無根本的實質變化,所以統稱為IA32(Intel Architecture 32 bit)
80386從8086,80286過度而來的,為了保持向上兼容,還保留了以前的16為段寄存器。雖然只用分頁機制就能實現有效的內存保護,但還不得不在分段機制的基礎上實現保護模式,所以IA32體系結構中的分段機制很大程度上是Intel產品兼容的結果。
現在幾乎所有的risc體系結構的處理器不支持分段機制只采用了分頁機制來實現對多任務間的內存保護。同時linux中內存管理也盡可能的不用IA32體系結構中的分段機制,只是在迫不得已的時候才用,這也調高了linux可移植性。
物理地址:是指出現在cpu地址總線上的尋址物理內存的地址信號,是地址轉化的結果
邏輯地址:是程序代碼經過編譯後出現在匯編程序中的地址
線性地址:線性地址又名虛擬地址,在32位cpu架構下。可以表示4GB的地址空間用十六進制表示為:0x00000000到0xffffffff
查看本欄目更多精彩內容:http://www.bianceng.cn/OS/unix/
地址之間的轉換:
一個基於IA32體系結構的當代操作系統中(采用了保護模式和分頁機制的情況下),訪問一個內存單元需要兩次地址的轉換:
cpu將一個邏輯地址轉換為物理地址:cpu利用段式內存管理單元,將邏輯地址轉換為線性地址,在利用頁式管理單元把線性地址,轉化為物理地址。
在大多數的risc下,只需要一次線性地址到物理地址的轉換即可,在大多數risc的情況下沒有分段的概念,沒有邏輯地址。
段寄存器:
IA32體系結構只提供了段寄存器。在實模式下段寄存器用於存放段基地址,此時我們稱段寄存器為段基地址寄存器。在保護模式下,段寄存器用於存放段選擇子,此時我們稱段寄存器為段選擇子寄存器。段基地址寄存器和段選擇子寄存器是在不同模式下對段寄存器的不同解釋。IA32體系結構提供的段寄存器包括cs,ds,ss,es,fs,gs。盡管只用6個寄存器但程序可以把一個寄存器用於不同的目的。將其值先放到存儲器中然後再恢復即可。段寄存器視為了對內存進行分段管理而增加的。
CS:代碼段寄存器,CS是指向存放程序的段。SS:堆棧段寄存器,指向當前程序棧的段。DS:數據段寄存器,指向包含靜態數據或全局數據的段。其他段寄存器可用於其他用途,指向任意段。
段基地址寄存器:在這種模式下32位cpu內存管理與16位cpu是一致的。IA32體系結構處於實模式是邏輯地址由一個段基地址和一個段內偏移量決定。段基地址寄存器保存了一個16位的段基地址,段內偏移地址也是一個16位的數據。在實模式下線性地址即物理地址。
線性地址=16位段基地址*16 + 偏移量
段選擇子寄存器:在保護模式下由一個段選擇子寄存器和一個段內偏移量決定。根據段選擇子寄存器可以獲得一個32位段基地址。偏移量是32位的數據,每個段的最大容量可達4GB。
線性地址=32位段基地址 + 32位偏移量數據