1. 程式人生 > >哈工大作業系統實驗:地址對映與共享

哈工大作業系統實驗:地址對映與共享

全域性描述符表GDT和區域性描述符表GDT

一個任務會涉及多個段,每個任務需要一個描述符來描述,為了便於組織管理,80386把描述符組織成線性表。由描述符組成的線性表稱為描述符表。在80386中有三種類型的描述符表:全域性描述符表GDT(Global Descriptor Table)、區域性描述符表LDT(Local Descriptor Table)和中斷描述符表IDT(Interrupt Descriptor Table)。

在整個系統中,全域性描述符表GDT和中斷描述符表IDT只有一張,區域性描述符表可以有若干張,每個任務可以有一張。

每個描述符表本身形成一個特殊的資料段。這樣的特殊資料段最多可包含有8K(8192)個描述符. 每個任務的區域性描述符表LDT含有該任務自己的程式碼段、資料段和堆疊段的描述符,也包含該任務所使用的一些門描述符,如任務門和呼叫門描述符等。隨著任務的切換,系統當前的區域性描述符表LDT也隨之切換。

全域性描述符表GDT含有每一個任務都可能或可以訪問的段的描述符,通常包含描述作業系統所使用的程式碼段、資料段和堆疊段的描述符,也包含多種特殊資料段描述符,如各個用於描述任務LDT的特殊資料段等。

在任務切換時,切換LDT,並不切換GDT

通過LDT可以使各個任務私有的各個段與其它任務相隔離,從而達到受保護的目的。通過GDT可以使各任務都需要使用的段能夠被共享。

一個任務可使用的整個虛擬地址空間分為相等的兩半,一半空間的描述符在全域性描述符表中,另一半空間的描述符在區域性描述符表中。由於全域性和區域性描述符表都可以包含多達8192個描述符,而每個描述符所描述的段的最大值可達4G位元組,因此最大的虛擬地址空間可為: 4GB8192

2=64MMB=64TB

段選擇子

在真實模式下,邏輯地址空間中儲存單元的地址由段值和段內偏移兩部分組成。 在保護方式下,虛擬地址空間(相當於邏輯地址空間)中儲存單元的地址由段選擇子和段內偏移兩部分組成。 與真實模式相比,段選擇子代替了段值。

在這裡插入圖片描述 段選擇子的高13位是描述符索引(Index)。所謂描述符索引是指描述符在描述符表中的序號

段選擇子的第2位是引用描述符表指示位,標記為TI(Table Indicator),TI=0指示從全域性描述符表GDT中讀取描述符;TI=1指示從區域性描述符表LDT中讀取描述符。

選擇子–>描述符---->段基地址----+偏移->線性地址

選擇子的最低兩位是請求特權級RPL(Requested Privilege Level),用於特權檢查。每當程式試圖訪問一個段時,要把當前特權級與所訪問段的特權級進行比較,以確定是否允許程式對該段的訪問

虛擬地址轉換為線性地址

為了將虛擬地址轉換為線性地址,分段單元執行如下操作。

  • 先檢查段選擇子的T1欄位,已決定段描述符號,儲存在全域性段描述符表GDL還是區域性段描述符表中。如果在全域性段描述符表GDL中,則分段單元則從GDTR中得到GDT的線性基地址,相反如果區域性段描述符表中則從LDTR中獲取到LDT的線性基地址。
  • 從段選擇子的index索引欄位,計算段描述符的地址,index欄位的值乘以8(一個段描述符的大小是8個位元組),然後這個值(偏移)與GDTR或者LDTR的暫存器的值(全域性/區域性段描述符表的基地址)相加,全域性/區域性段描述符表中偏移為index*8的這個地址就儲存著我們當前段的段描述符。
  • 把得到的段描述符的base欄位與邏輯地址額偏移offset值相加就得到了線性地址 在這裡插入圖片描述

分段管理機制結束

接下來是頁式管理

如果沒有采用儲存器分頁管理機制,那麼我們得到的線性地址就直接對應與實體地址,否則,則需要將線性地址轉換為實體地址。

page = frame = block

  • :線性地址被分為以固定長度為單位的組,成為頁。頁內部連續的線性地址空間被對映到連續的實體地址中。

  • 頁框:把所有的 RAM 分成固定長度的頁框(page frame)(有時叫做物理頁)。每一個頁框包含一個頁(page),也就是說一個頁框的長度與一個頁的長度一致。頁框是主存的一部分,因此也是一個儲存區域。區分一頁和一個頁框是很重要的,前者只是一個數據塊,可以存放在任何頁框或磁碟中。

  • 頁表: 把線性地址對映到實體地址的資料結構稱為頁表(page table)。頁表存放在主存

32位線性地址被分成三個區域

目錄偏移 頁表偏移 Offset
最高10位 中間10位 最低12位

CR3 指向頁目錄指標表(PDPT)的基地址 在這裡插入圖片描述

Directory欄位和Table欄位都是10位長,因此頁目錄和頁表都可以多達1024項。那麼一個頁目錄可以定址到高達 1024 * 1024 * 4096=2^32個儲存單元,這和32位地址所期望的一樣。

在這裡插入圖片描述 在這裡插入圖片描述

哈工大實驗開始

在bochs 中執行這個程式,並且找到i的實體地址然後修改他的值,修改成0讓他跳出死迴圈

#include <stdio.h>

int i = 0x12345678;

int main(void)
{
    printf("The logical/virtual address of i is 0x%08x", &i);
    fflush(stdout);

    while (i)
        ;

    return 0;
}

基本的思想:

在這裡插入圖片描述

  • ds段是選擇子 index(描述表內偏移) ti rpl 根據T1是0(GDT)是1(LDT)
  • LDTR:是區域性描述符表暫存器 index TI RPL
  • GDTR:全域性描述符表暫存器,他的值+LDTR的INDEX *8 就找到 LDT
  • 找到LDT 之後 根據在這裡插入圖片描述組合出base,就是LDT的入口
  • base + ds的index *8 就是 段基址+偏移量 在根據上圖得出的線性地址的基址
  • &i 就是得出來的偏移
  • 基址+偏移就是線性地址 在這裡插入圖片描述 分段結束

在這裡插入圖片描述 得出線性地址0X1000 3004 換算成 二進位制就是 0001000000 0000000011 000000000100 也就是 director = 64 table = 3 offset = 4

  • CR+dir*4得到頁目錄 在這裡插入圖片描述
  • 頁目錄最高20位 + table*4 得到頁 在這裡插入圖片描述
  • 頁最高20位+offset得到實體地址 (這時候檢視該地址的內容,可以看到是I =12345678) 在這裡插入圖片描述 修改為0則完成修改I值,可以跳出迴圈 在這裡插入圖片描述

總結一下過程

  • 找段號跟段偏移量(選擇子index就是描述表偏移)
  • 找LDT跟GDT
  • 根據GDT的段描述符找到LDT入口(GDT+LDTR*8)再後檢視內容,根據描述表結構組合出LDT的地址
  • 根據LDT地址檢視內容,組合出線性地址的基址(段基址)
  • 段基址+偏移量(ip內容 (通過&得出來))得出線性地址
  • 線性地址換算成二進位制分別對應DIR TABLE OFFSET
  • CR3+DIR(十進位制)*4得出頁目錄地址,檢視內容最高20位是有效位
  • 頁目錄有效位+TABLE(十進位制)*4得出頁表地址,檢視內容,最高20位是有效位
  • 頁表 + OFFSET 得出實際實體地址