国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

Linux設(shè)備模型

發(fā)布時(shí)間:2009-12-14 17:00    發(fā)布者:linux_Ultra
關(guān)鍵詞: linux , 模型 , 設(shè)備
Linux設(shè)備驅(qū)動(dòng)程序?qū)W習(xí)(15)
-Linux設(shè)備模型(熱插拔、mdev 與 firmware)

熱插拔
有 2 個(gè)不同角度來(lái)看待熱插拔:
   從內(nèi)核角度看,熱插拔是在硬件、內(nèi)核和內(nèi)核驅(qū)動(dòng)之間的交互。
   從用戶角度看,熱插拔是內(nèi)核和用戶空間之間,通過(guò)調(diào)用用戶空間程序(如hotplug、udev 和 mdev)的交互。 當(dāng)需要通知用戶內(nèi)核發(fā)生了某種熱插拔事件時(shí),內(nèi)核才調(diào)用這個(gè)用戶空間程序。
現(xiàn)在的計(jì)算機(jī)系統(tǒng),要求 Linux 內(nèi)核能夠在硬件從系統(tǒng)中增刪時(shí),可靠穩(wěn)定地運(yùn)行。這就對(duì)設(shè)備驅(qū)動(dòng)作者增加了壓力,因?yàn)樵谒麄儽仨毺幚硪粋(gè)毫無(wú)征兆地突然出現(xiàn)或消失的設(shè)備。
熱插拔工具
當(dāng)用戶向系統(tǒng)添加或刪除設(shè)備時(shí),內(nèi)核會(huì)產(chǎn)生一個(gè)熱插拔事件,并在 /proc/sys/kernel/hotplug 文件里查找處理設(shè)備連接的用戶空間程序。這個(gè)用戶空間程序主要有
hotplug:這個(gè)程序是一個(gè)典型的 bash 腳本,只傳遞執(zhí)行權(quán)給一系列位于 /etc/hot-plug.d/ 目錄樹(shù)的程序。hotplug 腳本搜索所有的有 .hotplug后綴的可能對(duì)這個(gè)事件進(jìn)行處理的程序并調(diào)用它們, 并傳遞給它們?cè)S多不同的已經(jīng)被內(nèi)核設(shè)置的環(huán)境變量。(基本已被淘汰,具體內(nèi)容請(qǐng)參閱《LDD3》)
udev :用于linux2.6.13或更高版本的內(nèi)核上,為用戶空間提供使用固定設(shè)備名的動(dòng)態(tài)/dev目錄的解決方案。它通過(guò)在 sysfs 的 /class/ 和/block/ 目錄樹(shù)中查找一個(gè)稱為 dev的文件,以確定所創(chuàng)建的設(shè)備節(jié)點(diǎn)文件的主次設(shè)備號(hào)。所以要使用udev,驅(qū)動(dòng)必須為設(shè)備在sysfs中創(chuàng)建類接口及其dev屬性文件,方法和sculld模塊中創(chuàng)建dev屬性相同。 udev的資料網(wǎng)上十分豐富,我就不在這廢話了,給出以下鏈接有興趣的自己研究:
《UDEV Primer》(英文),地址:
http://webpages.charter.net/decibelshelp/LinuxHelp_UDEVPrimer.html

《udev規(guī)則編寫(xiě)》(luofuchong翻譯),地址:
http://www.cnitblog.com/luofuchong/archive/2007/12/18/37831.html

《什么是udev》地址:
http://blog.csdn.net/steganography/archive/2006/04/10/657620.aspx

《udev-FAQ 中文翻譯》地址:
http://gnawux.bokee.com/3225765.html

《udev輕松上路》地址:
http://www.blog.edu.cn/user1/3313/archives/2007/1635169.shtml

《Udev (簡(jiǎn)體中文)》地址:
http://wiki.archlinux.org/index.php/Udev_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87
)

Udev官方主頁(yè):
http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html
下載地址:
http://www.kernel.org/pub/linux/utils/kernel/hotplug/

在《LFS》中也有介紹udev的使用,很值得參考!下載地址:
http://lfs.osuosl.org/lfs/downloads/stable/


mdev:一個(gè)簡(jiǎn)化版的udev,是busybox所帶的程序,十分適合嵌入式系統(tǒng)。

因?yàn)?font color="#0000ff">hotplug現(xiàn)在也在被慢慢地淘汰,udev不再依賴hotplug了,所以這里不再介紹;
udev較mdev復(fù)雜,不太適合嵌入式使用。(本人也有做udev的實(shí)驗(yàn),交叉編譯是通過(guò)了,但是使用上有問(wèn)題,沒(méi)有實(shí)現(xiàn)其功能。也許是我的文件系統(tǒng)沒(méi)做好,以后有時(shí)間再研究和寫(xiě)記錄。有成功高人的通知一聲,交流一下經(jīng)驗(yàn)。^_^謝謝!);
mdev簡(jiǎn)單易用,比較適合嵌入式系統(tǒng),實(shí)驗(yàn)成功。以下詳細(xì)介紹mdev的使用。
mdev

在一開(kāi)始建立根文件系統(tǒng)時(shí),我根據(jù) WeiBing 的博客上《UDEV on embeded Linux-2.6.19.2》(地址:
http://weibing.blogbus.com/logs/4485453.html
)這篇文章的提示,開(kāi)始使用mdev,但是當(dāng)時(shí)只是啟動(dòng)時(shí)mdev -s一下,并沒(méi)有深究。現(xiàn)在在學(xué)習(xí)了Linux設(shè)備模型之后,對(duì)于Linux中/dev目錄的動(dòng)態(tài)管理有了更深的認(rèn)識(shí),并認(rèn)真的看了一下busybox中的mdev.txt文檔并翻譯了一下,做成了PDF(下載地址:
http://blogimg.chinaunix.net/blog/upfile2/080111091002.pdf
),在看下面的內(nèi)容時(shí)請(qǐng)先看看這篇文檔。

先聲明一個(gè)要點(diǎn):要實(shí)現(xiàn)設(shè)備節(jié)點(diǎn)文件的自動(dòng)、動(dòng)態(tài)的增刪,必須在你自己的驅(qū)動(dòng)源碼中實(shí)現(xiàn) 類 接口,并在類設(shè)備的目錄中添加包含設(shè)備號(hào)的名為“dev”的屬性文件。

mdev原理及bug

要使用mdev,適當(dāng)知道一下原理是必不可少的(能完整地研究mdev源碼是最好的)。說(shuō)實(shí)話起初我并沒(méi)有想看mdev的源碼,是在使用時(shí)發(fā)現(xiàn)了問(wèn)題后才去研究了一下mdev的源碼。現(xiàn)在簡(jiǎn)單介紹一下mdev的原理:

執(zhí)行mdev -s:以‘-s’為參數(shù)調(diào)用位于/sbin目錄寫(xiě)的mdev(其實(shí)是個(gè)鏈接,作用是傳遞參數(shù)給/bin目錄下的busybox程序并調(diào)用它),mdev掃描 /sys/class 和/sys/block中所有的類設(shè)備目錄,如果在目錄中含有名為“dev”的文件,且文件中包含的是設(shè)備號(hào),則mdev就利用這些信息為這個(gè)設(shè)備在/dev下創(chuàng)建設(shè)備節(jié)點(diǎn)文件。一般只在啟動(dòng)時(shí)才執(zhí)行一次 “mdev -s”。

