Unix操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序的基本結(jié)構(gòu)
學(xué)習(xí)了很多關(guān)于Unix操作系統(tǒng)的知識(shí),今天我們來(lái)講解下Unix操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序的基本結(jié)構(gòu)的知識(shí)。在Unix操作系統(tǒng)里,對(duì)用戶程序而言,設(shè)備程序隱藏了設(shè)備的具體細(xì)節(jié),對(duì)各種不同設(shè)備提供了一致的接口,一般來(lái)說(shuō)是把設(shè)備映射為一個(gè)特殊的設(shè)備文件,用戶程序可以象對(duì)其它文件一樣對(duì)此設(shè)備文件進(jìn)行操作。
Unix操作系統(tǒng)對(duì)設(shè)備支持兩個(gè)標(biāo)準(zhǔn)接口:塊特別設(shè)備文件和字符特別設(shè)備文件,通過(guò)塊(字符)特別設(shè)備文件存取的設(shè)備稱為塊(字符)設(shè)備或具有塊(字符)設(shè)備接口。
塊設(shè)備接口僅支持面向塊的I/O操作,所有I/O操作都通過(guò)在內(nèi)核地址空間中的I/O緩沖區(qū)進(jìn)行,它可以支持幾乎任意長(zhǎng)度和任意位置上的I/O請(qǐng)求,即提供隨機(jī)存取的功能。字符設(shè)備接口支持面向字符的I/O操作,它不經(jīng)過(guò)Unix操作系統(tǒng)的快速緩存,所以它們負(fù)責(zé)管理自己的緩沖區(qū)結(jié)構(gòu)。字符設(shè)備接口只支持順序存取的功能,一般不能進(jìn)行任意長(zhǎng)度的I/O請(qǐng)求,而是限制I/O請(qǐng)求的長(zhǎng)度必須是設(shè)備要求的基本塊長(zhǎng)的倍數(shù)。
顯然,本程序所驅(qū)動(dòng)的串行卡只能提供順序存取的功能,屬于是字符設(shè)備,因此后面的討論在兩種設(shè)備有所區(qū)別時(shí)都只涉及字符型設(shè)備接口。設(shè)備由一個(gè)主設(shè)備號(hào)和一個(gè)次設(shè)備號(hào)標(biāo)識(shí)。主設(shè)備號(hào)唯一標(biāo)識(shí)了設(shè)備類型,即設(shè)備驅(qū)動(dòng)程序類型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表項(xiàng)的索引。次設(shè)備號(hào)僅由設(shè)備驅(qū)動(dòng)程序解釋,一般用于識(shí)別在若干可能的硬件設(shè)備中,I/O請(qǐng)求所涉及到的那個(gè)設(shè)備。
Unix操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序可以分為三個(gè)主要組成部分:
1 自動(dòng)配置和初始化子程序,負(fù)責(zé)檢測(cè)所要驅(qū)動(dòng)的硬件設(shè)備是否存在和是否能正常工作。如果該設(shè)備正常,則對(duì)這個(gè)設(shè)備及其相關(guān)的、設(shè)備驅(qū)動(dòng)程序需要的軟件狀態(tài)進(jìn)行初始化。這部分驅(qū)動(dòng)程序僅在初始化的時(shí)候被調(diào)用一次。
2 服務(wù)于I/O請(qǐng)求的子程序,又稱為驅(qū)動(dòng)程序的上半部分。調(diào)用這部分是由于系統(tǒng)調(diào)用的結(jié)果。這部分程序在執(zhí)行的時(shí)候,系統(tǒng)仍認(rèn)為是和進(jìn)行調(diào)用的進(jìn)程屬于同一個(gè)進(jìn)程,只是由用戶態(tài)變成了核心態(tài),具有進(jìn)行此Unix操作系統(tǒng)調(diào)用的用戶程序的運(yùn)行環(huán)境,因此可以在其中調(diào)用sleep等與進(jìn)程運(yùn)行環(huán)境有關(guān)的函數(shù)。
3 中斷服務(wù)子程序,又稱為驅(qū)動(dòng)程序的下半部分。在Unix操作系統(tǒng)中,并不是直接從中斷向量表中調(diào)用設(shè)備驅(qū)動(dòng)程序的中斷服務(wù)子程序,而是由Unix操作系統(tǒng)來(lái)接收硬件中斷,再由系統(tǒng)調(diào)用中斷服務(wù)子程序。
中斷可以產(chǎn)生在任何一個(gè)進(jìn)程運(yùn)行的時(shí)候,因此在中斷服務(wù)程序被調(diào)用的時(shí)候,不能依賴于任何進(jìn)程的狀態(tài),也就不能調(diào)用任何與進(jìn)程運(yùn)行環(huán)境有關(guān)的函數(shù)。因?yàn)樵O(shè)備驅(qū)動(dòng)程序一般支持同一類型的若干設(shè)備,所以一般在系統(tǒng)調(diào)用中斷服務(wù)子程序的時(shí)候,都帶有一個(gè)或多個(gè)參數(shù),以唯一標(biāo)識(shí)請(qǐng)求服務(wù)的設(shè)備。
在Unix操作系統(tǒng)內(nèi)部,I/O設(shè)備的存取通過(guò)一組固定的入口點(diǎn)來(lái)進(jìn)行,這組入口點(diǎn)是由每個(gè)設(shè)備的設(shè)備驅(qū)動(dòng)程序提供的。一般來(lái)說(shuō),字符型設(shè)備驅(qū)動(dòng)程序能夠提供如下幾個(gè)入口點(diǎn):
1 open入口點(diǎn)。打開設(shè)備準(zhǔn)備I/O操作。對(duì)字符特別設(shè)備文件進(jìn)行打開操作,都會(huì)調(diào)用設(shè)備的open入口點(diǎn)。open子程序必須對(duì)將要進(jìn)行的I/O操作做好必要的準(zhǔn)備工作,如清除緩沖區(qū)等。如果設(shè)備是獨(dú)占的,即同一時(shí)刻只能有一個(gè)程序訪問(wèn)此設(shè)備,則open子程序必須設(shè)置一些標(biāo)志以表示設(shè)備處于忙狀態(tài)。
2 close入口點(diǎn)。關(guān)閉一個(gè)設(shè)備。當(dāng)***一次使用設(shè)備終結(jié)后,調(diào)用close子程序。獨(dú)占設(shè)備必須標(biāo)記設(shè)備可再次使用。
3 read入口點(diǎn)。從設(shè)備上讀數(shù)據(jù)。對(duì)于有緩沖區(qū)的I/O操作,一般是從緩沖區(qū)里讀數(shù)據(jù)。對(duì)字符特別設(shè)備文件進(jìn)行讀操作將調(diào)用read子程序。
4 write入口點(diǎn)。往設(shè)備上寫數(shù)據(jù)。對(duì)于有緩沖區(qū)的I/O操作,一般是把數(shù)據(jù)寫入緩沖區(qū)里。對(duì)字符特別設(shè)備文件進(jìn)行寫操作將調(diào)用write子程序。
5 ioctl入口點(diǎn)。執(zhí)行讀、寫之外的操作。
6 select入口點(diǎn)。檢查設(shè)備,看數(shù)據(jù)是否可讀或設(shè)備是否可用于寫數(shù)據(jù)。select系統(tǒng)調(diào)用在檢查與設(shè)備特別文件相關(guān)的文件描述符時(shí)使用select入口點(diǎn)。如果設(shè)備驅(qū)動(dòng)程序沒(méi)有提供上述入口點(diǎn)中的某一個(gè),系統(tǒng)會(huì)用缺省的子程序來(lái)代替。對(duì)于不同的Unix操作系統(tǒng),也還有一些其它的入口點(diǎn)。
好了,關(guān)于Unix操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序的基本結(jié)構(gòu)的知識(shí),我們今天就講解到這里,以后希望有更多的機(jī)會(huì)來(lái)和大家來(lái)探討。
【編輯推薦】