【梳理】簡明操作系統原理 第十一章 I / O設備(內附文檔高清截圖)

參考教材:
Operating Systems: Three Easy Pieces
Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau
在線閱讀:
http://pages.cs.wisc.edu/~remzi/OSTEP/
University of Wisconsin Madison 教授 Remzi Arpaci-Dusseau 認爲課本應該是免費的
————————————————————————————————————————
這是專業必修課《操作系統原理》的複習指引。
在本文的最後附有複習指導的高清截圖。需要掌握的概念在文檔截圖中以藍色標識,並用可讀性更好的字體顯示 Linux 命令和代碼。代碼部分語法高亮。
操作系統原理不是語言課,本複習指導對用到的編程語言的語法的講解也不會很細緻。如果不知道代碼中的一些關鍵字或函數的具體用法,你應該自行查找相關資料。

十一 I / O設備

1、一顆較新的Intel CPU通過各種各樣的總線與其它設備連接,如圖。

較新的CPU中已經集成了內存控制器(memory controller),負責和內存之間的通信。外圍部件互連擴展(Peripheral Component Interconnect Express,PCI-E)總線一般用於連接顯卡(video card / graphics card),用於處理圖形;也可以連接固態硬盤(solid state drive,SSD)、網卡(network interface controller / network interface card,NIC,也稱網絡適配器(network adapter))甚至是聲卡(sound card)等其它設備。CPU與專門的I / O處理芯片(Intel稱爲平臺控制器(Platform Controller Hub,PCH))通過直接媒體接口(Direct Media Interface,DMI)連接。通用串行總線(Universal Serial Bus,USB)通常用於連接計算機以外的設備,集成在計算機內的一些設備也可能通過USB連接。硬盤有SATA接口的;支持NVMe協議的SSD大都連接M.2(較少爲U.2)接口,它們實際上都通過PCI-E進行傳輸;也有直接插在主板上的PCI-E插槽上的SSD。eSATA(外置SATA)和mSATA接口現在不多見。但是PCH提供的PCI-E的速率受DMI帶寬的嚴重製約,其實際速率並不如直連CPU的PCI-E。PCH提供的配合各種技術規範(PCI-E、SATA、USB)的通道並不能全部同時工作,同一條通道在同一時刻只能支持一種設備。支持何種設備則通過PCH芯片內的MUX選擇。

如圖,Intel的一顆PCH共有30條HSIO(High-speed IO)通道(lane)。雖然它設計了24條PCI-E通道,但是它們並不能同時啓用;有的PCH芯片只允許同時啓用16條甚至更少的PCI-E通道,導致帶寬(bandwidth,BW,這裏指數據的傳輸速率)驟降;一些通道選擇作爲USB或GbE(用於連接網卡)或SATA通道後,它們就不能再作爲PCI-E通道使用。而PCH提供的這些通道被用於哪些接口,則是主板(mainboard / motherboard)廠商的設計決定的。
總線具有層次性(hierarchy),工作速率最高的部件在總線上的位置離CPU最近。層次總線是性能和成本上的一種折中,因爲設計高性能總線是非常困難、非常昂貴的。

2、OS與IO設備之間,一種比較原始的交互方式大致具有如下幾個步驟:
(1)OS控制CPU去反覆讀寫IO設備中的狀態寄存器(稱爲輪詢(polling)),直到該寄存器的信息反映設備已就緒。
(2)OS將數據發送到設備的數據寄存器中。
(3)OS將需要執行的命令寫入設備的命令寄存器。這一步告訴設備:數據已準備好,需要開始執行指定的命令。
(4)OS等待設備完成操作。這也是通過輪詢完成的,最終讀取到成功的信息或錯誤碼。
在這個模式中,由於CPU直接參與數據傳輸,它被稱爲PIO(programmed I / O),CPU執行I / O端口指令來進行數據的讀寫。PIO模式實現簡單,但效率很低且不便。反覆的輪詢會導致很高的CPU佔用率,不但浪費大量CPU時間,而且這段時間還不能在該核心上切換其它進程繼續。當前,這種傳輸方式基本已經被淘汰。