熱插拔事件:由于啟動(dòng)時(shí)運(yùn)行了命令:echo /sbin/mdev > /proc/sys/kernel/hotplug,那么當(dāng)有熱插拔事件產(chǎn)生時(shí),內(nèi)核就會(huì)調(diào)用位于 /sbin目錄的mdev。這時(shí)mdev通過(guò)環(huán)境變量中的 ACTION 和DEVPATH,來(lái)確定此次熱插拔事件的動(dòng)作以及影響了/sys中的那個(gè)目錄。接著會(huì)看看這個(gè)目錄中是否有“dev”的屬性文件,如果有就利用這些信息為這個(gè)設(shè)備在/dev 下創(chuàng)建設(shè)備節(jié)點(diǎn)文件。

源碼的bug(個(gè)人意見(jiàn)):由于mdev是通過(guò)判斷“dev”屬性文件的路徑字符串中的第6個(gè)字符是否為‘c’,來(lái)決定設(shè)備是字符設(shè)備還是塊設(shè)備【type = (path[5] == 'c' ? S_IFCHR : S_IFBLK);例如path = "/sys/class/ldd/sculld*/"為字符設(shè)備,而/sys/devices/ldd0/sculld*/就會(huì)被誤判為塊設(shè)備】,那么如果你在非 /sys/class 和 /sys/block目錄下建立了“dev”屬性文件且內(nèi)容是設(shè)備號(hào)(像sculld中就這樣做了),那么mdev也會(huì)在/dev下創(chuàng)建設(shè)備節(jié)點(diǎn)文件。這樣可能所創(chuàng)建的設(shè)備節(jié)點(diǎn)文件是錯(cuò)的。
以我實(shí)驗(yàn)為例,我以上一篇的文章中的sculld為基礎(chǔ),加上了類接口(這樣在/sys/devices/ldd0/sculld*/和 /sys/class/ldd/sculld* 中都有內(nèi)容為設(shè)備號(hào)的“dev”屬性文件)。在運(yùn)行時(shí)發(fā)現(xiàn)一直會(huì)將有的sculld*創(chuàng)建為塊設(shè)備節(jié)點(diǎn)文件。郁悶死了,難道我的驅(qū)動(dòng)有錯(cuò)???最后研究了mdev源碼之后發(fā)現(xiàn),只要在/sys中建立了“dev”屬性文件且內(nèi)容是設(shè)備號(hào),mdev就會(huì)以所在的目錄為名在/dev下創(chuàng)建設(shè)備節(jié)點(diǎn)文件。像sculld模塊,mdev會(huì)為一個(gè)設(shè)備創(chuàng)建兩次設(shè)備文件,由于文件名一樣,第二次的文件會(huì)覆蓋第一次的。如果第二次是因?yàn)?sys/devices/ldd0/sculld*/dev 產(chǎn)生的設(shè)備節(jié)點(diǎn)文件,那么設(shè)備節(jié)點(diǎn)文件就會(huì)被錯(cuò)誤地創(chuàng)建為塊設(shè)備。
我認(rèn)為這個(gè)bug的解決辦法有如下兩種:
(1)在你寫(xiě)驅(qū)動(dòng)的時(shí)候,只在/sys/class 和 /sys/block 中的類設(shè)備目錄中存在包含設(shè)備號(hào)的“dev”屬性文件。(你無(wú)法保證被人的驅(qū)動(dòng)會(huì)這么做)
(2)修正mdev源碼:
修改/busybox-1.9.0/util-linux/mdev.c文件的第328行:
if (!strcmp(action, "remove"))
       make_device(temp, 1);
else if (!strcmp(action, "add")) {
         if (env_path[2]=='l') make_device(temp,0);  //tekkamanninja
            if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE)
                load_firmware(getenv("FIRMWARE"), temp);
        }
也就是在增加設(shè)備節(jié)點(diǎn)文件之前檢查/sys/目錄下的路徑是否為/class和/block(通過(guò)檢查路徑字符串的第3個(gè)字符是否為‘l’)。

本人推薦第二種做法!

mdev使用
mdev的使用在busybox中的mdev.txt文檔已經(jīng)將得很詳細(xì)了。但作為例子,我簡(jiǎn)單講講我的使用過(guò)程:

(1)在編譯時(shí)加上對(duì)mdev的支持(我是使用的是busybox1.9.0):
    Linux System Utilities  --->   
            
mdev      
               Support /etc/mdev.conf
                 Support command execution at device addition/removal

(2)在啟動(dòng)時(shí)加上使用mdev的命令:
我在自己創(chuàng)建的根文件系統(tǒng)(nfs)中的/linuxrc文件中添加了如下指令:
#掛載/sys為sysfs文件系統(tǒng)
    echo "----------mount /sys as sysfs"
    /bin/mount -t tmpfs mdev /dev
    /bin/mount -t sysfs sysfs /sys
    echo "----------Starting mdev......"
    /bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
    mdev -s
注意:是/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug,并非/bin/echo /bin/mdev > /proc/sys/kernel/hotplug。busybox的文檔有錯(cuò)!!
  
(3)在你的驅(qū)動(dòng)中加上對(duì)類設(shè)備接口的支持,并在類設(shè)備目錄下添加包含設(shè)備號(hào)的名為“dev”的屬性文件。

(4)至于/etc/mdev.conf文件,可有可無(wú),不影響使用,只是添加了些功能。
     為了實(shí)驗(yàn)我在/etc創(chuàng)建了mdev.conf文件并輸入了:
    sculld[0-1] 0:0 666 * echo tekkaman > /tmp/mdev
     這樣,在掛載和卸載sculld.ko時(shí),在/tmp/下會(huì)出現(xiàn)mdev文件,里面字符為tekkaman
具體的實(shí)驗(yàn)源碼和現(xiàn)象在文章后面有。

firmware
硬件市場(chǎng)的激烈競(jìng)爭(zhēng), 使得制造商連一點(diǎn)用于設(shè)備控制固件的 EEPROM 的成本都不愿意花費(fèi)。因此固件一般發(fā)布在和硬件配套的驅(qū)動(dòng)包中,由操作系統(tǒng)(其實(shí)是驅(qū)動(dòng)程序)負(fù)責(zé)傳送固件到設(shè)備。
內(nèi)核固件接口
獲取固件的正確方法是當(dāng)需要時(shí)從用戶空間獲取它。一定不要試圖從內(nèi)核空間直接打開(kāi)包含固件的文件,那是一個(gè)易出錯(cuò)的操作, 因?yàn)樗巡呗?以文件名的形式)包含進(jìn)了內(nèi)核。正確的方法是使用固件接口:
#include linux/firmware.h>
int request_firmware(const struct firmware **fw,
                     const char *name, /* name 為固件文件名*/
                     struct device *device);
