顯示具有 udev device node 屬性 hotplug rule udevinfo 標籤的文章。 顯示所有文章
顯示具有 udev device node 屬性 hotplug rule udevinfo 標籤的文章。 顯示所有文章

2009年3月20日 星期五

udev操作 如何從udevinfo udevmonitor的觀察來寫udev rule

udev
userspace device management
目的是允許使用者動態的管理device node


#===============
# 緣起
#===============
1.
device node是Linux系統user space跟hardware device溝通的介面
$ ls -al /dev
...
crw-rw---- 1 root audio 14, 12 2009-03-18 08:54 adsp //ALSA audio
crw-rw---- 1 root dialout 188, 0 2009-03-18 17:05 ttyUSB0 //usb serial port
brw-rw---- 1 root disk 8, 1 2009-03-18 08:54 sda1 //HD
brw-rw---- 1 root disk 1, 0 2009-03-18 08:54 ram0 //ram
crw-rw---- 1 root audio 10, 135 2009-03-18 08:54 rtc //real time clock
...
P.S.
c: character device, b: block device

2.
傳統使用者自己手動device node,
後來有devfs可以自動建立device node,但有缺點是建立的規則是寫在driver內,無法在user space決定node的名字屬性等等[2]

3.
sysfs是一個在2.6 kernel新出的檔案系統,由kernel本身管理,當device plug進系統時,會顯示基本的device資訊,udev會利用這個資訊,以及設定的rule條件,來建立
或是執行一些額外的程式

#===============
# 提供的功能
#===============
1. Rename a device node from the default name to something else
(自己可以device node名字)
2. Provide an alternative/persistent name for a device node by creating a symbolic link to the default device node
(可以建立device node別名-symbolic link)
3. Name a device node based on the output of a program
(名字的決定還可以呼叫外部程式)
4. Change permissions and ownership of a device node
(預設建立的device node權限可以改變)
(例如usb device預設建立出來0660,可以改變一建立就是0666)
5. Launch a script when a device node is created or deleted (typically when a device is attached or unplugged)
(可以在device node建立或是刪除時執行外部script)
6. Rename network interfaces
(network interface也可以改名)
[1]

#===============
# rules的範例
#===============
+------------------------------------------------------------------------------------------------
Q1. Change permissions and ownership of a device node

dnwOTG USB driver是一個根據drivers/usb/usb-skeleton.c的usb driver
當VENDOR_ID和PRODUCT_ID符合的裝置plug之後,會主動建立/dev/dnwOTG這device node
但是他的權限是0660 root root所以變成一般使用者無法直接read/write
一般情況
$ ll /dev/dnwOTG -al
crw-rw---- 1 root root 180, 192 2009-03-18 18:36 /dev/dnwOTG

如何加入規則希望變成這樣
$ ll /dev/dnwOTG -al
crw-rw-rw- 1 root root 180, 192 2009-03-18 18:35 /dev/dnwOTG

Answer:
1. 使用工具程式udevmonitor
$ udevmonitor --udev
(執行dnw c2000000, 使得usb device出現,會觀察到)

UDEV [1237372815.218233] add /devices/pci0000:00/0000:00:1d.7/usb5/5-3 (usb)
UDEV [1237372815.218391] add /class/usb_endpoint/usbdev5.118_ep00 (usb_endpoint)
UDEV [1237372815.255269] add /devices/pci0000:00/0000:00:1d.7/usb5/5-3/5-3:1.0 (usb)
UDEV [1237372815.255379] add /class/usb/dnwOTG (usb)
^^^^^^^^^^^^^^^^^^^^
UDEV [1237372815.255465] add /class/usb_endpoint/usbdev5.118_ep81 (usb_endpoint)
UDEV [1237372815.255550] add /class/usb_endpoint/usbdev5.118_ep02 (usb_endpoint)
UDEV [1237372815.278249] add /class/usb_device/usbdev5.118 (usb_device)

得知有這一udev event

2. 使用工具程式udevinfo
$ udevinfo -a -p /class/usb/dnwOTG
...
looking at device '/class/usb/dnwOTG':
KERNEL=="dnwOTG"
SUBSYSTEM=="usb"
DRIVER==""
ATTR{dev}=="180:192"
...

3. 加入規則改變mode
sudo vi /etc/udev/rules.d/40-permissions.rules
最後一行加入
KERNEL=="dnwOTG", MODE="0666"

+------------------------------------------------------------------------------------------------
Q2. 希望能當mvp kernel開完,OTG ready同時在host PC自己建立好network usb0 (不用在ifdown usb0;ifup usb0)

Answer:
1. 使用工具程式udevmonitor
$ udevmonitor --udev
...
UDEV [1237373325.456422] add /class/usb_endpoint/usbdev5.122_ep01 (usb_endpoint)
UDEV [1237373325.462935] add /class/usb_device/usbdev5.122 (usb_device)
UDEV [1237373325.632610] add /class/net/usb0 (net)
^^^^^^^^^^^^^^^^^
...

得知有這一udev event

2. 使用工具程式udevinfo
$ udevinfo -a -p /class/net/usb0
...
looking at device '/class/net/usb0':
KERNEL=="usb0"
SUBSYSTEM=="net"
DRIVER==""
ATTR{weight}=="0"
ATTR{tx_queue_len}=="1000"
ATTR{flags}=="0x1003"
ATTR{mtu}=="1500"
ATTR{operstate}=="unknown"
ATTR{dormant}=="0"
ATTR{carrier}=="1"
ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
ATTR{address}=="42:f9:d6:bf:97:10"
ATTR{link_mode}=="0"
ATTR{type}=="1"
ATTR{features}=="0x0"
ATTR{ifindex}=="31"
ATTR{iflink}=="31"
ATTR{addr_len}=="6"
...

3. 加入規則
sudo vi /etc/udev/rules.d/80-programs.rules
最後加入
# 當usb0進來且條件是SUBSYSTEM=="net", ACTION=="add" 執行/lib/udev/usb0nic的程式
KERNEL=="usb0", SUBSYSTEM=="net", ACTION=="add", \
RUN+="usb0nic on"

# 當usb0進來且條件是SUBSYSTEM=="net", ACTION=="remove" 執行/lib/udev/usb0nic的程式
KERNEL=="usb0", SUBSYSTEM=="net", ACTION=="remove", \
RUN+="usb0nic off"

4. 編輯usb0nic
$ sudo vi /lib/udev/usb0nic
#! /bin/sh
if test -z "$1"
then
exit
else
if [ $1 == "on" ];then
usb_exist=`ifconfig | awk '/usb0/{print $1}'`
if [ $usb_exist == "usb0" ]; then
ifdown usb0
fi
ifup usb0
fi
if [ $1 == "off" ];then
ifdown usb0
fi
fi

$ sudo chmod +x /lib/udev/usb0nic

#===============
# 參考資料
#===============
1. [Writing udev rules,version 0.74], Daniel Drake (dsd), http://reactivated.net/writing_udev_rules.html
詳細說明如何寫udev rules,使用實際範例說明,淺顯易懂
2. [udev and devfs - The final word], Greg Kroah-Hartman, http://kernel.org/pub/linux/utils/kernel/hotplug/udev_vs_devfs
udev的創始者說明udev跟devfs的差異和比較