小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Linux設(shè)備驅(qū)動模型

 lchjczw 2012-03-10

Udev
       先前所需的硬件文件節(jié)點都需要在/dev下靜態(tài)創(chuàng)建,隨2.4核而來的devfs,帶來了動態(tài)設(shè)備節(jié)點創(chuàng)建。Devfs雖然提供了in-memory filesystem創(chuàng)建節(jié)點的方法,但是節(jié)點命名依然取決于設(shè)備驅(qū)動。命名管理和內(nèi)核結(jié)合的不好,The place for policy is in header files, kernel module parameters, or user space。Udev將設(shè)備管理交給用戶空間。
      Udev依賴于以下技術(shù):(1)、內(nèi)核sysfs支持,sysfs啟動時掛載到/sys下(可查看/etc/fstab);(2)、一系列用戶空間工具:udevd和udevinfo;(3)、定義在/etc/udev/rules.d/目錄下的用戶定義規(guī)則

使用Udev:

1、首先從sysfs的相關(guān)文件中獲取文件屬性。假設(shè)DVD:/dev/sr0,CD-RW:/dev/sr1。使用udevinfo來收集設(shè)備信息。bash> udevinfo -a -p /sys/block/sr0

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>
Figure 4.4. Sysfs hierarchy of a USB mouse.

[/sys]
     +[block]
     -[bus]—[usb]—[devices]—[usb2]—[2-2]—[2-2:1.0]-[usbendpoint:usbdev2.2-ep81]
     -[class]-[input]—[mouse2]—[device]—[bus]—[usbendpoint:usbdev2.2-ep81]
             -[usb_device]—[usbdev2.2]—[device]—[bus]
             -[usb_endpoint]—[usbdev2.2-ep00]—[device]
                            —[usbdev2.2-ep81]—[device]
     -[devices]—[pci0000:00]—[0000:00:1d:1]—[usb2]—[2-2]—[2-2:1.0]
     +[firmware]
     +[fs]
     +[kernel]
     +[module]
     +[power]

類編程接口建立在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ā)展歷程:

To see how hotplug handling has evolved recently, let's consider progressive levels of udev running different versions of the 2.6 kernel:

  1. With a udev-039 package and a 2.6.9 kernel, when the kernel detects a hotplug event, it invokes the user space helper registered with /proc/sys/kernel/hotplug. This defaults to /sbin/hotplug, which receives attributes of the hotplugged device in its environment. /sbin/hotplug looks inside the hotplug configuration directory (usually /etc/hotplug.d/default/) and runs, for example, /etc/hotplug.d/default/10-udev.hotplug, after executing other scripts under /etc/hotplug/.

    bash> ls -l /etc/hotplug.d/default/
    ...
    lrwcrwxrwx 1 root root 14 May 11 2005 10-udev.hotplug -> /sbin/udevsend
    ...

    When /sbin/udevsend thus gets executed, it passes the hotplugged device information to udevd.

  2. With udev-058 and a 2.6.11 kernel, the story changes somewhat. The udevsend utility replaces /sbin/hotplug:

    bash> cat /proc/sys/kernel/hotplug
    /sbin/udevsend
  3. With the latest levels of udev and the kernel, udevd assumes full responsibility of managing hotplug without depending on udevsend. It now pulls hotplug events directly from the kernel via netlink sockets (see Figure 4.4). /proc/sys/kernel/hotplug contains nothing:

    bash> cat /proc/sys/kernel/hotplug
    bash>

Udev還可以處理coldplug,因為udev是用戶空間程序而且在內(nèi)核啟動后才started,需要基于coldplug設(shè)備上模擬熱插拔事件。在boot 時,內(nèi)核在sysfs下創(chuàng)建名為uevent的文件for all devices,并且emits coldplug events to those files,當(dāng)udev啟動時,它讀取/sys下面所有的uevent文件并為每個冷插拔設(shè)備產(chǎn)生熱插拔事件。

Microcode Download

設(shè)備驅(qū)動used to把微代碼存在頭文件的static數(shù)組中,但是這不好,因為微代碼常因為設(shè)備廠商的不同而是分布的as binary images,解決方案是在用戶空間保存微代碼,然后將它們在需要時傳遞給內(nèi)核。Sysfs和udev提供了實現(xiàn)的架構(gòu)。

以下是Intel PRO/Wireless 2100 WiFi mini PCI card 微代碼下載的例子:在http://ipw2100./firmware.php下載并存放在您系統(tǒng)的/lib/firmware/里面,而且您已經(jīng)插入了驅(qū)動模塊ipw2100.ko:
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下的:
static struct pci_device_id xircom_pci_table[] = {
    {0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID,},
    {0,},
};

/* Mark the device table */
MODULE_DEVICE_TABLE(pci, xircom_pci_table);
 這聲明了該驅(qū)動支持任意PCI vender ID為0x115D和PCI device ID為0x0003的卡,當(dāng)您安裝了該驅(qū)動模塊后,depmod工具查看module image并且解釋在device table里面的ID,然后將下面的entry加入 /lib/modules/kernel-version/modules.aliasalias 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
   ...
   MODALIAS=pci:v0000115Dd00000003sv0000115Dsd00001181bc02sc00i00
   ...

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:
bash> lsmod
Module      Size   Used by
xircom_cb   10433 0
...

現(xiàn)在該card就可以上網(wǎng)沖浪了。

一部分不支持在嵌入式設(shè)備上使用Udev的原因:

Udev on Embedded Devices

One school of thought deprecates the use of udev in favor of statically created device nodes on embedded devices for the following reasons:

  • Udev creates /dev nodes during each reboot, compared to static nodes that are created only once during software install. If your embedded device uses flash storage, flash pages that hold /dev nodes suffer an erase-write cycle on each boot in the case of the former, and this reduces flash life span. (Flash memory is discussed in detail in Chapter 17, "Memory Technology Devices.") You do have the option of mounting /dev over a RAM-based filesystem, however.

  • Udev contributes to increased boot time.

  • Udev features such as dynamic creation of /dev nodes and autoloading of modules create a degree of indeterminism that some solution designers prefer to avoid on special-purpose embedded devices, especially ones that do not interact with the outside world via hotpluggable buses. According to this point of view, static node creation and boot-time insertion of any modules provide more control over the system and make it easier to test.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多