/*要求用戶空間定位并提供一個(gè)固件映象給內(nèi)核;若成功加載, 返回值是 0(否則返回錯(cuò)誤碼)*/
/*因?yàn)?request_firmware 需要用戶空間的操作, 所以返回前將保持休眠。若驅(qū)動(dòng)必須使用固件而不能進(jìn)入休眠時(shí),可使用以下異步函數(shù):*/
int request_firmware_nowait(
    struct module *module, /* = THIS_MODULE*/
    int uevent,
    const char *name,
    struct device *device,
    void *context,/*不由固件子系統(tǒng)使用的私有數(shù)據(jù)指針*/
    void (*cont)(const struct firmware *fw, void *context));
/*如果一切正常,request_firmware_nowait 開(kāi)始固件加載過(guò)程并返回 0. 過(guò)了一段時(shí)間后(默認(rèn)10秒),將用加載的結(jié)果(若加載失敗, fw 為 NULL)作為參數(shù)調(diào)用 cont。*/
/* fw 參數(shù)指向以下結(jié)構(gòu)體:*/
struct firmware {
    size_t size;
    u8 *data;
};
/*那個(gè)結(jié)構(gòu)包含實(shí)際的固件, 它現(xiàn)在可被下載到設(shè)備中.但是請(qǐng)注意:在發(fā)送它到硬件之前,必須檢查這個(gè)文件以確保它是正確的固件映象(設(shè)備固件常常包含標(biāo)識(shí)字符串、 校驗(yàn)和等等)*/
/*當(dāng)固件已經(jīng)發(fā)送到設(shè)備后,應(yīng)當(dāng)釋放 firmware 結(jié)構(gòu)體, 使用:*/
void release_firmware(struct firmware *fw);
注意:要使用firmware,必須要在配置內(nèi)核時(shí)選上:
   Device Drivers  --->   
          Generic Driver Options  --->      
               Userspace firmware loading support
否則會(huì)出現(xiàn): Unknown symbol release_firmware 和: Unknown symbol request_firmware 的錯(cuò)誤。
               
固件接口工作原理
固件子系統(tǒng)使用 sysfs 和熱插拔機(jī)制工作。當(dāng)調(diào)用 request_firmware時(shí), 函數(shù)將在 /sys/class/firmware 下創(chuàng)建一個(gè)以設(shè)備名為目錄名的新目錄,其中包含 3 個(gè)屬性:
loading :這個(gè)屬性應(yīng)當(dāng)被加載固件的用戶空間進(jìn)程設(shè)置為 1。當(dāng)加載完畢, 它將被設(shè)為 0。被設(shè)為 -1 時(shí),將中止固件加載。
data :一個(gè)用來(lái)接收固件數(shù)據(jù)的二進(jìn)制屬性。在設(shè)置 loading 為1后, 用戶空間進(jìn)程將固件寫(xiě)入這個(gè)屬性。
device :一個(gè)鏈接到 /sys/devices 下相關(guān)入口項(xiàng)的符號(hào)鏈接。
一旦創(chuàng)建了 sysfs 入口項(xiàng), 內(nèi)核將為設(shè)備產(chǎn)生一個(gè)熱插拔事件,并傳遞包括變量 FIRMWARE 的環(huán)境變量給處理熱插拔的用戶空間程序。FIRMWARE 被設(shè)置為提供給 request_firmware 的固件文件名。
用戶空間程序定位固件文件, 并將其拷貝到內(nèi)核提供的二進(jìn)制屬性;若無(wú)法定位文件, 用戶空間程序設(shè)置 loading 屬性為 -1。
若固件請(qǐng)求在 10 秒內(nèi)沒(méi)有被服務(wù), 內(nèi)核就放棄并返回一個(gè)失敗狀態(tài)給驅(qū)動(dòng)。超時(shí)周期可通過(guò) sysfs 屬性 /sys/class/firmware/timeout 屬性改變。
request_firmware 接口允許使用驅(qū)動(dòng)發(fā)布設(shè)備固件。當(dāng)正確地集成進(jìn)熱插拔機(jī)制后, 固件加載子系統(tǒng)允許設(shè)備不受干擾地工作。顯然這是處理問(wèn)題的最好方法,但固件受版權(quán)保護(hù),小心違反版權(quán)法。
ARM9開(kāi)發(fā)板實(shí)驗(yàn)

實(shí)驗(yàn)源碼:
http://blogimg.chinaunix.net/blog/upfile2/080114113255.gz


實(shí)驗(yàn)現(xiàn)象:
[Tekkaman2440@SBC2440V4]#ls -l /dev/sculld*
ls: /dev/sculld*: No such file or directory
[Tekkaman2440@SBC2440V4]#cat /tmp/mdev
cat: can't open '/tmp/mdev': No such file or directory

[Tekkaman2440@SBC2440V4]#insmod /lib/modules/lddbus.ko
Mount lddbus ok !
Bus device is ldd0 !
You can see me in sys/module/ , sys/devices/ , sys/class/ and sys/bus/ !
[Tekkaman2440@SBC2440V4]#insmod /lib/modules/sculld.ko
[Tekkaman2440@SBC2440V4]#ls -l /dev/sculld*
crw-rw-rw-    1 root     root     252,   0 Jan  1 00:00 /dev/sculld0
crw-rw-rw-    1 root     root     252,   1 Jan  1 00:00 /dev/sculld1
crw-rw----    1 root     root     252,   2 Jan  1 00:00 /dev/sculld2
crw-rw----    1 root     root     252,   3 Jan  1 00:00 /dev/sculld3
[Tekkaman2440@SBC2440V4]#rmmod sculld
The LDD class
ldd_classdev_release : sculld0 release!
The LDD class
ldd_classdev_release : sculld1 release!
The LDD class
ldd_classdev_release : sculld2 release!
The LDD class
ldd_classdev_release : sculld3 release!
[Tekkaman2440@SBC2440V4]#ls -l /dev/sculld*
ls: /dev/sculld*: No such file or directory
[Tekkaman2440@SBC2440V4]#cat /tmp/mdev
tekkaman



到此 Linux設(shè)備模型 的學(xué)習(xí)暫時(shí)告一段落。
本文地址:http://m.qingdxww.cn/thread-6525-1-1.html     【打印本頁(yè)】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
linux_Ultra 發(fā)表于 2009-12-14 18:35:46
udev實(shí)現(xiàn)原理

            

轉(zhuǎn)載時(shí)請(qǐng)注明出處和作者聯(lián)系方式:http://blog.csdn.net/absurd

作者聯(lián)系方式:李先靜

更新時(shí)間:2007-4-29



相對(duì)于linux來(lái)說(shuō),udev還是一個(gè)新事物。然而,盡管它03年才出現(xiàn),盡管它很低調(diào)(J),但它無(wú)疑已經(jīng)成為linux下不可或缺的組件了。udev是什么?它是如何實(shí)現(xiàn)的?最近研究Linux設(shè)備管理時(shí),花了一些時(shí)間去研究udev的實(shí)現(xiàn)。



udev是什么?u 是指user space,dev是指device,udev是用戶空間的設(shè)備驅(qū)動(dòng)程序嗎?最初我也這樣認(rèn)為,調(diào)試內(nèi)核空間的程序要比調(diào)試用戶空間的程序復(fù)雜得多,內(nèi)核空間的程序的BUG所引起的后果也嚴(yán)重得多,device driver是內(nèi)核空間中所占比較最大的代碼,如果把這些device driver中硬件無(wú)關(guān)的代碼,從內(nèi)核空間移動(dòng)到用戶空間,自然是一個(gè)不錯(cuò)的想法。



