Linux 文件系统与设备文件系统 (一)—— udev 设备文件系统
一、什么是Linux設備文件系統
? ? ? 首先我們不看定義,定義總是太抽象很難理解,我們先看現象。當我們往開發板上移植了一個新的文件系統之后(假如各種設備驅動也移植好了),啟動開發板,我們用串口工具進入開發板,查看系統/dev目錄,往往里面沒有或者就只有null、console等幾個系統必須的設備文件在這兒外,沒有任何設備文件了。那我們移植好的各種設備驅動的設備文件怎么沒有啊?如果要使用這些設備,那不是要一個一個的去手動的創建這些設備的設備文件節點,這給我們使用設備帶來了極為的不便(在之前篇幅中講的各種設備驅動的移植都是這樣)。
? ? ? 設備文件系統就是給我們解決這一問題的關鍵,他能夠在系統設備初始化時動態的在/dev目錄下創建好各種設備的設備文件節點(也就是說,系統啟動后/dev目錄下就有了各種設備的設備文件,直接就可使用了)。除此之外,他還可以在設備卸載后自動的刪除/dev下對應的設備文件節點(這對于一些熱插拔設備很有用,插上的時候自動創建,拔掉的時候又自動刪除)。還有一個好處就是,在我們編寫設備驅動的時候,不必再去為設備指定主設備號,在設備注冊時用0來動態的獲取可用的主設備號,然后在驅動中來實現創建和銷毀設備文件(一般在驅動模塊加載和卸載函數中來實現)。
二、關于udev
? ? ? ?2.4 內核使用devfs(設備文件系統)在設備初始化時創建設備文件,設備驅動程序可以指定設備號、所有者、用戶空間等信息,devfs 運行在內核環境中,并有不少缺點:可能出現主/輔設備號不夠,命名不靈活,不能指定設備名稱等問題。
? ? ? 而自2.6 內核開始,引入了sysfs 文件系統。sysfs 把連接在系統上的設備和總線組織成一個分級的文件,并提供給用戶空間存取使用。udev 運行在用戶模式,而非內核中。udev 的初始化腳本在系統啟動時創建設備節點,并且當插入新設備——加入驅動模塊——在sysfs上注冊新的數據后,udev會創新新的設備節點。
? ? ?udev 是一個工作在用戶空間的工具,它能根據系統中硬件設備的狀態動態的更新設備文件,包括設備文件的創建,刪除,權限等。這些文件通常都定義在/dev 目錄下,但也可以在配置文件中指定。udev 必須內核中的sysfs和tmpfs支持,sysfs 為udev 提供設備入口和uevent 通道,tmpfs 為udev 設備文件提供存放空間。
? ? 注意,udev 是通過對內核產生的設備文件修改,或增加別名的方式來達到自定義設備文件的目的。但是,udev 是用戶模式程序,其不會更改內核行為。也就是說,內核仍然會創建sda,sdb等設備文件,而udev可根據設備的唯一信息來區分不同的設備,并產生新的設備文件(或鏈接)。而在用戶的應用中,只要使用新產生的設備文件即可。
? ??
三、udev和devfs設備文件的對比
? ? ? ?提到udev,不能不提的就是devfs,下面看一下udev 與 devfs 的區別:
1、udev能夠實現所有devfs實現的功能。但udev運行在用戶模式中,而devfs運行在內核中。
2、當一個并不存在的 /dev 節點被打開的時候, devfs一樣自動加載驅動程序而udev確不能。udev設計時,是在設備被發現的時候加載模塊,而不是當它被訪問的時候。?devfs這個功能對于一個配置正確的計算機是多余的。系統中所有的設備都應該產生hotplug 事件、加載恰當的驅動,而 udev 將會注意到這點并且為它創建對應的設備節點。如果你不想讓所有的設備驅動停留在內存之中,應該使用其它東西來?管理你的模塊 (如腳本, modules.conf, 等等) 。其中devfs 用的方法導致了大量無用的 modprobe 嘗試,以此程序探測設備是否存在。每個試探性探測都新建一個運行 modprobe 的進程,而幾乎所有這些都是無用的
3、udev是通過對內核產生的設備名增加別名的方式來達到上述目的的。前面說過,udev是用戶模式程序,不會更改內核的行為。
? ? ? ?因此,內核依然會我行我素地產生設備名如sda,sdb等。但是,udev可以根據設備的其他信息如總線(bus),生產商(vendor)等不同來區分不同的設備,并產生設備文件。udev只要為這個設備文件取一個固定的文件名就可以解決這個問題。在后續對設備的操作中,只要引用新的設備名就可以了。但為了保證最大限度的兼容,一般來說,
新設備名總是作為一個對內核自動產生的設備名的符號鏈接(link)來使用的。
? ? ?例如:內核產生了sda設備名,而根據信息,這個設備對應于是我的內置硬盤,那我就可以制定udev規則,讓udev除了產生/dev/sda設備文件 外,另外創建一個符號鏈接叫/dev/internalHD。這樣,我在fstab文件中,就可以用/dev/internalHD來代替原來的 /dev/sda了。下次,由于某些原因,這個硬盤在內核中變成了sdb設備名了,那也不用著急,udev還會自動產生/dev/internalHD這 個鏈接,并指向正確的/dev/sdb設備。所有其他的文件像fstab等都不用修改。
? ? 而在在2.6內核以前一直使用的是 devfs,devfs掛載于/dev目錄下,提供了一種類似于文件的方法來管理位于/dev目錄下的所有設備,但是devfs文件系統有一些缺點,例 如:不確定的設備映射,有時一個設備映射的設備文件可能不同,例如我的U盤可能對應sda有可能對應sdb 。
四、udev 的工作流程圖
? ? ? ?下面先看一張流程圖:
? ? ? ? 前面提到設備文件系統udev的工作過程依賴于sysfs文件系統。udev文件系統在用戶空間工作,它可以根據sysfs文件系統導出的信息(設備號(dev)等),動態建立和刪除設備文件。
? ? ? ? sysfs文件系統特點:sysfs把連接在系統上的設備和總線組織成為一個分級的目錄及文件,它們可以由用戶空間存取,向用戶空間導出內核數據結構以及它們的屬性,這其中就包括設備的主次設備號。
? ? ? ?
? ? ? 那么udev 是如何建立設備文件的呢?
a --?對于已經編入內核的驅動程序
? ?當被內核檢測到的時候,會直接在 sysfs 中注冊其對象;對于編譯成模塊的驅動程序,當模塊載入的時候才會這樣做。一旦掛載了 sysfs 文件系統(掛載到 /sys),內建的驅動程序在 sysfs 注冊的數據就可以被用戶空間的進程使用,并提供給 udev 以創建設備節點。
? ? udev 初始化腳本負責在 Linux 啟動的時候創建設備節點,該腳本首先將 /sbin/udevsend 注冊為熱插拔事件處理程序。熱插拔事件本不應該在這個階段發生,注冊 udev 只是為了以防萬一。
? ?然后?udevstart 遍歷 /sys 文件系統(其屬性文件dev中記錄這設備的主設備號,與次設備號),并在 /dev 目錄下創建符合描述的設備文件。
? 例如,/sys/class/tty/vcs/dev 里含有"7:0"字符串,udevstart 就根據這個字符串創建主設備號為 7 、次設備號為 0 的 /dev/vcs 設備。udevstart 創建的每個設備的名字和權限由 /etc/udev/rules.d/ 目錄下的文件指定的規則來設置。如果 udev 找不到所創建設備的權限文件,就將其權限設置為缺省的 660 ,所有者為 root:root 。
b --?編譯成模塊的驅動程序
? ? ? 前面我們提到了"熱插拔事件處理程序"的概念,當內核檢測到一個新設備連接時,內核會產生一個熱插拔事件,并在 /proc/sys/kernel/hotplug 文件里查找處理設備連接的用戶空間程序。udev 初始化腳本將 udevsend 注冊為該處理程序。當產生熱插拔事件的時候,內核讓 udev 在 /sys 文件系統里檢測與新設備的有關信息,并為新設備在 /dev 里創建項目。
? ? ?大多數 Linux 發行版通過 /etc/modules.conf 配置文件來處理模塊加載,對某個設備節點的訪問導致相應的內核模塊被加載。對 udev 這個方法就行不通了,因為在模塊加載前,設備節點根本不存在。為了解決這個問題,在 LFS-Bootscripts 軟件包里加入了 modules 啟動腳本,以及 /etc/sysconfig/modules 文件。通過在 modules 文件里添加模塊名,就可以在系統啟動的時候加載這些模塊,這樣 udev 就可以檢測到設備,并創建相應的設備節點了。如果插入的設備有一個驅動程序模塊但是尚未加載,Hotplug 軟件包就有用了,它就會響應上述的內核總線驅動熱插拔事件并加載相應的模塊,為其創建設備節點,這樣設備就可以使用了。
五、創建和配置mdev
? ? ? ???mdev是udev的簡化版本,是busybox中所帶的程序,最適合用在嵌入式系統,而udev一般都用在PC上的Linux中,相對mdev來說要復雜些;
1、我們應該明白,不管是udev還是mdev,他們就是一個應用程序,就跟其他應用程序一樣(比如:Boa服務),配置了就可以使用了。為了方便起見,我們就使用busybox自帶的一個mdev,這樣在配置編譯busybox時,只要將mdev的支持選項選上,編譯后就包含了mdev設備文件系統的應用(當然你也可以不使用busybox自帶的,去下載udev的源碼進行編譯移植。
| #cd busybox-1.13.0/ |
| Linux System Utilities ---> |
2、 udev或者mdev需要內核sysfs和tmpfs虛擬文件系統的支持,sysfs為udev提供設備入口和uevent通道,tmpfs為udev設備文件提供存放空間。所以在/etc/fstab配置文件中添加如下內容(紅色部分):
| # device??mount-point?????type??????options????dump????fsck order |
3.、在系統初始化配置文件/etc/init.d/rcS中掛載mdev要用到的sysfs文件系統和tmpfs文件系統,這個在我們介紹根文件系統時已經看到:
? ? ?然后啟動/sbin目錄下的mdev應用對系統的設備進行搜索(紅色部分)。
| # Mount virtual filesystem |
a --?" mdev -s?" 的含義是掃描 /sys 中所有的類設備目錄,如果在目錄中有含有名為“dev”的文件,且文件中包含的是設備號,則mdev就利用這些信息為該設備在/dev下創建設備節點文件;
b --?"echo /sbin/mdev > /proc/sys/kernel/hotplug"?的含義是當有熱插拔事件產生時,內核就會調用位于 /sbin 目錄的 mdev 。這時 mdev 通過環境變量中的 ACTION 和DEVPATH,來確定此次熱插拔事件的動作以及影響了 /sys 中的那個目錄。接著,會看這個目錄中是否有“dev”的屬性文件。如果有就利用這些信息為這個設備在 /dev 下創建設備節點文件。
4、在設備驅動程序中加上對類設備接口的支持,即在驅動程序加載和卸載函數中實現設備文件的創建與銷毀,這個在我們前面Linux 字符設備驅動結構(二)—— 自動創建設備節點?可以看到實例,下面在介紹一個
? ? ?例如在之前篇幅的按鍵驅動中添加(紅色部分):
[cpp]?view plaincopy
5、至于mdev的配置文件/etc/mdev.conf,這個可有可無,只是設定設備文件的一些規則。我這里就不管他了,讓他為空好了。
?
6、完成以上步驟后,重新編譯文件系統,下載到開發板上,啟動開發板后進入開發板的/dev目錄查看,就會有很多系統設備節點在這里產生了,我們就可以直接使用這些設備節點了。
總結
以上是生活随笔為你收集整理的Linux 文件系统与设备文件系统 (一)—— udev 设备文件系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据密集型系统设计pdf下载
- 下一篇: Exynos4412 Uboot 移植(