udev 文件系統製作

第一、什麼是udev?



這篇文章UDEV Primer給我們娓娓道來,花點時間預習一下是值得的。當然,不知道udev是什麼也沒關係,

把它當個助記符好了,有了下面的上路指南,可以節省很多時間。我們只需要樹立一個信念:udev很簡單!

嵌入式的udev應用尤其簡單。



第二、爲什麼udev要取代devfs?



這是生產關係適應生產力的需要,udev好,devfs壞,用好的不用壞的。



udev是硬件平臺無關的,屬於user space的進程,它脫離驅動層的關聯而建立在操作系統之上,基於這種設

計實現,我們可以隨時修改及刪除/dev下的設備文件名稱和指向,隨心所欲地按照我們的願望安排和管理設

備文件系統,而完成如此靈活的功能只需要簡單地修改udev的配置文件即可,無需重新啓動操作系統。udev

已經使得我們對設備的管理如探囊取物般輕鬆自如。




第三、如何得到udev?



udev的主頁在這裏:http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html

我們按照下面的步驟來生成udev的工具程序,以arm-linux爲例:



1、 下載最新的udev

     wget http://www.us.kernel.org/pub/linux/utils/kernel/hotplug/udev-113.tar.bz2

     或其他的方法下載udev-113.tar.bz2 。



2、解壓udev-113.tar.bz2

    tar jxvf udev-113.tar.bz2



3、修改Makefile

    cd   udev-113

    編輯Makefile,查找CROSS_COMPILE,修改CROSS_COMPILE ?= arm-linux-



4、編譯(交叉編譯器要用2.95.3以上的,不然可能編譯過不去。我用的是3.4.1)

    export PATH=/usr/local/arm/3.4.1/bin:$PATH

    make



    沒有什麼意外的話當前目錄下生成udev,udevcontrol,udevd,udevinfo,udevmonitor,udevsettle,udevstart,

    udevtest,udevtrigger九個工具程序,在嵌入式系統裏,我們只需要udevd和udevstart就能使udev工作得很好,

    其他工具則幫助我們完成udev的信息察看、事件捕捉或者更高級的操作。



5、看看用到了哪共享些庫

    arm-linux-readelf -a udevstart | grep "Shared library"

    ----------------------------------------------------------------------------------

    eg:

    [root@localhost udev-113]# arm-linux-readelf -a udevstart | grep "Shared library"

     0x00000001 (NEEDED)                      Shared library: [libc.so.6]

    ----------------------------------------------------------------------------------

    說明用到了libc.so的庫,所以要把 libc.so 和 libc.so.6 庫拷貝到文件系統的/lib目錄.

   其它共享庫,用同樣方法只是把arm-linux-readelf -a udevstart | grep "Shared library"中的

    udevstart 改成 別的文件名。



6、拷貝相應的共享庫到/lib目錄(共享庫指交叉編譯器的庫在本文用到的庫在 /usr/local/arm/3.4.1).

    (/lib是你建的文件系統的目錄,不是你的電腦的/lib。提醒下就怕新手盲目亂做。)




ld-2.3.2.so   ld-linux.so.2   libc.so.6   libc.so   libc-2.3.2.so




第四、如何配置udev?



首先,udev需要內核sysfs和tmpfs的支持,sysfs爲udev提供設備入口和uevent通道,tmpfs爲udev設備文件提

供存放空間,也就是說,在上電之前系統上是沒有足夠的設備文件可用的,我們需要一些技巧讓kernel先引導

起來。



於在kernel啓動未完成以前我們的設備文件不可用,如果使用mtd設備作爲rootfs的掛載點,這個時候/dev/mtdblock

這個設備目錄是不存在的,我們無法讓kernel通過/dev/mtdblock/X這樣的設備找到rootfs,kernel只好停在那裏驚慌。

這個問題我們可以通過給kernel傳遞設備號的方式來解決,在linux系統中,mtdblock的主設備號是31,part號

從0開始,那麼以前的/dev/mtdblock/3就等同於31:03,以次類推,所以我們只需要修改bootloader傳給kernel

的cmd line參數,使root=31:03,就可以讓kernel在udevd未起來之前成功的找到rootfs。



另外一種方法就是給kernel傳遞未經歸類的設備文件名,在udev未創建之前,所有的設備實際上已經通過sysfs

建立,mtdblockX的位置相對於/sys/block/mtdblockX/dev,這個文件裏存放着mtdblockX的設備號,形式與上