但我的想法并不正確,udev的文檔是這樣說(shuō)的,

1.         dynamic replacement for /dev。作為devfs的替代者,傳統(tǒng)的devfs不能動(dòng)態(tài)分配major和minor的值,而major和minor非常有限,很快就會(huì)用完了。udev能夠像DHCP動(dòng)態(tài)分配IP地址一樣去動(dòng)態(tài)分配major和minor。



2.         device naming。提供設(shè)備命名持久化的機(jī)制。傳統(tǒng)設(shè)備命名方式不具直觀性,像/dev/hda1這樣的名字肯定沒(méi)有boot_disk這樣的名字直觀。udev能夠像DNS解析域名一樣去給設(shè)備指定一個(gè)有意義的名稱。



3.         API to access info about current system devices 。提供了一組易用的API去操作sysfs,避免重復(fù)實(shí)現(xiàn)同樣的代碼,這沒(méi)有什么好說(shuō)的。



我們知道,用戶空間的程序與設(shè)備通信的方法,主要有以下幾種方式,

1.         通過(guò)ioperm獲取操作IO端口的權(quán)限,然后用inb/inw/ inl/ outb/outw/outl等函數(shù),避開(kāi)設(shè)備驅(qū)動(dòng)程序,直接去操作IO端口。(沒(méi)有用過(guò))

2.         用ioctl函數(shù)去操作/dev目錄下對(duì)應(yīng)的設(shè)備,這是設(shè)備驅(qū)動(dòng)程序提供的接口。像鍵盤、鼠標(biāo)和觸摸屏等輸入設(shè)備一般都是這樣做的。

3.         用write/read/mmap去操作/dev目錄下對(duì)應(yīng)的設(shè)備,這也是設(shè)備驅(qū)動(dòng)程序提供的接口。像framebuffer等都是這樣做的。



上面的方法在大多數(shù)情況下,都可以正常工作,但是對(duì)于熱插撥(hotplug)的設(shè)備,比如像U盤,就有點(diǎn)困難了,因?yàn)槟悴恢溃菏裁磿r(shí)候設(shè)備插上了,什么時(shí)候設(shè)備拔掉了。這就是所謂的hotplug問(wèn)題了。



處理hotplug傳統(tǒng)的方法是,在內(nèi)核中執(zhí)行一個(gè)稱為hotplug的程序,相關(guān)參數(shù)通過(guò)環(huán)境變量傳遞過(guò)來(lái),再由hotplug通知其它關(guān)注hotplug事件的應(yīng)用程序。這樣做不但效率低下,而且感覺(jué)也不那么優(yōu)雅。新的方法是采用NETLINK實(shí)現(xiàn)的,這是一種特殊類型的socket,專門用于內(nèi)核空間與用戶空間的異步通信。下面的這個(gè)簡(jiǎn)單的例子,可以監(jiān)聽(tīng)來(lái)自內(nèi)核hotplug的事件。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include



static int init_hotplug_sock(void)

{

    struct sockaddr_nl snl;

    const int buffersize = 16 * 1024 * 1024;

    int retval;



    memset(&snl, 0x00, sizeof(struct sockaddr_nl));

    snl.nl_family = AF_NETLINK;

    snl.nl_pid = getpid();

    snl.nl_groups = 1;



    int hotplug_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

    if (hotplug_sock == -1) {

        printf("error getting socket: %s", strerror(errno));

        return -1;

    }



    /* set receive buffersize */

    setsockopt(hotplug_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize));



    retval = bind(hotplug_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl));

    if (retval < 0) {

        printf("bind failed: %s", strerror(errno));

        close(hotplug_sock);

        hotplug_sock = -1;

        return -1;

    }



    return hotplug_sock;

}



#define UEVENT_BUFFER_SIZE      2048



int main(int argc, char* argv[])

{

         int hotplug_sock       = init_hotplug_sock();

        

         while(1)

         {

                   char buf[UEVENT_BUFFER_SIZE*2] = {0};

                   recv(hotplug_sock, &buf, sizeof(buf), 0);

                   printf("%s\n", buf);

         }



         return 0;

}



編譯:

gcc -g hotplug.c -o hotplug_monitor



運(yùn)行后插/拔U盤,可以看到:

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/usbdev2.2_ep00

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0

add@/class/scsi_host/host2

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep81

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep02

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep83

add@/class/usb_device/usbdev2.2

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host2/target2:0:0/2:0:0:0

add@/class/scsi_disk/2:0:0:0

add@/block/sda

add@/block/sda/sda1

add@/class/scsi_device/2:0:0:0

add@/class/scsi_generic/sg0

remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep81

remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep02

remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep83

remove@/class/scsi_generic/sg0

remove@/class/scsi_device/2:0:0:0

remove@/class/scsi_disk/2:0:0:0

remove@/block/sda/sda1

remove@/block/sda

remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host2/target2:0:0/2:0:0:0

remove@/class/scsi_host/host2

remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0

remove@/class/usb_device/usbdev2.2

remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/usbdev2.2_ep00

remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1



udev的主體部分在udevd.c文件中,它主要監(jiān)控來(lái)自4個(gè)文件描述符的事件/消息,并做出處理:

1.         來(lái)自客戶端的控制消息。這通常由udevcontrol命令通過(guò)地址為/org/kernel/udev/udevd的本地socket,向udevd發(fā)送的控制消息。其中消息類型有:

l         UDEVD_CTRL_STOP_EXEC_QUEUE 停止處理消息隊(duì)列。

l         UDEVD_CTRL_START_EXEC_QUEUE 開(kāi)始處理消息隊(duì)列。

l         UDEVD_CTRL_SET_LOG_LEVEL 設(shè)置LOG的級(jí)別。

l         UDEVD_CTRL_SET_MAX_CHILDS 設(shè)置最大子進(jìn)程數(shù)限制。好像沒(méi)有用。

l         UDEVD_CTRL_SET_MAX_CHILDS_RUNNING 設(shè)置最大運(yùn)行子進(jìn)程數(shù)限制(遍歷proc目錄下所有進(jìn)程,根據(jù)session的值判斷)。

l         UDEVD_CTRL_RELOAD_RULES 重新加載配置文件。

2.         來(lái)自內(nèi)核的hotplug事件。如果有事件來(lái)源于hotplug,它讀取該事件,創(chuàng)建一個(gè)udevd_uevent_msg對(duì)象,記錄當(dāng)前的消息序列號(hào),設(shè)置消息的狀態(tài)為EVENT_QUEUED,然后并放入running_list和exec_list兩個(gè)隊(duì)列中,稍后再進(jìn)行處理。

3.         來(lái)自signal handler中的事件。signal handler是異步執(zhí)行的,即使有signal產(chǎn)生,主進(jìn)程的select并不會(huì)喚醒,為了喚醒主進(jìn)程的select,它建立了一個(gè)管道,在signal handler中,向該管道寫(xiě)入長(zhǎng)度為1個(gè)子節(jié)的數(shù)據(jù),這樣就可以喚醒主進(jìn)程的select了。

4.         來(lái)自配置文件變化的事件。udev通過(guò)文件系統(tǒng)inotify功能,監(jiān)控其配置文件目錄/etc/udev/rules.d,一旦該目錄中文件有變化,它就重新加載配置文件。



