TSS详解 ——《x86汇编语言:从实模式到保护模式》读书笔记33
TSS(Task State Segment,任務狀態段)詳解
1. TSS描述符
和LDT一樣,必須為每個TSS在GDT中創建對應的描述符。TSS描述符的格式如下圖:
B位是“忙”位(Busy)。在任務剛剛創建的時候,它應該為0,表明任務不忙。當任務開始執行時,或者處于掛起狀態(臨時被中斷執行)時,由處理器固件把B位置1.
任務是不可重入的。就是說在多任務環境中,如果一個任務是當前任務,那么它可以切換到其他任務,但是不能從自己切換到自己。在TSS描述符中設置B位,并由處理器固件進行管理,可以防止這種情況的發生。
2. TSS的格式
在一個多任務環境中,當任務發生切換時,必須保存現場(比如通用寄存器,段寄存器,棧指針等)。為了保存被切換任務的狀態,并且在下次執行它時恢復現場,每個任務都應當有一片內存區域,專門用于保存現場信息,這就是任務狀態段(Task State Segment)。
在創建一個任務的時候,我們要為這個任務創建TSS并填寫其中的一些字段。
前一任務鏈接(TSS Back Link):TSS內偏移0處是前一個任務的TSS描述符的選擇子。
當Call指令、中斷或者異常造成任務切換,處理器會把舊任務的TSS選擇子復制到新任務的TSS的Back Link字段中,并且設置新任務的NT(EFLAGS的bit14)為1,以表明新任務嵌套于舊任務中。關于這點我們會在第15章學習。在創建一個任務的時候,這個字段可以填寫0.
SS0,SS1,SS2和ESP0,ESP1,ESP2分別是0,1,2特權級堆棧的選擇子和棧頂指針。這些內容應當由任務的創建者填寫,且屬于填寫后一般不變的靜態字段。
CR3和分頁有關,我們會在第16章學習。如果沒有啟用分頁,可以填寫0.
偏移為0x20~0x5C的區域是處理器各個寄存器的快照部分,用于任務切換時保存現場。在一個多任務環境中,每次創建一個任務,內核至少要填寫EIP,EFLAGS,ESP,CS,DS,SS,ES,FS和GS。當任務首次執行時,處理器從這些寄存器中加載初始執行環境,從CS:EIP處開始執行任務的第一條指令。
LDT選擇子是當前任務的LDT選擇子,由內核填寫,以指向當前任務的LDT。該信息由處理器在任務切換時使用,在任務運行期間保持不變。
T(Debug Trap)位用于軟件調試。在多任務環境中,如果T=1,則每次切換到該任務的時候,會引發一個調試異常中斷(int 1).
I/O位圖基地址用來決定當前的任務是否可以訪問特定的硬件端口。關于這個,下文會具體說明。
3. I/O許可位圖(I/O Permission Bit Map)
EFLAGS寄存器的IOPL位決定了當前任務的I/O特權級別。如果在數值上CPL<=IOPL,那么所有的I/O操作都是允許的,針對任何硬件端口的訪問都可以通過;如果在數值上CPL>IOPL,也并不是說就不能訪問硬件端口。事實上,處理器的意思是總體上不允許,但個別端口除外。至于個別端口是哪些端口,要找到當前任務的TSS,并檢索I/O許可位圖。
I/O許可位圖(I/O Permission Bit Map)是一個比特序列,因為處理器最多可以訪問65536個端口,所以這個比特序列最多允許65536比特(即8KB)。
如下圖中的綠色部分,第一個字節代表端口0~7,第二個字節代表端口8~15,以此類推。每個比特的值決定了相應的端口是否允許訪問。為1時禁止訪問,為0時允許訪問。
在TSS內偏移為102字節的那個字單元,是I/O位圖基地址字段,它指明了I/O許可位圖相對于TSS起始處的偏移,例如下圖中這個字段的值是144.
有幾點需要說明:
1. 如果I/O位圖基地址的值>=TSS的段界限(就是TSS描述符中的段界限),就表示沒有I/O許可位圖。
2. 處理器要求I/O位圖的末尾必須附加一個全1的字節,即0xFF.
3. 處理器不要求為每一個I/O端口都提供位映射,對于那些沒有在位圖中映射的位,處理器假定它對應的比特是1(禁止訪問)。
4. TSS描述符中的界限值包括I/O許可位圖在內,也包括最后附加的0xFF. 以下圖為例,TSS的界限值是149(總大小150減去1)。
【end】
總結
以上是生活随笔為你收集整理的TSS详解 ——《x86汇编语言:从实模式到保护模式》读书笔记33的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 任务和特权级保护(二)——《x86汇编语
- 下一篇: 用友元函数重载乘法,用成员函数重载除法