一步步编写操作系统 60 cpu的IO特权级2 什么是驱动程序
用戶程序可以在由操作系統加載時通過指定整個eflags設置,操作系統如何設置自己的IOPL呢,即使內核IOPL為0也得寫進去eflags寄存器中才生效。可惜的是,沒有直接讀寫eflags寄存器的指令,不過可以通過將棧中數據彈出到eflags寄存器中來實現修改。可以先用pushf指令將eflags整體壓入棧,然后在棧中修改相應位,再用popf指令彈出到eflags寄存器中。另外一個可利用棧的指令是iretd,用iretd指令從中斷返回時,會將棧中相應位置的數據當成eflags的內容彈出到eflags寄存器中。所以可以改變IOPL的指令只有popf和iretd指令,依然是只有在0特權下才能執行。如果在其它特權級下執行此指令,處理器也不會引發異常,只是沒任何反應。
接下來看看IO位圖是怎么回事。
假如,數值上CPL <= IOPL,程序既可以執行IO特權指令,又可以操作所有的IO端口。倘若數值上CPL > IOPL,程序也不是完全無法進行任何IO操作,有點奇怪是不,似乎和咱們的邏輯不符,其實這樣是有道理的。
之前說過,IOPL是所有IO端口的開關,不過,這個開關還留有余地,如果將開關打開,便可以訪問全部65536個端口,如果開關被關上,即數值上CPL > IOPL,則可以通過IO位圖來設置部分端口的訪問權限。也就是說,先在整體上關閉,再從局部上打開。這有點像設置防火墻的規則,先默認為全部禁止訪問,想放行哪些端口再單獨打開。
處理器為什么允許這么做呢?原因是為了提速。
如果所有IO端口訪問都要經過內核的話,由低特權級轉向高特權級時是需要保存任務上下文環境的,這個過程也是要消耗處理器時間,隨著端口訪問多起來,時間成本還是很可觀的。這一典型的應用就是硬件的驅動程序,它位于特權級1。
什么是驅動程序?
驅動程序就是通過in、out等IO指令直接訪問硬件的程序,它為上層程序提供對硬件的控制訪問,相當于硬件的代理,程序員通過它就免去了學習硬件控制的相關知識,簡化了程序設計。
所以說,驅動程序肯定是要直接控制IO端口的,盡管它可以像linux那樣位于0特權級,但它位于1特權級時,依然可以直接操作硬件端口。
即使是在3特權級下,也要考慮某些需要快速反應的場合,比如某個應用程序需要快速的以硬件交互,所以處理器允許通過I/O位圖來為3特權級程序打開某些端口的控制。這些規則同樣適用于2特權級,也就是說在任意特權級下,處理器都可以通過I/O位圖為相應特權級的程序開啟特定的端口。
欲知I/O位圖是怎么回事,咱們先把位圖的概念明確。
位圖就是bit map,map就是映射,建立的是某種對應關系,像地圖那樣,圖上某個區域代表實際地理范圍,bit就是位,bit map就是用一個bit映射到某個實際的對象。位圖這種結構的操作單位就是bit,所以位圖其實就是一串二進制01數字,對位圖的操作也就是讀寫相應的位,處理器中對內存的訪問是以字節為單位,不能直接操作位,所以對于操作位圖,簡單說來就是先將該位所在的字節讀到內存,若是想將該位置為1,可以用1對該位進行或’運算,若想將該位清0,可以用0對該位進行’與’運算,以后咱們少不了操作位圖,到時候再實踐。
intel處理器最大支持65536個端口,它允許任務通過I/O位圖來開啟特定端口,位圖中的每一bit代表相應的端口,比如第0個bit表示第0個端口,第65535個bit表示第65535個端口,65536個端口號占用的位圖大小是63356/8=8192字節,即8KB。I/O位圖中如果相應bit被置為0,表示相應端口可以訪問,否則為1的話,表示該端口禁止訪問。如圖
再次聲明,I/O位圖只是在數值上CPL > IOPL,即當前特權級比IOPL低時才有效,若當前特權級大于等于IOPL,任何端口都可直接訪問不受限制。
總結
以上是生活随笔為你收集整理的一步步编写操作系统 60 cpu的IO特权级2 什么是驱动程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浦发美团点评信用卡额度一般是多少
- 下一篇: 第一批储蓄国债发行终于定了,最新利率公布