|
Udev 使用Udev: 1、首先從sysfs的相關(guān)文件中獲取文件屬性。假設(shè)DVD:/dev/sr0,CD-RW:/dev/sr1。使用udevinfo來收集設(shè)備信息。bash> udevinfo -a -p /sys/block/sr0 Code View: bash> udevinfo -a -p /sys/block/sr0 ... looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4': BUS=?usb? ID=?1-4? SYSFS{bConfigurationValue}=?1? ... SYSFS{idProduct}=?0701? SYSFS{idVendor}=?05e3? SYSFS{manufacturer}=?Genesyslogic? SYSFS{maxchild}=?0? SYSFS{product}=?USB Mass Storage Device? ... bash> udevinfo -a -p /sys/block/sr1 ... looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-3': BUS=?usb? ID=?1-3? SYSFS{bConfigurationValue}=?2? ... SYSFS{idProduct}=?0302? SYSFS{idVendor}=?0dbf? SYSFS{manufacturer}=?Addonics? SYSFS{maxchild}=?0? SYSFS{product}=?USB to IDE Cable? ... 2、使用收集的產(chǎn)品信息來辨別設(shè)備并加入udev命名規(guī)則,創(chuàng)建一個/etc/udev/rules.d/40-cdvd.rules并加入如下規(guī)則: BUS="usb", SYSFS{idProduct}="0701", SYSFS{idVendor}="05e3",
KERNEL="sr[0-9]*", NAME="%k", SYMLINK="usbdvd"
BUS="usb", SYSFS{idProduct}="0302", SYSFS{idVendor}="0dbf",
KERNEL="sr[0-9]*", NAME="%k", SYMLINK="usbcdrw"規(guī)則1的意思是:無論何時它發(fā)現(xiàn)一個產(chǎn)品id為0x0701,vender ID是0x05e3,而且名字以sr開頭的usb設(shè)備,都會在/dev下創(chuàng)建一個同名的節(jié)點,并produce一個命名為usbdvd的符號鏈接給那個節(jié)點。 為了測試您規(guī)則中的語法錯誤,在/sys/block/sr*上運行udevtest。為了打開/var/log/messages的verbose messages,設(shè)置/etc/udev/udev.conf中的udev_log為"yes".為使新加入的規(guī)則在/dev下生效,使用udevstart重啟udev,然后您的dvd驅(qū)動會標(biāo)識為/dev/usbdvd。您可以使用mount /dev/usbdvd /mnt/dvd來掛載。 udev的其他功能:Linux熱插拔管理、自動按需加載模塊、下載微代碼到需要的設(shè)備。 Sysfs, Kobjects,and Device Classes 一般用于bus和內(nèi)核實現(xiàn)領(lǐng)域,隱藏在提供給設(shè)備驅(qū)動的API服務(wù)中。 sysfs是內(nèi)核架構(gòu)設(shè)備模型的用戶空間實現(xiàn),和procfs一樣都是內(nèi)存文件系統(tǒng),包含了內(nèi)核數(shù)據(jù)結(jié)構(gòu)的相關(guān)信息。procfs是內(nèi)核的一般性質(zhì)的窗口,而sysfs則專注于設(shè)備模型。sysfs不是用于替代procfs,因為進(jìn)程描述符信息和sysctl參數(shù)都屬于procfs,而非sysfs。udev依賴于sysfs實現(xiàn)大部分功能。 kobjects常嵌入在大的結(jié)構(gòu)體里面,主要包括kref(參數(shù)計數(shù)管理,kref_init初始化,kref_get()增加計數(shù),kref_put()減少計數(shù),并在計數(shù)為0的時候釋放kobject),指向所屬kset的指針,kobj_type(描述kobject類型);kobjects與sysfs密切相關(guān),每個內(nèi)核instantiated的kobject都有一個sysfs representation。 設(shè)備類是驅(qū)動中能用到的另一個接口,類接口抽象了認(rèn)為每一個設(shè)備都會屬于一個設(shè)備類中,如usb鼠標(biāo)、PS/2鍵盤等屬于輸入類,而且在/sys/class/input/下?lián)碛薪涌凇?/PRE>
類編程接口建立在kobjects和sysfs之上,讓我們來看一下RTC: bash> modprobe rtc bash> ls -lR /sys/class/misc drwr-xr-x 2 root root 0 Jan 15 01:23 rtc /sys/class/misc/rtc: total 0 -r--r--r-- 1 root root 4096 Jan 15 01:23 dev --w------- 1 root root 4096 Jan 15 01:23 uevent bash> ls -l /dev/rtc crw-r--r-- 1 root root 10, 135 Jan 15 01:23 /dev/rtc /sys/class/misc/rtc/dev包含了設(shè)備的主次設(shè)備號,/sys/class/misc/rtc/uevent用于coldplugging,/dev/rtc被應(yīng)用程序用于訪問RTC驅(qū)動。Misc驅(qū)動使用misc_register()初始化,里面的代碼和下面的類似: /* ... */
dev = MKDEV(MISC_MAJOR, misc->minor);
misc->class = class_device_create(misc_class, NULL, dev,
misc->dev,
"%s", misc->name);
if (IS_ERR(misc->class)) {
err = PTR_ERR(misc->class);
goto out;
}
/* ... */
下圖展示了在classes、kobjects、sysfs和udev之間的轉(zhuǎn)換,最終導(dǎo)致了/sys和/dev里面的文件的產(chǎn)生。 另外一個好的抽象是bus-device-driver編程接口。以I2C為例,I2C核心層對監(jiān)測到的每一個I2C總線適配器使用bus_register()注冊,當(dāng)I2C客戶端設(shè)備如EEPROM被監(jiān)測到時,由device_register()注冊,最終I2C EEPROM客戶端驅(qū)動程序使用driver_register()注冊自身,這些注冊直接使用I2C核提供的服務(wù)。bus_register()會在/sys/bus增加入口,device_register()在/sys/devices下增加入口,struct bus_type,struct device,struct device_driver是主要使用的數(shù)據(jù)結(jié)構(gòu)。 Hotplug和Coldplug 在系統(tǒng)運行時動態(tài)接入的設(shè)備叫熱插拔設(shè)備,而在系統(tǒng)啟動前就事先接入的叫冷插拔設(shè)備。在以前內(nèi)核使用在/proc中注冊的輔助程序通知用戶空間有設(shè)備接入,而現(xiàn)在當(dāng)內(nèi)核監(jiān)測到熱插拔時,它們使用netlink sockets向用戶空間發(fā)送uevents。netlink是內(nèi)核和用戶空間通信的有效工具,在用戶空間管理設(shè)備節(jié)點創(chuàng)建和刪除的udevd接收到uevents并管理hotplug。以下是熱插拔的發(fā)展歷程:1、在初始化時,驅(qū)動喚醒request_firmware(..,"ipw2100-1.3.fw",..);2、這dispatch一個熱插拔uevent to用戶空間,along with the identity of the requested microcode image。3、Udevd接收到uevent并responds by invoking /sbin/firmware_helper,對于這點,它使用如下在/etc/udev/rules.d/下面的類似的規(guī)則:ACTION=="add", SUBSYSTEM=="firmware", RUN="/sbin/firmware_helper"4、/sbin/firmware_helper進(jìn)入/lib/firmware/并且定位微代碼Image ipw2100-1.3.fw。它dumps the image to /sys/class/0000:02:02.0/data(0000:02:02是PCI bus:device:function,是WiFi卡的標(biāo)記);5、驅(qū)動接收到微代碼并且把它下載到設(shè)備,當(dāng)完成后,它調(diào)用release_firmware()來釋放相應(yīng)的數(shù)據(jù)結(jié)構(gòu)。6、驅(qū)動執(zhí)行剩下的初始化和WiFi適配器。Module Autoload自動按需下載內(nèi)核模塊是Linux支持的有效特性,為理解內(nèi)核如何發(fā)出"module fault"并且udev如何處理它,讓我插入Xircom CardBus Ethernet adapter into a laptop's PC Card slot: 1、在編譯時,對所支持設(shè)備的辨別就作為驅(qū)動模塊對象的一部分產(chǎn)生,如drivers/net/tulip/xircom_cb.c下的: 這聲明了該驅(qū)動支持任意PCI vender ID為0x115D和PCI device ID為0x0003的卡,當(dāng)您安裝了該驅(qū)動模塊后,depmod工具查看module image并且解釋在device table里面的ID,然后將下面的entry加入 /lib/modules/kernel-version/modules.alias:alias pci:v0000115Dd00000003sv*sd*bc*sc*i* xircom_cb,這里v表示VenderID,d代表DeviceID,sv代表subvenderID,*代表通配。
2、當(dāng)您在CardBus插槽中熱插拔Xircom card時,內(nèi)核產(chǎn)生一個uevent聲稱對新插入設(shè)備的辨認(rèn)。您可以使用udevmonitor來查看產(chǎn)生的uevent: bash> udevmonitor --env 3、Udevd經(jīng)netlink socket接收到uevent,并喚醒modprobe with 上述的內(nèi)核傳遞給它的MODALIAS。 modprobe pci:v0000115Dd00000003sv0000115Dsd00001181bc02sc00i00 4、modprobe在/lib/modules/kernel-version/modules.alias中發(fā)現(xiàn)相符的entry,并進(jìn)而插入xircom_cb: 現(xiàn)在該card就可以上網(wǎng)沖浪了。 一部分不支持在嵌入式設(shè)備上使用Udev的原因:
|
|
|