其中最主要的事件,當(dāng)然是來(lái)自內(nèi)核的hotplug事件,如何處理這些事件是udev的關(guān)鍵。udev本身并不知道如何處理這些事件,也沒(méi)有必要知道,因?yàn)樗粚?shí)現(xiàn)機(jī)制,而不實(shí)現(xiàn)策略。事件的處理是由配置文件決定的,這些配置文件即所謂的rule。



關(guān)于rule的編寫(xiě)方法可以參考《writing_udev_rules》,udev_rules.c實(shí)現(xiàn)了對(duì)規(guī)則的解析。



在規(guī)則中,可以讓外部應(yīng)用程序處理某個(gè)事件,這有兩種方式,一種是直接執(zhí)行命令,通常是讓modprobe去加載驅(qū)動(dòng)程序,或者讓mount去加載分區(qū)。另外一種是通過(guò)本地socket發(fā)送消息給某個(gè)應(yīng)用程序。



在udevd.c:udev_event_process函數(shù)中,我們可以看到,如果RUN參數(shù)以”socket:”開(kāi)頭則認(rèn)為是發(fā)到socket,否則認(rèn)為是執(zhí)行指定的程序。



下面的規(guī)則是執(zhí)行指定程序:

60-pcmcia.rules:                RUN+="/sbin/modprobe pcmcia"



下面的規(guī)則是通過(guò)socket發(fā)送消息:

90-hal.rules:RUN+="socket:/org/freedesktop/hal/udev_event"



hal正是我們下一步要關(guān)心的,接下來(lái)我會(huì)分析HAL的實(shí)現(xiàn)原理。



~~end~~
linux_Ultra 發(fā)表于 2009-12-14 18:37:18
第一、什么是udev?

這篇文章UDEV Primer給我們娓娓道來(lái),花點(diǎn)時(shí)間預(yù)習(xí)一下是值得的。當(dāng)然,不知道udev是什么也沒(méi)關(guān)系,
把它當(dāng)個(gè)助記符好了,有了下面的上路指南,可以節(jié)省很多時(shí)間。我們只需要樹(shù)立一個(gè)信念:udev很簡(jiǎn)單!
嵌入式的udev應(yīng)用尤其簡(jiǎn)單。

第二、為什么udev要取代devfs?

這是生產(chǎn)關(guān)系適應(yīng)生產(chǎn)力的需要,udev好,devfs壞,用好的不用壞的。

udev是硬件平臺(tái)無(wú)關(guān)的,屬于user space的進(jìn)程,它脫離驅(qū)動(dòng)層的關(guān)聯(lián)而建立在操作系統(tǒng)之上,基于這種設(shè)
計(jì)實(shí)現(xiàn),我們可以隨時(shí)修改及刪除/dev下的設(shè)備文件名稱和指向,隨心所欲地按照我們的愿望安排和管理設(shè)
備文件系統(tǒng),而完成如此靈活的功能只需要簡(jiǎn)單地修改udev的配置文件即可,無(wú)需重新啟動(dòng)操作系統(tǒng)。udev
已經(jīng)使得我們對(duì)設(shè)備的管理如探囊取物般輕松自如。

第三、如何得到udev?

udev的主頁(yè)在這里:http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html
我們按照下面的步驟來(lái)生成udev的工具程序,以arm-linux為例:
1、wget http://www.us.kernel.org/pub/linux/utils/kernel/hotplug/udev-100.tar.bz2
2、tar xjf udev-100.tar.bz2
3、cd udev-100 編輯Makefile,查找CROSS_COMPILE,修改CROSS_COMPILE ?= arm-linux-
4、make

沒(méi)有什么意外的話當(dāng)前目錄下生成udev,udevcontrol,udevd,udevinfo,udevmonitor,udevsettle,udevstart,
udevtest,udevtrigger九個(gè)工具程序,在嵌入式系統(tǒng)里,我們只需要udevd和udevstart就能使udev工作得很好,
其他工具則幫助我們完成udev的信息察看、事件捕捉或者更高級(jí)的操作。

另外一個(gè)方法是直接使用debian提供的已編譯好的二進(jìn)制包,美中不足的是版本老了一些。
1、wget http://ftp.us.debian.org/debian/pool/main/u/udev/udev_0.056-3_arm.deb
2、ar -xf udev_0.056-3_arm.deb
3、tar xzf data.tar.gz

在sbin目錄里就有我們需要的udevd和udevstart工具程序。

建議大家采用第一種方式生成的udevd和udevstart。為什么要用最新udev呢?新的強(qiáng),舊的弱,用強(qiáng)的不用弱的。

第四、如何配置udev?

首先,udev需要內(nèi)核sysfs和tmpfs的支持,sysfs為udev提供設(shè)備入口和uevent通道,tmpfs為udev設(shè)備文件提
供存放空間,也就是說(shuō),在上電之前系統(tǒng)上是沒(méi)有足夠的設(shè)備文件可用的,我們需要一些技巧讓kernel先引導(dǎo)
起來(lái)。

由于在kernel啟動(dòng)未完成以前我們的設(shè)備文件不可用,如果使用mtd設(shè)備作為rootfs的掛載點(diǎn),這個(gè)時(shí)候/dev/mtdblock
是不存在的,我們無(wú)法讓kernel找到rootfs,kernel只好停在那里驚慌。
這個(gè)問(wèn)題我們可以通過(guò)給kernel傳遞設(shè)備號(hào)的方式來(lái)解決,在linux系統(tǒng)中,mtdblock的主設(shè)備號(hào)是31,part號(hào)
從0開(kāi)始,那么以前的/dev/mtdblock/3就等同于31:03,以次類推,所以我們只需要修改bootloader傳給kernel
的cmd line參數(shù),使root=31:03,就可以讓kernel在udevd未起來(lái)之前成功的找到rootfs。
O.K.下一個(gè)問(wèn)題。

其次,需要做的工作就是重新生成rootfs,把udevd和udevstart復(fù)制到/sbin目錄。然后我們需要在/etc/下為udev
建立設(shè)備規(guī)則,這可以說(shuō)是udev最為復(fù)雜的一步。這篇文章提供了最完整的指導(dǎo):Writing udev rules
文中描述的復(fù)雜規(guī)則我們可以暫時(shí)不用去理會(huì),上路指南將帶領(lǐng)我們輕松穿過(guò)這片迷霧。這里提供一個(gè)由簡(jiǎn)入
繁的方法,對(duì)于嵌入式系統(tǒng),這樣做可以一勞永逸。

1、在前面用到的udev-100目錄里,有一個(gè)etc目錄,里面放著的udev目錄包含了udev設(shè)備規(guī)則的詳細(xì)樣例文
本。為了簡(jiǎn)單而又簡(jiǎn)潔,我們只需要用到etc/udev/udev.conf這個(gè)文件,在我們的rootfs/etc下建立一個(gè)udev目
錄,把它復(fù)制過(guò)去,這個(gè)文件很簡(jiǎn)單,除了注釋只有一行,是用來(lái)配置日志信息的,嵌入式系統(tǒng)也許用不上
日志,但是udevd需要檢查這個(gè)文件。

