1. 程式人生 > >udev和mdev學習總結

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