一步步编写操作系统 61 任务状态段 TSS
I/O位圖是位于TSS中的,它可以存在也可以不存在,它只是用來設(shè)置對某些特定端口的訪問,沒有它的話便默認(rèn)為禁止訪問所有端口。正是由于它可有可用,所以TSS的段界限TSS limit(即實(shí)際大小-1)并不固定。當(dāng)TSS中不包括I/O位圖時(shí),TSS只有104字節(jié)大小。話說回來了,當(dāng)處理器執(zhí)行某些IO指令時(shí),若當(dāng)前特權(quán)級比IOPL低,處理器就會(huì)認(rèn)為也許只是給當(dāng)前任務(wù)單獨(dú)放行了某些端口,于是它就到TSS中找I/O位圖,如果I/O位圖不存在,即所有端口都禁止訪問,于是處理器就會(huì)拋異常。
讀到這里,有兩個(gè)問題要解決:
在TSS結(jié)構(gòu)中,有一項(xiàng)是“I/O位圖在TSS中的偏移地址”, 它在TSS中偏移102字節(jié)的地方,占2個(gè)字節(jié)空間,就是圖5-47的左上角,此處用來存儲I/O位圖的偏移地址,即此地址是I/O位圖在TSS中以0為起始的偏移量。如果某個(gè)TSS存在I/O位圖的話,此處用來保存它的偏移地址,示意如圖
如圖所示,TSS中如果有I/O位圖的話,它將位于TSS的頂端,這就是TSS的實(shí)際尺寸并不固定的原因,當(dāng)包括I/O位圖時(shí),其大小是“I/O位圖偏移地址”+8192+1字節(jié),結(jié)尾這個(gè)1字節(jié)是I/O位圖中最后的0xff,說來話長,一會(huì)再解釋。若不包括I/O位圖,其大小則為最小尺寸104字節(jié)。由于I/O位圖偏移地址并不固定,可以大于等于104,所以在TSS中偏移102字節(jié)和I/O位圖之間可能會(huì)有空閑區(qū)域。
您看,既然I/O位圖位于TSS內(nèi),那它的地址必須是在TSS的尺寸范圍之內(nèi),即地址的范圍是在TSS偏移(104 ~ TSS 段界限limit)之間,如果偏移地址不在此范圍,即大于等于TSS 段界限limit(TSS尺寸大小-1),則表明沒有I/O位圖。
現(xiàn)在來說下為什么在IO位圖的結(jié)尾有個(gè)0xff。
在計(jì)算機(jī)系統(tǒng)硬件中,IO端口是按字節(jié)來編址的,意思是說一個(gè)端口只能讀寫1個(gè)字節(jié)的數(shù)據(jù)。如果對一個(gè)端口連續(xù)讀寫多個(gè)字節(jié),實(shí)際上是從以該端口號為起始的多個(gè)端口一并讀進(jìn)來的。舉個(gè)例子,比如in指令可以讀取16位端口數(shù)據(jù),即一次讀取2字節(jié),假設(shè)端口0x234是16位端口:
in ax,0x234這相當(dāng)于
in al,0x234 in ah,0x235處理器在進(jìn)行端口讀寫時(shí),若當(dāng)前特權(quán)級CPL低于IO特權(quán)級IOPL時(shí),如果有I/O位圖的話,處理器會(huì)在I/O位圖中檢查端口相應(yīng)的bit是否為0。若在某個(gè)端口中讀取多個(gè)字節(jié),處理器必然會(huì)檢查連續(xù)的多個(gè)端口在I/O位圖中對應(yīng)的多個(gè)bit,這些bit必須都得為0 才允許訪問它們。
連續(xù)的多個(gè)bit也許會(huì)跨字節(jié),比如端口0x234對應(yīng)的bit在前一個(gè)字節(jié)的最后一位,0x235對應(yīng)的bit在后一個(gè)字節(jié)的第0位,這樣處理器必須將這兩個(gè)字節(jié)都讀進(jìn)來處理。
大多數(shù)情況下跨字節(jié)都沒問題,但當(dāng)?shù)?個(gè)bit在位圖的最后一個(gè)字節(jié)時(shí)就會(huì)出問題,處理器要讀進(jìn)多個(gè)字節(jié),所以,第2個(gè)bit所在的字節(jié)就越界了,該字節(jié)已經(jīng)不屬于位圖范圍。
為解決這個(gè)問題,處理器要求位圖的最后一字節(jié)必須是0xFF,此字節(jié)有兩個(gè)作用:
第一,處理器允許I/O位圖中不映射所有的端口, 即I/O位圖長度可以不足8KB,但位圖的最后一字節(jié)必須為0xFF。如果在位圖范圍外的端口,處理器一律默認(rèn)禁止訪問。這樣一來,如果位圖最后一字節(jié)的0xFF屬于全部65536個(gè)端口范圍之內(nèi),字節(jié)各位全為1表示禁止訪問此字節(jié)代表的全部端口,這并沒什么過錯(cuò)。
第二,如果該字節(jié)已經(jīng)超過了全部端口的范圍,它并不用來映射端口,只是用來做為位圖的邊界標(biāo)記,用于跨位圖最后一個(gè)字節(jié)時(shí)的“余量字節(jié)”。避免越界訪問TSS外的內(nèi)存。
這就是位圖中最后一字節(jié)必須為0xFF的原因。
您看I/O位圖我說的這么熱鬧,其實(shí)咱們不用它,這里的介紹完全是為了讓大伙了解IO訪問的工作原理,只會(huì)有益無害。
到了這里,特權(quán)級就講完了,本章也結(jié)束了,友情提示,我知道本章內(nèi)容有點(diǎn)多,您已經(jīng)很累了,現(xiàn)在所說的是結(jié)束語,所以可以略過這里不看啦。
總結(jié)
以上是生活随笔為你收集整理的一步步编写操作系统 61 任务状态段 TSS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 比x86性能强90% 苹果M2版MacB
- 下一篇: 一步步编写操作系统 79 在c代码中内联