2、在rootfs/etc/udev下建立一個(gè)rules.d目錄,生成一個(gè)空的配置文件touch etc/udev/rules.d/udev.conf。然后
我們來(lái)編輯這個(gè)文件并向它寫(xiě)入以下配置項(xiàng):

###############################################
# vc devices
KERNEL=="tty[0-9]*", NAME="vc/%n"

# block devices
KERNEL=="loop[0-9]*", NAME="loop/%n"

# mtd devices
KERNEL=="mtd[0-9]*", NAME="mtd/%n"
KERNEL=="mtdblock*", NAME="mtdblock/%n"

# input devices
KERNEL=="mice" NAME="input/%k"
KERNEL=="mouse[0-9]*", NAME="input/%k"
KERNEL=="ts[0-9]*", NAME="input/%k"
KERNEL=="event[0-9]*", NAME="input/%k"

# misc devices
KERNEL=="apm_bios", NAME="misc/%k"
KERNEL=="rtc", NAME="misc/%k"
################################################

保存它,我們的設(shè)備文件系統(tǒng)基本上就可以了,udevd和udevstart會(huì)自動(dòng)分析這個(gè)文件。

3、為了使udevd在kernel起來(lái)后能夠自動(dòng)運(yùn)行,我們?cè)趓ootfs/etc/init.d/rcS中增加以下幾行:

##################################
/bin/mount -t tmpfs tmpfs /dev

echo "Starting udevd..."
/sbin/udevd --daemon
/sbin/udevstart
##################################

4、重新生成rootfs,燒寫(xiě)到flash指定的rootfs part中。

5、如果需要?jiǎng)討B(tài)改變?cè)O(shè)備規(guī)則,可以把etc/udev放到j(luò)ffs或yaffs part,以備修改,根據(jù)需求而定,可以隨時(shí)擴(kuò)
充udev.conf中的配置項(xiàng)。
linux_Ultra 發(fā)表于 2009-12-14 18:37:59
Udev (簡(jiǎn)體中文)
From ArchWiki
Jump to: navigation, search


i18n
English
Русский
繁體中文
簡(jiǎn)體中文

注意: 如果您是從DevFS升級(jí)到Udev, 請(qǐng)查看 DevFS to Udev.

這篇文檔將介紹udev的一些新的變化。從084版開(kāi)始,udev能夠代替hotplug和coldplug的所有功能。正因?yàn)檫@樣,hotplug包已經(jīng)從Arch倉(cāng)庫(kù)中去掉了。
Contents
[hide]

    * 1 重要提示
    * 2 基本需求
    * 3 最近更新
    * 4 模塊禁用列表
    * 5 load_modules: 有用的啟動(dòng)參數(shù)
    * 6 已知的硬件問(wèn)題
    * 7 自動(dòng)加載帶來(lái)的一些問(wèn)題
          o 7.1 CPUFreq模塊
          o 7.2 聲音問(wèn)題和一些不能自動(dòng)加載的模塊
          o 7.3 多個(gè)同類型設(shè)備(網(wǎng)卡,聲卡)每次啟動(dòng)的都不同
    * 8 自己編譯內(nèi)核造成的一些已知問(wèn)題
          o 8.1 Udev無(wú)法啟動(dòng)
          o 8.2 CD/DVD符號(hào)和權(quán)限錯(cuò)誤
    * 9 Udev小竅門
          o 9.1 自動(dòng)加載usb設(shè)備

重要提示

...切記,在使用udev加載任何modules(內(nèi)核模塊)之前(無(wú)論是否是啟動(dòng)時(shí)自動(dòng)加載),您必須在/etc/rc.conf將MOD_AUTOLOAD選項(xiàng)設(shè)置為yes ,否則您必須手動(dòng)加載這些modules。您可以修改rc.conf中的MODULES或者使用modprobe命令來(lái)手動(dòng)加載您所需要的modules。另一種方法是用hwdetect --modules生成系統(tǒng)硬件的modules列表,然后將這個(gè)列表添加到rc.conf中讓系統(tǒng)啟動(dòng)時(shí)自動(dòng)加載這些modules。
基本需求

    * 內(nèi)核: 2.6.15或更高版本。
    * 您將無(wú)法在fstab和bootloader設(shè)置中再使用DevFS格式的設(shè)備名稱! 更多相關(guān)內(nèi)容請(qǐng)查看DevFS to Udev。

最近更新

    * startudev程序被取出。如果需要重新加載udev規(guī)則請(qǐng)使用 /etc/start_udev。
    * Udev代替了hotplug和hwdetect的功能。同時(shí)我們保存了hwdetect,并且只在 mkinitrd程序生成initrd的時(shí)候用到。
    * Udev可以同時(shí)加載多個(gè)模塊,這樣可以加快啟動(dòng)速度,然而,這樣做的結(jié)果是她不能保證每次加載的順序,所以當(dāng)你使用多聲卡或網(wǎng)卡的時(shí)候就會(huì)出現(xiàn)問(wèn)題,這個(gè)問(wèn)題下面將會(huì)再討論。

模塊禁用列表

udev也會(huì)犯錯(cuò)或加載錯(cuò)誤的模塊。為了防止錯(cuò)誤的發(fā)生,你可以使用模塊禁用列表 。一旦加入該列表的模塊,無(wú)論是啟動(dòng)時(shí),或者是運(yùn)行時(shí)(如usb硬盤等)udev都不會(huì)加載這些模塊。

只需在您在 rc.conf的MODULES中對(duì)應(yīng)模塊前加上感嘆號(hào)(!)就可禁用該模塊。

例如,

MODULES=(!moduleA !moduleB)

load_modules: 有用的啟動(dòng)參數(shù)

如果您在內(nèi)核啟動(dòng)參數(shù)中加入load_modules=off,那么udev會(huì)停止任何自動(dòng)加載工作. 如果系統(tǒng)出現(xiàn)問(wèn)題時(shí),這個(gè)功能會(huì)十分有用。如果udev加載了有問(wèn)題的模塊導(dǎo)致系統(tǒng)掛起或者其它嚴(yán)重的問(wèn)題時(shí),你可以使用這個(gè)參數(shù)來(lái)禁用自動(dòng)加載,以此來(lái)防止加載有問(wèn)題的模塊。
已知的硬件問(wèn)題

- BusLogic設(shè)備被損壞而且導(dǎo)致啟動(dòng)時(shí)死機(jī)。

這是一個(gè)內(nèi)核的Bug目前還沒(méi)有修正。

- PCMCIA讀卡器被認(rèn)為是可移除設(shè)備.

把它們加入到/etc/pmount.allow中,使用hal的pmount來(lái)讀取

自動(dòng)加載帶來(lái)的一些問(wèn)題
CPUFreq模塊

我門還沒(méi)有找到一個(gè)很好的方法加載不同的CPUFreq控制器,所以我們把從自動(dòng)加載進(jìn)程里把它去掉了。如果您需要測(cè)量CPU頻率,你必須在rc.conf的MODULES隊(duì)列中顯式的加入合適的模塊。
聲音問(wèn)題和一些不能自動(dòng)加載的模塊

一些用戶跟蹤發(fā)現(xiàn)問(wèn)題出在/etc/modprobe.conf中一些舊的部分,試著去掉這些舊的部分再試試看。
多個(gè)同類型設(shè)備(網(wǎng)卡,聲卡)每次啟動(dòng)的都不同

因?yàn)閡dev同時(shí)加載所有模塊,所以一些設(shè)備可能初始化順序不同。例如同時(shí)有兩個(gè)網(wǎng)卡時(shí),它們總是在eth0和eth1之間變來(lái)變?nèi)ァ?br />
常用的解決辦法是在您的rc.conf文件中通過(guò)修改MODULES隊(duì)列來(lái)指明順序。這個(gè)隊(duì)列里的模塊將在udev自動(dòng)加載之前由系統(tǒng)加載,因此您可以控制模塊在啟動(dòng)時(shí)加載順序。

# 在e100之前加載8139too
MODULES=(8139too e100)

另一個(gè)解決網(wǎng)卡的方法是使用udev-sanctified方法為每個(gè)網(wǎng)卡靜態(tài)命名。創(chuàng)建文件/etc/udev/rules.d/10-network.rules然后將不同的網(wǎng)卡通過(guò)MAC地址綁定到不同的名字上:

SUBSYSTEM=="net", SYSFS{address}=="aa:bb:cc:dd:ee:ff", NAME="lan0"
SUBSYSTEM=="net", SYSFS{address}=="ff:ee:dd:cc:bb:aa", NAME="wlan0"

同時(shí),您需要注意以下內(nèi)容:

    * 您可以通過(guò)下面的命令獲得網(wǎng)卡的MAC地址:: udevinfo -a -p /sys/class/net/<你的網(wǎng)卡>
    * 注意在udev規(guī)則文件中使用小寫(xiě)的16進(jìn)制MAC地址,因?yàn)閡dev無(wú)法識(shí)別大寫(xiě)的MAC地址。
    * 一些用戶在使用舊的命名方式時(shí)出現(xiàn)問(wèn)題,例如: eth0, eth1, 等等. 如果出現(xiàn)這個(gè)問(wèn)題,試試使用 "lan"或者"wlan"之類的名字.

注意不要忘記修改您的/dec/rc.conf和其它使用ethX命名的配置文件。
自己編譯內(nèi)核造成的一些已知問(wèn)題
Udev無(wú)法啟動(dòng)

請(qǐng)確定您的內(nèi)核版本大于或等于2.6.15。較早的內(nèi)核沒(méi)有udev自動(dòng)裝載所需要的uevent功能。
CD/DVD符號(hào)和權(quán)限錯(cuò)誤

如果您使用2.6.15的內(nèi)核的話,您需要安裝ABS的uevent補(bǔ)丁(它從2.6.16內(nèi)核中抽取了一些uevent功能)。您可以使用abs命令來(lái)同步ABS樹(shù),然后您就可以在/var/abs/kernels/kernel26/下找到abs補(bǔ)丁。
Udev小竅門
自動(dòng)加載usb設(shè)備

KERNEL=="sd[a-z]", NAME="%k", SYMLINK+="usb%m", GROUP="users", OPTIONS="last_rule"
ACTION=="add", KERNEL=="sd[a-z][0-9]", SYMLINK+="usb%n", GROUP="users", NAME="%k"
ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mkdir -p /mnt/usb%n"
ACTION=="add", KERNEL=="sd[a-z][0-9]", PROGRAM=="/lib/udev/vol_id -t %N", RESULT=="vfat", RUN+="/bin/mount -t vfat -o rw,noauto,sync,dirsync,noexec,nodev,noatime,dmask=000,fmask=111 /dev/%k /mnt/usb%n", OPTIONS="last_rule"
ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mount -t auto -o rw,noauto,sync,dirsync,noexec,nodev,noatime /dev/%k /mnt/usb%n", OPTIONS="last_rule"
ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/umount -l /mnt/usb%n"
ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/rmdir /mnt/usb%n", OPTIONS="last_rule"

把這些udev規(guī)則放到/etc/udev/rules.d/下任何一個(gè)文件名以.rules結(jié)尾的文件中,例如/etc/udev/rules.d/sda.rules。

如果想同時(shí)建立/media到/mnt符號(hào)連接,可以使用下面的版本:

KERNEL=="sd[a-z]", NAME="%k", SYMLINK+="usbhd-%k", GROUP="users", OPTIONS="last_rule"
ACTION=="add", KERNEL=="sd[a-z][0-9]", SYMLINK+="usbhd-%k", GROUP="users", NAME="%k"
ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mkdir -p /media/usbhd-%k"
ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/ln -s /media/usbhd-%k /mnt/usbhd-%k"
ACTION=="add", KERNEL=="sd[a-z][0-9]", PROGRAM=="/lib/udev/vol_id -t %N", RESULT=="vfat", RUN+="/bin/mount -t vfat -o rw,noauto,sync,dirsync,noexec,nodev,noatime,dmask=000,fmask=111 /dev/%k /media/usbhd-%k", OPTIONS="last_rule"
ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mount -t auto -o rw,noauto,sync,dirsync,noexec,nodev,noatime /dev/%k /media/usbhd-%k", OPTIONS="last_rule"
ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/rm -f /mnt/usbhd-%k"
ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/umount -l /media/usbhd-%k"
ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/rmdir /media/usbhd-%k", OPTIONS="last_rule"

注意!如果你是用的其它的固定設(shè)備(例如SATA的硬盤,您可以從/etc/fstab中查看)被識(shí)別為/dev/sdX,您必須從sd[a-z] 中去掉你的那個(gè)sdX。例如,如果您的SATA硬盤被是識(shí)別為/dev/sda,您就需要把所有的“sd[a-z]”替換成“sd[b-z]”。在規(guī)則文件的文件名前加上數(shù)字(如:010.udev.rules)是個(gè)很好的主意,這樣udev在讀取標(biāo)準(zhǔn)規(guī)則前,將會(huì)讀取這個(gè)規(guī)則文件。這些規(guī)則設(shè)置后不需要修改/etc/fstab文件。請(qǐng)查看mount命令的參數(shù)來(lái)修改權(quán)限等特性(您可以從論壇搜索查看mount命令的參數(shù),然后根據(jù)您的需要修改它們)。
linux_Ultra 發(fā)表于 2009-12-14 18:39:20
udev 是Linux kernel 2.6系列的設(shè)備管理器。它主要的功能是管理/dev目錄底下的設(shè)備節(jié)點(diǎn)。它同時(shí)也是用來(lái)接替devfs及hotplug的功能,這意味著它要在添加/刪除硬件時(shí)處理/dev目錄以及所有用戶空間的行為,包括加載firmware時(shí)。

udev的最新版本依賴于升級(jí)后的Linux kernel 2.6.13的uevent接口的最新版本。使用新版本udev的系統(tǒng)不能在2.6.13以下版本啟動(dòng),除非使用noudev參數(shù)來(lái)禁用udev并使用傳統(tǒng)的/dev來(lái)進(jìn)行設(shè)備讀取。
目錄
[隱藏]

    * 1 概要
    * 2 運(yùn)行方式
    * 3 系統(tǒng)架構(gòu)
    * 4 作者
    * 5 外部鏈接
    * 6 參考文獻(xiàn)

[編輯] 概要

