天天看點

【從頭開始寫作業系統系列】實作一個-GDT(2)選擇子是什麼?動手實作選擇子

在這篇文章我們将要做:

  • 介紹選擇子
  • 實作一個選擇子結構

選擇子是什麼?

在上篇文章中我們介紹了段描述符以及段描述符表,這篇文章我們複習一下段、段描述符、段描述符表的功能,并且介紹一下段選擇子以及段描述符表。

  • 段(Segment):在80X86中,我們知道分段機制将記憶體空間分為了多個線性區域,我們把這些線性區域稱為段。由于我們要将這些段區分開來,于是我們對段賦予3個屬性。他們分别是段基址(Base)、段界限(Limit)、段屬性(Attribute),段基址表示了一個段線上性空間中的開始位址,段界限表示段内最大偏移量,也就是說,它定義了段的大小,段屬性描述了段的一些特性,包括可讀可寫可執行、特權級等。
  • 段描述符(Descriptor):在程式中我們需要定義一個資料結構來表示段,包括段基址(Base)、段界限(Limit)、段屬性(Attribute)這3個屬性,這個資料結構叫做 段描述符(Descriptor)。段是一個邏輯概念,段描述符是對應的資料結構。
  • 段描述符表(Descriptor Table):在一個程式中,不僅僅是隻有一個段(段描述符),我們需要一種方法将它們組織起來,也就是說需要一個數組來儲存它們,這個結構就是段描述符表。段描述符表分為兩種,一種是全局描述符表(GDT),一種是局部描述符表(LDT),系統中供所有任務使用的是全局描述符表,每個任務使用的是它自己的局部描述符表。
  • 段選擇子(Selector):我們已經知道段描述符是存儲于段描述符表中的,當我們需要通路段描述符時是如何通路的呢?其實,我們是通過段描述符在段描述符表中的位置來進行通路的。段選擇子就是這樣的一個16位的辨別符,它辨別了段描述符在段描述符表中的位置。
  • 段描述表寄存器:如何讓系統知道段描述符表在什麼地方呢?處理器提供了記憶體管理寄存器,分别是全局描述符表寄存器(GDTR)、局部描述符表寄存器(LDTR)。GDTR寄存器中用于存放全局描述符表GDT的32位線性基位址和16位的表的長度值。LDTR寄存器中用于存放局部描述符表LDT的32位線性基位址和16位的表的長度值。通過系統指令,lgdt将GDT的線性基址和長度值加載到GDTR寄存器中,lldt将LDT的線性基址和長度值加載到LDTR寄存器中。
【從頭開始寫作業系統系列】實作一個-GDT(2)選擇子是什麼?動手實作選擇子

動手實作選擇子

選擇子結構

【從頭開始寫作業系統系列】實作一個-GDT(2)選擇子是什麼?動手實作選擇子

選擇子的彙編實作

  • testgdt.asm
[SECTION .gdt]
; 定義GDT資料段
LABEL_GDT:     Descriptor       ,                ,            ; 空描述符
LABEL_DESC_CODE32: Descriptor       , SegCode32Len - , DA_C + DA_32; 非一緻代碼段
LABEL_DESC_VIDEO:  Descriptor B8000h,           ffffh, DA_DRW      ; 顯存首位址
; GDT 結束

GdtLen      equ $ - LABEL_GDT  ; GDT長度
GdtPtr      dw  GdtLen - 1  ; GDT界限
        dd  0       ; GDT基位址

; GDT 選擇子
SelectorCode32      equ LABEL_DESC_CODE32   - LABEL_GDT
SelectorVideo       equ LABEL_DESC_VIDEO    - LABEL_GDT
; END of [SECTION .gdt]
           
  • pm.inc
; 描述符類型
DA_32       EQU h   ;  位段

; 存儲段描述符類型
DA_DRW      EQU h ; 存在的可讀寫資料段屬性值
DA_C        EQU h ; 存在的隻執行代碼段屬性值
DA_CR       EQU Ah ; 存在的可執行可讀代碼段屬性值
DA_CCO      EQU Ch ; 存在的隻執行一緻代碼段屬性值
DA_CCOR     EQU Eh ; 存在的可執行可讀一緻代碼段屬性值

;描述符
;個參數:
;   .段基址:位(位元組)
;   .段界限:低位
;   .屬性:位(高位元組中的低位總是)

%macro Descriptor  ;定義宏Descriptor,有個參數
    dw  %2 & 0FFFFh ;用參數的低位填充一個WORD
    dw  %1 & 0FFFFh ;用參數的低位填充一個WORD
    db  (%1 >> ) & 0FFh   ;用參數的-位填充一個BYTE
    dw  ((%2 >> ) & 0F00h) | (%3 & 0F0FFh) ;用參數的-位以及參數的-位和-位填充一個WORD
    dw  (%1 >> ) & 0FFh   ;用參數的-位填充一個WORD
%endmacro
           

現在選擇子已經初步完成,下篇文章我們重點講解 GDT 以及它的實作。

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。

文章來源:http://blog.luoyuanhang.com

繼續閱讀