一種方式相同。這時由於沒有相應的udev規則,所有的設備都被隱含地映射到/dev目錄下,mtdblockX對應於

/dev/mtdbockX,這樣我們給kernel傳遞root=/dev/mtdblock3,kernel發現/dev沒有被建立,就自動從映射表裏

查找對應關係,最後取出/sys/block/mtdblockX/dev裏的設備號,完成rootfs的掛載。




O.K.下一個問題。



其次,需要做的工作就是重新生成rootfs。

      1.把udevd和udevstart,test-udev,udevcontrol,udevtrigger,

         udevinfo,udevmonitor,udevsettle,udevtest複製到/sbin目錄。

      2. 然後我們需要在/etc/下爲udev 建立設備規則



        建立設備規則是udev最爲複雜的一步。這篇文章提供了最完整的指導:Writing udev rules

        文中描述的複雜規則我們可以暫時不用去理會,上路指南將帶領我們輕鬆穿過這片迷霧。

        這裏提供一個由簡入繁的方法,對於嵌入式系統,這樣做可以一勞永逸。



1、在前面用到的udev-113目錄裏,有一個etc目錄,裏面放着的udev目錄包含了udev設備規則的詳細樣例文

本。爲了簡單而又簡潔,我們只需要用到etc/udev/udev.conf這個文件,在我們的rootfs/etc下建立一個udev目

錄,把它複製過去,這個文件很簡單,除了註釋只有一行,是用來配置日誌信息的,嵌入式系統也許用不上

日誌,但是udevd需要檢查這個文件。



2、在rootfs/etc/udev下建立一個rules.d目錄.

         mkdir   -p   rootfs/etc/udev/rules.d


    生成一個空的配置文件

        touch etc/udev/rules.d/udev.rules。




3. 然後在rootfs/etc/udev/目錄下新建udev.conf文件。


      touch etc/udev/udev.conf



     然後 我們來編輯這個文件並向它寫入以下配置項:



###############################################

udev_root="/dev/"

udev_rules="/etc/udev/rules.d/"

udev_log="err"



# 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"

################################################



        保存它爲 udev.conf,注意: udev.conf的位置是rootfs/etc/udev/udev.conf

        我們的設備文件系統基本上就可以了,udevd和udevstart會自動分析這個文件。



4、   爲了使udevd在kernel起來後能夠自動運行,我們在rootfs/etc/init.d/rcS中增加以下幾行:



##################################

/bin/mount -t tmpfs tmpfs /dev

         /bin/mount -t sysfs sysfs /sys


         #掛載/proc爲proc文件系統

echo "mount /proc as proc"

/bin/mount -n -t   proc none /proc



echo "Starting udevd..."

/sbin/udevd --daemon

/sbin/udevstart

##################################




5、   還有一點就是別忘要在/dev下手工建console和null等設備。

      cd /dev

      mknod -m 660 console c 5 1

      mknod -m 660 null     c 1 3




6、   重新生成rootfs,燒寫到flash指定的rootfs part中。



7、   如果需要動態改變設備規則,可以把etc/udev 放到jffs或yaffs part,以備修改,根據需求而定,可以隨時擴

      充udev.conf中的配置項。




8、生成文件系統。(不同的板子,和文件系統,或目錄不同,下面的方法不是通用的根據個人情況改下。)

    ./mkfs.jffs2 -p -l -e 0x20000 -n -v -r /data/rootfs2.6/ -o filesys.jffs2




支持熱拔插。

echo /sbin/mdev > /proc/sys/kernel/hotplug



==================================================================================

    我的rcS文件

==================================================================================

#! /bin/sh



PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:

runlevel=S

prevlevel=N

umask 022

export PATH runlevel prevlevel



#

# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.

#

trap ":" INT QUIT TSTP




HOSTNAME=OMAP5912OSK

hostname $HOSTNAME

echo ""

echo "******************************************"

echo "Starting System Init for $HOSTNAME"

echo "******************************************"



# goto the init.d directory

cd /etc/init.d



# Mount the default file systems

mount -a # Mount the default file systems



/bin/mount -t tmpfs tmpfs /dev

/bin/mount -t sysfs sysfs /sys




echo "Starting udevd..."

/sbin/udevd --daemon

/sbin/udevstart



/etc/rc.d/init.d/netd start

/etc/rc.d/init.d/httpd start



/sbin/ifconfig lo 127.0.0.1

/sbin/ifconfig eth0 192.168.0.2 up

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章