任務門及任務切換

1.利用中斷引發任務切換:

1.1中斷描述符表IDT:

在保護模式下,實模式下中斷向量表不再使用,取而代之的是中斷描述符表IDT。IDT與GDT,LDT一樣,用於保存描述符;但IDT保存的是門描述符:中斷門、陷阱門、任務門;

1.2任務門

中斷髮生時,如果中斷號對應的門是任務門,則必須進行任務切換;
任務門描述符格式:

P位指示該門是否有效,0不允許通過此門實施任務切換; DPL爲任務門描述符特權級,對因中斷通過任務門引發任務切換沒用,但對非中斷通過任務門引發任務切換有用;

1.3中斷執行

中斷執行一般執行過程:
中斷髮生==>處理器用中斷號*8(描述符佔8B)作爲索引訪問IDT==>訪問門描述符==>取出代碼段選擇子和段內偏移==>轉去執行;

通過中斷引發任務切換具體過程:

  1. 中斷髮生==>處理器將中斷號*8==>訪問中斷向量表IDT;
  2. 看是否爲任務門描述符,是則進行任務切換,否則普通中斷處理;
  3. 取出任務門描述符==>從描述符中取出新任務TSS選擇子;
  4. 用TSS選擇子訪問GDT==>取出新任務TSS描述符;
  5. 將當前任務狀態存到TR指向的TSS(當前)中;
  6. 訪問新任務TSS,從中恢復恢復各寄存器內容:通用寄存器、標誌寄存器EFLAGS、段寄存器、EIP、ESP、LDTR等;
  7. TR指向新任務TSS(任務切換完成)
  8. [1].把舊任務TSS選擇子填寫到新任務TSS的任務鏈接域,固件執行(TSS結構),且舊任務TSS描述符中B位置保持"1"不變;
    [2].EFLAGS寄存器中NT位置"1",表示發生嵌套
    (32位處理器的EFLAGS寄存器中NT位(14位),是嵌套任務標誌位,爲"1"則表示當前任務嵌套於其他任務內);
    [3].新任務TSS描述符中B位置"1",表示忙;

1.3中斷返回

中斷不論常規中斷處理過程,還是任務切換,返回都需要指令iret,前者返回同一任務內不同代碼段,後者返回被中斷任務;
處理器通過EFLAGS中NT判斷是哪種情況,因爲若引發任務切換則新任務EFLAGS中NT位爲"1";

中斷返回過程(iret執行):
iret指令,則檢查NT位:
==>若0(沒嵌套),表明一般中斷過程,一般中斷處理;
==>若1(嵌套),固件將現EFLAGS中NT置"0"(不在嵌套),並將EFLAGS保存在現TSS中,現TSS描述符中B位置"0"(當前沒在執行),從現TSS任務鏈接域中取得TSS選擇子,所有原始狀態都從原TSS中恢復,包括EIP,回到任務切換出指令繼續執行;

2.利用指令引發任務切換:

利用calljmp指令,操作數爲任務的TSS描述符選擇子/任務門描述符,能夠實現任務切換,描述符可以安在GDT/LDT;如:

call 0x0010:0x000000
jmp 0x0010:0x000000

當執行到這兩條指令時,訪問GDT,若描述符是TSS描述符/任務門描述符==>偏移量忽略並從TSS中獲取,開始任務切換;

3.對比與安全檢查

利用calljmp指令和中斷引發任務切換對比:

JMP/CALL/中斷引發對比返回
CALL/中斷髮起切換引起嵌套
舊任務:TSS中B保持'1'(忙)不變,EFLAGS中NT保持不變;
新任務:TSS中B置'1'(忙),EFLAGS中NT置'1'(嵌套),新TSS任務鏈接域填舊TSS選擇子(固件執行)
指令iret/iretd(過程在1.3)
JMP不會引起嵌套
舊任務:TSS中B置'0'(非忙),EFLAGS中NT保持不變;
新任務:TSS中B置'1'(忙),EFLAGS中NT保持從TSS中加載時狀態;
新TSS任務鏈接域不變
JMP回來

安全檢查

  • 檢查是否允許從舊任務切換到新任務:
    JMP/CALL:舊任務CPL、新任務段選擇子RPL<=目標TSS/任務門DPL;
    異常、中斷(除in n引發)、iret:忽略目標門/TSS描述符DPL,int n引發中斷檢查DPL;
  • 檢查新任務TSS是否標記爲有效(P=1),且界限也有效(界限>=103)
  • 檢查新任務是否可用:
    B=0(CALL、JMP、異常或中斷髮起的任務切換);
    B=1(iret發起的任務切換);
  • 檢查舊任務和新任務TSS,以及所有要用的段描述符是否在內從中;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章