一、什麼是Linux設備文件系統
首先我們不看定義,定義總是太抽象很難理解,我們先看現象。當我們往開發板上移植了一個新的文件系統之後(假如各種設備驅動也移植好了),啓動開發板,我們用串口工具進入開發板,查看系統/dev目錄,往往裏面沒有或者就只有null、console等幾個系統必須的設備文件在這兒外,沒有任何設備文件了。那我們移植好的各種設備驅動的設備文件怎麼沒有啊?如果要使用這些設備,那不是要一個一個的去手動的創建這些設備的設備文件節點,這給我們使用設備帶來了極爲的不便(在之前篇幅中講的各種設備驅動的移植都是這樣)。
設備文件系統就是給我們解決這一問題的關鍵,他能夠在系統設備初始化時動態的在/dev目錄下創建好各種設備的設備文件節點(也就是說,系統啓動後/dev目錄下就有了各種設備的設備文件,直接就可使用了)。除此之外,他還可以在設備卸載後自動的刪除/dev下對應的設備文件節點(這對於一些熱插拔設備很有用,插上的時候自動創建,拔掉的時候又自動刪除)。還有一個好處就是,在我們編寫設備驅動的時候,不必再去爲設備指定主設備號,在設備註冊時用0來動態的獲取可用的主設備號,然後在驅動中來實現創建和銷燬設備文件(一般在驅動模塊加載和卸載函數中來實現)。
二、設備文件系統的種類
設備文件系統有:devfs、udev、mdev等。
mdev是udev的簡化版本,是busybox中所帶的程序,最適合用在嵌入式系統,而udev一般都用在PC上的Linux中,相對mdev來說要複雜些;devfs是2.4內核引入的,而在2.6內核中卻被udev所替代,他們有着共同的優點,只是devfs中存在着一些未修復的bug,作者也停止了對他的維護,最顯著的一個區別是:採用devfs時,當一個並不存在的設備節點被打開時,他卻還能自動加載對應的驅動,而udev則不能,udev認爲當打開並不存在的設備節點時不應該加載對應的驅動模塊,因爲加載了也沒用,浪費系統資源。
三、udev或者mdev設備文件系統的使用
1. 首先讓大家明白一個問題就是,不管是udev還是mdev,他們就是一個應用程序,就跟其他應用程序一樣(比如:Boa服務),配置了就可以使用了。爲了方便起見,我們就使用busybox自帶的一個mdev,這樣在配置編譯busybox時,只要將mdev的支持選項選上,編譯後就包含了mdev設備文件系統的應用(當然你也可以不使用busybox自帶的,去下載udev的源碼進行編譯移植)
#cd busybox-1.13.0/
#make menuconfig
|
Linux System Utilities --->
[*] mdev
[*] Support /etc/mdev.conf
[*] Support subdirs/symlinks
[*] Support regular expressions substitutions when renaming device
[*] Support command execution at device addition/removal
|
2. udev或者mdev需要內核sysfs和tmpfs虛擬文件系統的支持,sysfs爲udev提供設備入口和uevent通道,tmpfs爲udev設備文件提供存放空間。所以在/etc/fstab配置文件中添加如下內容(紅色部分):
# device mount-point type options dump fsck order
#----------------------------------------------------------------
procfs /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
usbfs /proc/bus/usb usbfs defaults 0 0
ramfs /dev ramfs defaults 0 0
none /dev/pts devpts mode=0622 0 0
|
3. 在系統初始化配置文件/etc/init.d/rcS中掛載mdev要用到的sysfs文件系統和tmpfs文件系統,然後啓動/sbin目錄下的mdev應用對系統的設備進行搜索(紅色部分)。
# Mount virtual filesystem
/bin/mount -t proc procfs /proc /bin/mount -n -t sysfs sysfs /sys
/bin/mount -n -t usbfs usbfs /proc/bus/usb
/bin/mount -t ramfs ramfs /dev
# Make dir
/bin/mkdir -p /dev/pts /bin/mkdir -p /dev/shm /bin/mkdir -p /var/log
/bin/mount -n -t devpts none /dev/pts -o mode=0622 /bin/mount -n -t tmpfs tmpfs /dev/shm
# Make device node echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
|
4. 在設備驅動程序中加上對類設備接口的支持,即在驅動程序加載和卸載函數中實現設備文件的創建與銷燬,例如在之前篇幅的按鍵驅動中添加(
紅色部分):
#include <linux/device.h>
//設備類用到的頭文件
static
int device_major = DEVICE_MAJOR;
//用於保存系統動態生成的主設備號
static
struct
class *button_class;
//定義一個類
static int __init button_init(void) {
//註冊字符設備,這裏定義DEVICE_MAJOR=0,讓系統去分配,註冊成功後將返回動態分配的主設備號
device_major = register_chrdev(DEVICE_MAJOR, DEVICE_NAME,
&buttons_fops);
if(device_major
< 0)
{
printk(DEVICE_NAME
" register faild!/n");
return device_major;
}
//註冊一個設備類,使mdev可以在/dev/目錄下建立設備節點
button_class =
class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(button_class))
{
printk(DEVICE_NAME
" create class faild!/n"); return
-1; }
//創建一個設備節點,取名爲DEVICE_NAME(即my2440_buttons)
//注意2.6內核較早版本的函數名是class_device_create,現該爲device_create
device_create(button_class,
NULL,
MKDEV(device_major,
0),
NULL,
DEVICE_NAME);
return 0; }
static void __exit button_exit(void) {
//註銷字符設備
unregister_chrdev(device_major, DEVICE_NAME);
//刪除設備節點,注意2.6內核較早版本的函數名是class_device_destroy,現該爲device_destroy
device_destroy(button_class,
MKDEV(device_major,
0));
//註銷類
class_destroy(button_class); }
|
4. 至於mdev的配置文件/etc/mdev.conf,這個可有可無,只是設定設備文件的一些規則。我這裏就不管他了,讓他爲空好了。
5. 完成以上步驟後,重新編譯文件系統,下載到開發板上,啓動開發板後進入開發板的/dev目錄查看,就會有很多系統設備節點在這裏產生了,我們就可以直接使用這些設備節點了。