特种文件系统(4)
9.4 devfs和sysfs
devfs和sysfs它們來了,真的來了,一前一后來的,來得是那么突然,來得是那么悄無聲息。一個(gè)臉色蒼白,蒼白得讓人不寒而栗;一個(gè)眼光深邃,深邃的讓人頓覺謙卑。人們一直在談?wù)撝鼈?#xff0c;據(jù)說先來的已經(jīng)死了,死的很透徹,是被它的門人殺死的,而且居然是后來者收買了它的門人,后來的現(xiàn)在還在收買其他門派的門人,正在覬覦“武林盟主”的地位。所有的事情就這么潛移默化的變化著,輪替著。一切看似那么平靜,平靜得已經(jīng)讓讓很多人開始摩拳擦掌。在這平靜之中不知何時(shí)又要到來一場可怕的血雨腥風(fēng)。
故事是這樣開始的……
9.4.1 devfs的由來
Linux,或者說類UNIX系統(tǒng)最“酷”的地方是,設(shè)備不是簡單地隱藏在晦澀的API之后,而是真正的與普通文件、目錄或符號連接一樣,存在于文件系統(tǒng)之上(還記得我們前面說過的9號計(jì)劃嘛?正是發(fā)源于此)。因?yàn)樽址O(shè)備和塊設(shè)備是映射到普通文件系統(tǒng)名稱空間的,這樣人們就可以通過很簡單的文件讀寫方式與硬件交互。很多時(shí)候僅使用標(biāo)準(zhǔn)的Linux命令,如cat或dd,就足夠了。這些映射設(shè)備的文件被合理的組織在了/dev目錄下。
devfs,也叫設(shè)備文件系統(tǒng),它的唯一目的就是提供一個(gè)新的,更合理的方式管理那些位于/dev目錄下的所有塊設(shè)備和字符設(shè)備。因?yàn)榈湫偷?/span>Linux系統(tǒng)以一種不太理想,而且麻煩的方式管理這些特殊文件。
時(shí)至今日,Linux支持的硬件種類越來越多,也就意味著在/dev中的文件數(shù)量也越來越多,用數(shù)以萬計(jì)來說的確很夸張,但是要說數(shù)以千計(jì)、數(shù)以百計(jì)是絕對不過份的。只是這還不是問題的根本,最根本的是這些特殊文件是寫死的,而且大多數(shù)根本不會映射到系統(tǒng)中,因?yàn)樵購?fù)雜的服務(wù)器,撐死也就配備幾十個(gè)設(shè)備。顯然是使用99.9%的努力,只是為了解決0.1%的問題。況且誰也不敢保證用戶以后不添置什么設(shè)備,所以這些文件一個(gè)都不能動。
不過devfs誕生之際,情況沒有上面說的那么糟糕。就是因?yàn)?/span>devfs的生辰問題,導(dǎo)致了它日后的結(jié)局,我們祖先發(fā)明的生辰八字有些時(shí)候想想還是蠻有“科學(xué)”道理的。devfs誕生的太早了,它雖然對上面的問題做了一定的處理,但是有些不是很合理,具體我們后面還會說。現(xiàn)在要說的是,它解決了一個(gè)更要命的問題。什么問題呢?設(shè)備號的問題。傳統(tǒng)的Linux設(shè)備驅(qū)動程序,要向系統(tǒng)提供一個(gè)文件映射,需要提供一個(gè)主設(shè)備號,而且這個(gè)主設(shè)備號必須保證唯一。由于歷史原因,早些年內(nèi)存比黃金還貴,這個(gè)主設(shè)備號被設(shè)計(jì)的只有8位,顯然這是稀缺資源啊,在它面前,黃金都只能汗顏了。既然這樣,開發(fā)人員自然不能憑空臆造一個(gè)主設(shè)備號了,只能聯(lián)系Linux內(nèi)核的開發(fā)人員來申請,如果人家正忙著呢,那您就只能等,還不能歇,一歇就麻煩了,因?yàn)榈却暾埖娜硕嗔巳チ恕K?#xff0c;您就甘心的在那兒耗著吧。直到人家看你是個(gè)虔誠的主兒,偶發(fā)惻隱之心,給您分配了一個(gè)“正式”的主設(shè)備號,您才算萬事大吉收工交差。其實(shí)后面的事情遠(yuǎn)沒有這么簡單,只是那已經(jīng)是歷史,我就不多叨嘮了。至于這種策略的后果是什么,我不說,誰都知道。反正很難想象,早年的Linux用戶真是有夠虔誠,要不然現(xiàn)在還有誰會知道有Linux這個(gè)破玩意兒呢?
不管devfs的命運(yùn)如何,但就僅僅是把這個(gè)濫問題給解決了,就可以稱之為偉大,何況這只是其中的一個(gè)部分呢?
9.4.2 進(jìn)入devfs
devfs是怎么解決這個(gè)濫問題的呢?它給驅(qū)動開發(fā)人員提供了一個(gè)叫devfs_register()的內(nèi)核API,這個(gè)API可以接受一個(gè)設(shè)備名稱作為參數(shù)。調(diào)用成功后,在/dev目錄下就會出現(xiàn)與設(shè)備名相同的文件名。而且devfs_register仍然支持主設(shè)備號的策略,這樣可以保持向下兼容性,降低早期的設(shè)備驅(qū)動程序移植的復(fù)雜性。
一旦所有設(shè)備驅(qū)動程序啟動并向內(nèi)核注冊適當(dāng)?shù)脑O(shè)備,內(nèi)核就啟動/sbin/init進(jìn)程,系統(tǒng)初始化腳本開始執(zhí)行。在啟動過程初期,rc腳本將devfs文件系統(tǒng)安裝在/dev中,這樣/dev中就包含了devfs所表達(dá)的所有設(shè)備映射關(guān)系,所有注冊的設(shè)備依然可以通過/dev目錄進(jìn)行訪問,用戶應(yīng)用程序不用做任何修改。
這種設(shè)計(jì)的最大優(yōu)點(diǎn)就是:所有需要的設(shè)備映射關(guān)系都由內(nèi)核自動創(chuàng)建,因此也就不用寫死設(shè)備文件了,那么/dev目錄下就不會充斥著大量的無用的設(shè)備文件了。在實(shí)際應(yīng)用中,只要查看一下devfs,就能夠知道這個(gè)系統(tǒng)上有什么設(shè)備了。
devfs讓一切變得容易了許多。最典型的就是當(dāng)你編寫一個(gè)顯示實(shí)時(shí)系統(tǒng)信息的程序時(shí),不用做依次輪詢哪些設(shè)備是“活躍的”這樣費(fèi)時(shí)的工作。因?yàn)橹灰x取/dev下得所有信息就可以搞定。即便用戶只想查看某一個(gè)類型設(shè)備的信息,比如光驅(qū),根據(jù)devfs的約定,只需要讀取/dev/cdroms下的所有文件即可。
在實(shí)際操作中,比如你想訪問一個(gè)特定的塊設(shè)備,還有很多不同的途徑。例如:一個(gè)服務(wù)器上,只有一個(gè)SCSI光驅(qū);使用devfs后,就可用通過/dev/cdroms/cdrom0訪問;還通過使用/dev/scsi/host0/bus0/target4/lun0/cd訪問它。這兩種都映射了同一個(gè)設(shè)備,你可以選擇一個(gè)你認(rèn)為最方便的途徑。如果你愿意,還可以使用一種老式的設(shè)備名稱/dev/sr0訪問光驅(qū),這都是因?yàn)橛幸粋€(gè)非常便捷的叫devfsd的小程序在幕后完成的工作。這個(gè)程序雖然小,但是功能很多。它負(fù)責(zé)創(chuàng)建老式的“兼容性”設(shè)備映射文件,允許你一很多方式自定義/dev。
9.4.3 sysfs的由來
sysfs是后來的,收買了devfs的門徒,殺死了devfs,它用的不是錢和刀,是udev。還發(fā)表聲明公開了devfs該殺的四大罪狀。但是馬上就有人不服了:才四大罪狀,好多貪官100條大罪都犯下了,也沒判死刑不是?Linux是一個(gè)崇尚簡單的世界,只要有一條能夠說明你很麻煩,就有理由殺掉你,況四條大罪呼?那么這四條大罪是什么呢?
第一,不確定的設(shè)備映射,有時(shí)一個(gè)設(shè)備映射的設(shè)備文件可能不同,例如我的U盤,可能對應(yīng)sda也可能對應(yīng)sdb。
第二,沒有足夠的主/輔設(shè)備號,當(dāng)設(shè)備過多的時(shí)候,這就是一個(gè)問題。前面說過,雖然devfs已經(jīng)意識到了將來的設(shè)備會很多,但是沒處理好,沒有給主/輔設(shè)備號太多的擴(kuò)展余地。
第三,dev目錄下文件太多而且不能表示當(dāng)前系統(tǒng)上的實(shí)際設(shè)備(這個(gè)罪狀在我看來是有點(diǎn)牽強(qiáng)的,不過欲加之罪嘛)。
第四,命名不夠靈活,不能任意指定。
于是devfs死了,sysfs成為了新的“幫主”。那么sysfs究竟是什么來頭呢?系出名門,出身高貴啊。
最初,當(dāng)人們已經(jīng)開始意識到procfs的復(fù)雜度之后,就開始想將procfs中有關(guān)設(shè)備的部分獨(dú)立出來。最開始采用ramfs(這個(gè)可以看作是RamDisk和tmpfs的中間產(chǎn)品)作為基礎(chǔ),名曰ddfs,后來發(fā)現(xiàn)driverfs更為貼切。這些都是在2.5版本中內(nèi)核鼓搗的。按照那個(gè)時(shí)候的內(nèi)核版本號的規(guī)則,所有第二位為奇數(shù)的版本都是實(shí)驗(yàn)版,所以2.5這個(gè)內(nèi)核版本對于大眾來說是不多見的。driverfs把實(shí)際連接到系統(tǒng)上的設(shè)備和總線組織成一個(gè)分級的文件,和devfs相同,用戶空間的程序同樣可以利用這些信息以實(shí)現(xiàn)和內(nèi)核的交互(這個(gè)思路來自procfs),該系統(tǒng)是當(dāng)前實(shí)際設(shè)備樹的一個(gè)直觀反映。到了2.6內(nèi)核,也就是2.5的最終成型版本,新設(shè)計(jì)了一個(gè)kobject子系統(tǒng),它就改變了實(shí)現(xiàn)策略拋棄了ramfs,利用kobject子系統(tǒng)來建立這些信息。當(dāng)一個(gè)kobject被創(chuàng)建的時(shí)候,對應(yīng)的文件和目錄也就被創(chuàng)建了,位于/sys下的相關(guān)目錄下。因此更名為sysfs。因?yàn)楸旧砭驮醋杂?/span>procfs的設(shè)計(jì)思路,因此它所提供的也是用戶空間與系統(tǒng)空間交換信息的接口。用戶空間工具udev就是利用了sysfs提供的信息在用戶空間實(shí)現(xiàn)了與devfs完全相同的功能。既然功能相同,而且是在用戶空間實(shí)現(xiàn),顯然比在內(nèi)核空間實(shí)現(xiàn)的devfs要簡單的多,安全得多,也會穩(wěn)定的多。devfs被殺,也許這就是它的宿命。
9.4.4 小結(jié)
其實(shí)sysfs和devfs做比拼已經(jīng)沒有實(shí)際的意義了,因?yàn)楝F(xiàn)在顯然已經(jīng)沒有任何爭端了。只是我想展現(xiàn)給大家還是開篇的一個(gè)主題:新的系統(tǒng)并不是只為了做同樣的事情比老的系統(tǒng)快一點(diǎn),還應(yīng)該允許我們用以前完全不可能的方法來處理事情。
顯然sysfs能夠?qū)崿F(xiàn)全部devfs的功能,而且是在用戶空間完成的。不單單是這樣。當(dāng)一部并不存在的/dev節(jié)點(diǎn)被打開的時(shí)候,devfs會很負(fù)責(zé)的去加載這個(gè)驅(qū)動程序,sysfs卻不會做這種傻事。不過也不能說devfs傻,應(yīng)該說它敬業(yè),要很負(fù)責(zé)的告訴用戶,這個(gè)設(shè)備不存在,但是它沒有好的機(jī)制去做,只能用笨方法,讓驅(qū)動程序?qū)嶋H去監(jiān)測設(shè)備來報(bào)告這個(gè)結(jié)果。sysfs如果只是做到這些,應(yīng)該還是不能足以收買devfs的門徒的,sysfs還能給內(nèi)核產(chǎn)生的設(shè)備名增加別名,好處就是用戶可以用自己喜歡的名字,顯然對用戶很友好。sysfs真正的徹底解決了devfs遇到的所有問題。
devfs和sysfs的故事講到這里也該結(jié)束了。在如今的Linux發(fā)行版中,你再也找不到devfs的影子了,但是procfs和sysfs還在。sysfs如今大紅大紫,procfs的命運(yùn)如何,還需要你我共同的期待。
轉(zhuǎn)載于:https://blog.51cto.com/jagen/1324370
總結(jié)
- 上一篇: 在TextView中添加图片属性
- 下一篇: 8.1个Windows 8.1的不足之处