1. 程式人生 > >對Linux記憶體地址轉換、保護模式的理解

對Linux記憶體地址轉換、保護模式的理解

相關概念:真實模式、保護模式、GDT、LDT、實體地址、邏輯地址、線性地址(虛擬地址) 真實模式 Intel 80286時代使用的模式。訪問記憶體是通過segment:offset找到記憶體的。即“左移4位加偏移”,segment<<4+offset = 實體地址 保護模式 如今大部分的x86操作系都在保護模式下執行。記憶體的管理模式分為兩種,段模式和頁模式 訪問一個記憶體地址仍然使用Segment:Offset的方式,segment是32位地址。 段模式提供了保護機制,其中每個段都會有一個數據結構叫段描述符,即[Base Address, Limit, Access]。每個段描述符的長度是8位元組,含有3個主要欄位:段基地址、段限長和段屬性。 GDT(Global Descriptor Table)
GDT是保護模式下關鍵的一個數據結構。GDT是一個數組,存放在記憶體的某一個位置上,陣列中存放了所有的段描述符。因為每一個程序都需要用到它,所以它是對所有程序可見的。 CPU必須知道GDT的入口,也就是它放在哪裡,CPU提供了一個暫存器GDTR(段描述符暫存器)用來存放GDT的入口地址,程式設計師將GDT設定在記憶體中某個位置之後,可以通過LGDT指令將GDT的入口地址裝入GDTR暫存器,從此以後,CPU就根據GDTR中的內容作為GDT的入口來訪問GDT了。 LDT(Local Descriptor Table) 它也是段描述符,但是它是某一個程序專有的。LDT的入口存在則在LDTR暫存器中。
段暫存器 段暫存器只有16位,其中存放的是段描述符在GDT或LDT內的索引值(index)。(注意區別段暫存器和段描述符暫存器,前者用來找某一個段描述符的位置,後者用來找整個GDT的位置)

實體地址
記憶體單元的地址,記憶體是一個線性的儲存空間,每個記憶體單元按地址從小到大排列著。CPU通過這個地址直接訪問地址對應的單元的資料。

邏輯地址

真實模式下的那種地址就是邏輯地址。它是機器指令裡出現的記憶體地址。段選擇符(16位) + 偏移量(32位) = 邏輯地址

段選擇符

段選擇符用16位來表示。最高13位表示要使用的段在描述符表中的索引號,低3位的前兩位表示使用段的權等級,最後1位指明描述符是位於GDT中還是位於LDT中(=0表示用GDT,=1表示用LDT)。段選擇符用於邏輯地址向線性地址的轉換,段描述符在GDT或LDT內的相對地址是由段選擇符的最高13位的值乘以8(因為每個描述符8位元組)得到的。

線性地址(虛擬地址)

線性地址就是對於某個程序自己地址空間的地址了。

三種地址的轉換流程

機器指令中出現的記憶體地址是邏輯地址,需要轉換成線性地址,再經過MMU轉換成實體地址才能夠被訪問到。

邏輯地址-線性地址轉換可以看做是對過去的相容。