3、中斷可以降低IO過程中的CPU佔用率。當有線程請求IO時,OS令其阻塞(進入睡眠),然後執行其它線程。當IO完成後,會產生一個硬件中斷,導致CPU執行相應的中斷處理程序,然後讓剛纔請求IO的進程繼續。中斷處理程序包含在操作系統中,它會完成相應的任務(例如處理數據或來自設備的錯誤碼)。
但中斷並不是所有時候都是最好的方案。如果一個IO設備執行任務非常快,可能在最初的幾次輪詢內就可以完成,那麼如果使用中斷,反而會降低系統的性能:線程切換、中斷處理和從中斷處理程序返回都需要耗費不少的時間。如果不知道設備到底快還是慢,則可以把兩種方法結合起來用:先輪詢一段較短的時間,如果設備仍未完成操作,再使用中斷。
此外,過多的中斷可能還會引發活鎖。例如在網絡應用中,有時會有大量的數據包發送給計算機。如果每來一個包都引發一次中斷,導致頻繁的切換動作,就增加了產生活鎖的概率。這一點還可能會被黑客利用,造成網絡服務器無法正常工作。更好的方法是允許較短時間的輪詢,並讓服務器處理完一連串的包以後再去檢查是否有新的數據包到來,而不是每來一個新的數據包都通過中斷來讓服務器立即處理它。
如果設備發起兩次中斷的間隔太短且中斷頻率又高,可以考慮將這些中斷合併爲單箇中斷,一次性處理較多的數據(操作)。當然,如果把太多的中斷都合併到一起,可能會明顯降低響應速率。這裏也要做好權衡。

4、即使有了中斷,CPU仍然需要親自將要複製的數據傳輸給設備,然後設備纔開始傳輸,CPU轉而執行其它任務。這個仍舊會帶來一定的CPU佔用率。解決的辦法是引入直接存儲訪問(direct memory access,DMA)。

有了 DMA機制以後,程序想傳輸數據時,OS就會令DMA控制器開始將數據複製給設備,然後開始傳輸。整個傳輸過程交由DMA控制器控制。傳輸完畢後,DMA控制器產生一箇中斷,OS就知道傳輸完成了。DMA負責傳輸期間,CPU具有更多的時間可以執行其它任務。

5、一種進行設備通信的方式是I / O指令。這些指令讓OS向設備的寄存器發送數據,並啓動傳輸過程。x86的in和out指令用於讀寫端口(port)。通過端口可以讀寫設備的寄存器,以此正式對設備發出IO請求。
當然,這些IO指令都是特權指令,只有操作系統有權執行。如果所有程序都可以不經過OS而直接執行IO指令,那麼計算機很容易被惡意程序破壞。
另一種方式是內存映射I / O(memory mapped I / O)。各設備的寄存器被映射到一定範圍的內存地址中,通過讀寫這部分內存來進行IO,就好像讀寫一般的內存空間那樣。
使用內存映射IO的方式進行設備通信,無需支持專門的IO指令。不過兩種方法到今天都一直有在使用。

6、每個設備都提供了不盡相同的接口,都具有不盡相同的工作方式。怎樣讓不同的設備都能夠與OS配合好呢?比如內置的機械硬盤(Hard disk drive,HDD)和SSD、U盤(USB flash drive)的工作原理不完全相同。有的SSD遵循AHCI(Advanced Host Controller Interface)協議,有的則遵循NVMe(Non-Volatile Memory Host)協議。我們希望它們在計算機上都能正常工作。這就要用到設備驅動(device driver),簡稱驅動(driver)。驅動也是一種抽象模型,能夠讓設備的硬件細節對操作系統透明(不可見),令操作系統將同一類設備(例如:存儲設備)基本一視同仁,減輕操作系統和上層應用程序的設計者的負擔:程序員們無需把各種各樣的設備的硬件細節都掌握就可以編寫代碼令它們正常工作。
下面是LINUX的文件系統棧的簡化模型:

我們可以看到,應用程序通過調用POSIX API來訪問文件系統,文件系統再通過塊接口繼續傳送,最後相應的指令傳到驅動層。一些特殊的應用程序,比如文件系統檢查器、磁盤碎片整理程序等,可以繞過文件系統進行讀寫。
硬盤是塊設備的一種,因爲數據的存取和傳輸都以塊爲單位,它們通過IO接口的一種——塊接口,與應用程序和操作系統進行通信。塊設備的傳輸速率通常比其它設備高很多。

在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章