深入理解linux內核——內存尋址(1)

內存地址

邏輯地址:包含在機器語言指令中用來指定一個操作數據或一條指令的地址。每一個邏輯地址都由一個段(segment)和偏移量(offset或displacement)組成,偏移量指明瞭從段開始的地方到實際地址之間的距離。

線性地址:也稱虛擬地址。

物理地址:用於內存芯片級內存單元尋址。它們與從微處理器的地址引腳發送到內存總線上的電信號相對應。

內存控制單元通過一種稱為分段單元的硬件電路把一個邏輯地址轉換成線性地址;接著第二個稱為分頁單元的硬件電路把線性地址轉換成一個物理地址。

深入理解linux內核——內存尋址(1)

硬件中的分段

從80286模型開始,intel處理器以兩種不同的方執行地址轉換,這兩種方式分別稱為實模式(read mode)和保護模式(protected mode)。

一個邏輯地址由兩部分組成:一個段標誌符一個指定段內相對地址的偏移量。段標誌符是一個16位長的字段,稱為段選擇符。而偏移量是一個32位長的字段。

為了方便快速找到段選擇符,處理器提供段寄存器,段寄存器的唯一目的是存放段選擇符。儘管只有6個段寄存器,但程序可以把同一個段寄存器用於不同的目的,方法是先將其值保存在內存中,用完後再恢復。

深入理解linux內核——內存尋址(1)

每個段由一個8字節的段描述符表示,它描述了段的特徵。段描述符放在全局描述符表(GDT)或局部描述符表(LDT)中。

通常只定義一個GDT中,而每個進程除了存放在GDT中的段之外如果還需要創建附加的段,就可以有自己的LDT。GDT在主體中的地址和大小存在gdtr控制寄存器中,當前正在被使用的LDT地址和大小放在ldtr控制寄存器中。

為了加快邏輯地址到線性地址的轉換,80x86處理器提供一種附加的非編程的寄存器供6個可編程的段寄存器使用。每當一個段選擇符被裝入段寄存器時,相應的段描述符就由內存裝入到對應的非編程CPU寄存器中。

從那時起,針對那個段的邏輯地址就可以不訪問主存中的GDT或LDT

,處理器只需直接引用存放段描述符的CPU寄存器即可。僅當段寄存器的內容改變時,才有必須訪問GDT或LDT。

深入理解linux內核——內存尋址(1)

由於段描述符是8字節長,因此它在GDT或LDT內的相對地址是由段選擇符的最高13位的值乘8得到的。

邏輯地址是怎麼樣轉換成相應的線性地址的:

1。先檢查段選擇符的TI字段,以決定段描述符保存在

哪一個描述符表中。TI字段指明描述符是在GDT中(在這種情況下, 分段單元從gdtr寄存器中得到GDT的線性基地址)還是在激活的LDT中(在這種情況下, 分段單元從ldtr寄存器中得到ldt的線性基地址)。

2。從段選擇符的index字段計算段描述符的地址,index字段的值乘8(一個段描述符的大小),這個結果與gdtr或ldtr寄存器中的內容相加

3。把邏輯地址的偏移量與段描述base字段的值相加得到了線性地址。

(後面的明天再說,掌握前面很重要)

linux中的分段

硬件中的分頁

linux中的分頁


分享到:


相關文章: