udev和mdev學習總結
Udev介紹
Udev分為三個子計劃:namedev,libsysfs和udev。Namedev為裝置命名子系統,libsysfs提供訪問sysfs檔案系統,從中獲取資訊的標準介面。Udev是提供/dev裝置節點檔案的動態建立和刪除策略。
Namedev 使用5個步驟來決定指定裝置的命名。
(1) 標籤/序列號
(2) 裝置匯流排號
(3) 總線上的拓撲
(4) 替換名稱
(5) 核心提供的名稱
Udev的規則檔案
Udev規則檔案以行為單位,以“#”開頭的代表註釋行,其餘的一行代表一個規則
規則分為匹配和賦值兩部分。兩部分皆有自己的關鍵字。
匹配關鍵字:
ACTION,用於匹配行為
KERNEL,匹配核心裝置名
BUS,匹配匯流排
SYSFS,匹配從sysfs得到的資訊,比如label,vendor,USB序列號。
SUBSYSTEM,匹配子系統名
賦值關鍵字
NAME,建立檔案裝置名
SYMLINK,符號連結名
OWNER,設定裝置的所有者
GROUP,設定裝置的組
IMPORT,呼叫外部程式
建立和配置udev
本人下載了udev-126,udev-100,udev-172, 使用udev-172無法編譯通過,udev-126不能得到試驗所說的9個工具程式,只有udevd,test-udev,udevadm三個工具程式。Udev-100可得到全部的9個程式
Udev-126的配置:./configure --prefix=/home/uncompress_software/udev-126/
--target=arm-linux --host=arm-vfp-linux-gnu LD=arm-vfp-linux-gnu-ld
make
make install
udev-100:修改了Makefile,其中包括CROSS_COMPILE,prefix兩個地方。
由於在kernel啟動未完成以前我們的裝置檔案不可用,如果使用mtd裝置作為rootfs的掛載點,這個時候/dev/mtdblock
是不存在的,我們無法讓kernel找到rootfs,kernel只好停在那裡驚慌。 這個問題我們可以通過給kernel傳遞裝置號的方式來解決,在linux系統中,mtdblock的主裝置號是31,part號 從0開始,那麼以前的/dev/mtdblock/3就等同於31:03,以次類推,所以我們只需要修改bootloader傳給kernel 的cmd line引數,使root=31:03,就可以讓kernel在udevd未起來之前成功的找到rootfs。
在嵌入式系統中,只需要udevd和udevstart就能使udev正常工作。
將生成的udevd和udevstart複製到/sbin目錄,同時將udev原始碼目錄中etc/udev的檔案複製到系統/etc目錄下。
最後編寫啟動,停止,重新啟動等工作的udev指令碼。
Mdev介紹
以下內容來自mdev入門
mdev有兩個主要的應用:初始化物件和動態更新。兩個應用都需要核心sysfs的支援。為了實現動態更新,你必須在核心配置時增加熱挺拔支援。
以下是系統初始化指令碼中一個典型的使用mdev 的程式碼片段:
[1] mount -t sysfs sysfs /sys
[2] echo /bin/mdev > /proc/sys/kernel/hotplug
[3] mdev -s
簡單說明一下上面的程式碼:
[1]你必須在執行mdev 前掛載 /sys 。
[2] 命令核心在增刪裝置時執行 /bin/mdev ,使裝置節點檔案會被建立和刪除。
[3] 設定mdev,讓它在系統啟動時建立所有的裝置節點。
當然,一個對mdev 更完整的安裝還必須在以上程式碼片段前執行下面的命令:
[4] mount -t tmpfs mdev /dev
[5] mkdir /dev/pts
[6] mount -t devpts devpts /dev/pts
[4]確保 /dev 是 tmpfs 檔案系統(假設檔案系統在 flash 外執行)。
[5] 建立/dev/pts 掛載點
[6] 在 /dev/pts 掛載 devpts 檔案系統
例如:
#!/bin/sh
if [ ! -x /sbin/mdev ]
then
exit 0
fi
case "$1" in
start)
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
# put /dev in a tmpfs
mount -n -o mode=0755 -t tmpfs mdev /dev
# Create static device nodes in /dev
mknod /dev/console c 5 1
chmod 600 /dev/console
mknod /dev/null c 1 3
chmod 666 /dev/null
# make and mount devpts
mkdir /dev/pts
mount -n -t devpts devpts /dev/pts
echo "Starting the hotplug events dispatcher mdev"
/sbin/mdev -s
mkdir /dev/shm
;;
stop)
;;
*)
echo "Usage: /etc/rc.d/init.d/mdev {start|stop}"
echo
exit 1
;;
esac
exit 0
說明:以上內容就是mdev的啟動指令碼,基本體現了上面的6個步驟。
Mount –n,掛載但不寫入
--blind,將一個子樹重新掛載到其它地方,使有多個地方可以見到些子樹
--move ,和blind有可比性,此項是移動子樹
Uevent,mdev,udev
如果你對linux裝置模型瞭解的很清楚,那麼很自然就會想起驅動模型中的uevent。
以下內容來自張俊嶺《對Linux 裝置驅動模型的一些理解》
uevent 是“user event”的簡稱,是一種核心向用戶空間傳送資訊的方式。Linux 核心的熱拔插機制(hotplug)就是通過uevent 實現的。
當在匯流排中註冊和刪除一個裝置或一個裝置驅動程式時,會呼叫kobject_uevent()產生uevent。kobject_uevent()的程式碼在lib/kobject_uevent.c 中,
1.查詢kobject 所屬的kset,並獲得kset 的uevent_ops如果kobj->uevent_suppress 為1,表示當前kobject 禁止產生uevent,返回0
2. 呼叫kset->uevent_ops->filter(),如果返回0,表示kset 禁止產生uevent,返回0
3.如果核心支援網路功能,使用netlink Socket 向用戶空間廣播uevent
4.如果uevent_helper 有效,則呼叫它。
udev 和mdev 是兩個使用uevent 機制處理熱插拔問題的使用者空間程式,兩者的實現機理不同。udev 是基於netlink 機制的,它在系統啟動時運行了一個deamon 程式udevd,通過監聽核心傳送的uevent 來執行相應的熱拔插動作,包括建立/刪除裝置節點,載入/解除安裝驅動模組等等。mdev 是基於uevent_helper 機制的,它在系統啟動時修改了核心中的uevnet_helper 變數(通過寫/proc/sys/kernel/hotplug),值為“/sbin/mdev”。這樣核心產生uevent 時會呼叫uevent_helper 所指的使用者級程式,也就是mdev,來執行相應的熱拔插動作。udev 使用的netlink 機制在有大量uevent 的場合效率高,適合用在PC 機上;而mdev 使用的uevent_helper 機制實現簡單,適合用在嵌入式系統中。另外要說明的一點是,uevent_helper 的初始值在核心編譯時時可配置的,預設值為/sbin/hotplug。如果想修改它的值,寫/proc/sys/kernel/hotplug 檔案就可以了,例如:
echo “/sbin/mdev” > /proc/sys/kernel/hotplug
補充一點:如果使用的是udevd,那麼uevent_helper變數應為空,即
echo “ ” > /proc/sys/kernel/hotplug