在傳統(tǒng)的Linux系統(tǒng)中,/dev目錄下的設(shè)備節(jié)點(diǎn)為一系列靜態(tài)存在的文件,而udev則動(dòng)態(tài)提供了在系統(tǒng)中實(shí)際存在的設(shè)備節(jié)點(diǎn)。雖然devfs提供了類似功能,udev的支持者也給出了很多udev實(shí)現(xiàn)比devfs好的理由[1]:

    * udev支持設(shè)備的固定命名,而并不依賴于設(shè)備插入系統(tǒng)的順序。默認(rèn)的udev設(shè)置提供了存儲(chǔ)設(shè)備的固定命名。任何硬盤都根據(jù)其唯一的文件系統(tǒng)id、磁盤名稱及硬件連接的物理位置來(lái)進(jìn)行識(shí)別。
    * udev完全在用戶空間執(zhí)行,而不是像devfs在內(nèi)核空間一樣執(zhí)行。結(jié)果就是udev將命名策略從內(nèi)核中移走,并可以在節(jié)點(diǎn)創(chuàng)建前用任意程序在設(shè)備屬性中為設(shè)備命名。

[編輯] 運(yùn)行方式

udev是一個(gè)通用的內(nèi)核設(shè)備管理器。它以守護(hù)進(jìn)程的方式運(yùn)行于Linux系統(tǒng),并監(jiān)聽(tīng)在新設(shè)備初始化或設(shè)備從系統(tǒng)中移除時(shí)內(nèi)核(通過(guò)netlink socket)發(fā)出的uevent。

系統(tǒng)提供了一套規(guī)則用于匹配可發(fā)現(xiàn)的設(shè)備事件和屬性的導(dǎo)出值。匹配規(guī)則可能命名并創(chuàng)建設(shè)備節(jié)點(diǎn),并運(yùn)行配置程序來(lái)對(duì)設(shè)備進(jìn)行設(shè)置。udev規(guī)則可以匹配像內(nèi)核子系統(tǒng)、內(nèi)核設(shè)備名稱、設(shè)備的物理等屬性,或設(shè)備序列號(hào)的屬性。規(guī)則也可以請(qǐng)求外部程序提供信息來(lái)命名設(shè)備,或指定一個(gè)永遠(yuǎn)一樣的自定義名稱來(lái)命名設(shè)備,而不管設(shè)備什么時(shí)候被系統(tǒng)發(fā)現(xiàn)。
[編輯] 系統(tǒng)架構(gòu)
Ambox outdated serious.svg
        當(dāng)前條目或章節(jié)需要更新。
請(qǐng)更新本文以反映近況和新增內(nèi)容。完成修改時(shí),請(qǐng)移除本模板。

udev系統(tǒng)可以分為三個(gè)部分:

    * namedev函數(shù)庫(kù),處理設(shè)備的命名。
    * libsysfs函數(shù)庫(kù),進(jìn)行設(shè)備信息的讀取(080版本后廢棄)
    * 守護(hù)進(jìn)程udevd,處于用戶空間,用于創(chuàng)建虛擬/dev

系統(tǒng)獲取內(nèi)核通過(guò)netlink socket發(fā)出的信息。早期的版本使用hotplug,并在/etc/hotplug.d/default添加一個(gè)鏈接到自身來(lái)達(dá)到目的。
[編輯] 作者

udev由Greg Kroah-Hartman和Kay Sievers共同開(kāi)發(fā),并得到Dan Stekloff等人的幫助。
[編輯] 外部鏈接

    * (英文)udev在kernel.org的主頁(yè)
    * (英文)Kay Sievers寫(xiě)的udev最近動(dòng)態(tài)
    * (英文)如何編寫(xiě)udev規(guī)則
    * (英文)udev問(wèn)答集
    * (英文)Gentoo的udev指南
    * (英文)udev和devfs的對(duì)比
    * (英文)Linux1394常見(jiàn)問(wèn)題:在不同驅(qū)動(dòng)器上創(chuàng)建設(shè)備節(jié)點(diǎn)要如何設(shè)置udev規(guī)則
    * (英文)udev教程

[編輯] 參考文獻(xiàn)

   1. ^ (英文)udev and devfs - The final word(2003年12月30日).於2008年1月13日查閱.
geyingzhen 發(fā)表于 2009-12-15 15:26:24
alpha321 發(fā)表于 2009-12-16 09:42:14
非常感謝樓主提供這么精彩的文章!
cybxlyh 發(fā)表于 2011-1-26 11:30:56
樓主,我在板子上運(yùn)行udevd后,插入U(xiǎn)盤,內(nèi)核有打印信息,并且在/sys/block下有sdb,sdb1以及里面的dev和uevent,但是udevd卻捕獲不到uevent事件,導(dǎo)致無(wú)法創(chuàng)建節(jié)點(diǎn),規(guī)則文件無(wú)法運(yùn)行,U盤也無(wú)法掛載。如果我運(yùn)行udevstart,節(jié)點(diǎn)就可以被創(chuàng)建,規(guī)則文件就能被執(zhí)行,實(shí)現(xiàn)U盤掛載,這說(shuō)明dev,uevent事件是有效的,只是udevd無(wú)法自動(dòng)進(jìn)行捕獲處理,你知道這會(huì)是什么原因嗎?
freeboy898 發(fā)表于 2011-11-4 14:46:15
相當(dāng)詳細(xì)的文章哦,非常感謝樓主分享!
wk978 發(fā)表于 2016-8-14 15:02:36
謝謝分享
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

廠商推薦

  • Microchip視頻專區(qū)
  • Chiptorials ——如何將CryptoAuthLib庫(kù)用于Microchip安全身份驗(yàn)證IC
  • Chiptorials——如何使用ATECC608 TrustFLEX實(shí)現(xiàn)公鑰輪換
  • Chiptorials ——使用ATECC608 TrustFLEX實(shí)現(xiàn)基本非對(duì)稱身份驗(yàn)證
  • FPGA設(shè)計(jì)流程培訓(xùn)教程
  • 貿(mào)澤電子(Mouser)專區(qū)

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 免费观看四虎精品国产永久 | 国产精品一区二区在线观看完整版 | 思思久久好好热精品国产 | 久久精品店 | 操操综合| 特黄特级高清免费视频毛片 | 亚洲成人网在线 | 欧美性色黄大片在线观看 | 亚洲国产日韩在线一区 | 污视频网站在线观看免费 | 一级片免费在线播放 | 久久好色 | 成人在线免费播放 | 2022av视频 | 天天射美女| 另类专区 亚洲 | 日韩精品福利视频一区二区三区 | 日韩免费视频一区 | 国产精品欧美一区喷水 | 日韩 亚洲 制服 欧美 综合 | 亚洲黄色高清视频 | 国产激情一区二区三区成人91 | 免费色播| 国产成人精品久久二区二区 | 四虎永久视频 | 国产成人福利在线视频下载 | 亚洲欧美综合在线观看 | 亚洲不卡免费视频 | 亚洲国产成人久久精品app | 欧美成人777 | 97国产成人精品免费视频 | 青青国产视频 | 日日夜夜噜噜噜 | 日本h在线精品免费观看 | 国产一级毛片高清视频在线 | 91精品国产福利在线观看 | 精品在线视频播放 | 九九视频网 | 六月婷婷综合 | 亚洲激情 欧美 | 俺也来国产精品欧美在线观看 |