udev和mdev hotplug事件

关于udev和mdev之间的区别与联系我发现自己现在还没有把它完整的给区分开来和联系起来.

    设备文件系统有devfs,mdev,udev

    mdev是udev的简化版本,是busybox中所带的程序,最适合用在嵌入式系统,而udev一般用在PC上的linux中,相对mdev来说要复杂些,devfs是2.4内核引入的,而在2.6内核中却被udev所替代,他们有着共同的优点,只是devfs中存在一些未修复的BUG,作者也停止了对他的维护,最显著的一个区别,采用devfs时,当一个并不存在的设备结点时,他却还能自动的加载对应的设备驱动,而udev则不能,udev认为当加载了不存在的对应的设备驱动的时候不应加载对应的驱动模块,因为加载也没有,浪费了资源.
  从本质上来说,udev与mdev他们都是一个应用程序,配置了就可以使用,为了方便使用,我们可以使用busybox自带的mdev,当然也可以去下载udev的源码去编译和移植.

  这应该是对udev和mdev的一个理解,我们下次可以再深入一些.

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

这段内容总结的很好,我也看了linux内核有关uevent的代码,的确是这样,这样看来简单的将mdev看做udev的简化版也就不准确了。这样在做嵌入式的文件系统就要注意了,一般只会使用mdev,目前我还不确定能不能只用udev,理论上是可以的,当然两种一起用也是可以的,也就是mdev + udev,但是这时要注意了,写规则时一定要注意,避免让它们重复执行。也就是说udev执行过的,mdev不要再执行了。其实udev最大的特点就是使用了netlink,实质上是一个scoket,这个特别的scoket用来监测uevent,当然,我们也可以自己写一个函数用来监测任何uevent事件。

首先介绍一下mdev与udev之间的关系:

        mdev是busybox中的一个udev管理程序的一个精简版,他也可以实现设备节点的自动创建和设备的自动挂载,只是在实现的过程中有点差异,在发生热插拔时间的时候,mdev是被hotplug直接调用,这时mdev通过环境变量中的 ACTION 和 DEVPATH,来确定此次热插拔事件的动作以及影响了/sys中的那个目录。接着会看看这个目录中是否有“dev”的属性文件,如果有就利用这些信息为这个设备在/dev 下创建设备节点文件。

 

 

/***********************************************************************************************************************************************************************************/

1.mdev支持

①用busybox制作根文件系统的时候,要选择支持mdev机制

Linux System Utilities  --->   
           [*] mdev      
           [*]   Support /etc/mdev.conf
           [*]     Support command execution at device addition/removal

②在文件系统/etc/init.d/rsC文件中添加如下内容

Vi  /etc/init.d/rcS
        mount -t tmpfs mdev /dev 
        mount -t sysfs sysfs /sys
        mkdir /dev/pts
        mount -t devpts devpts /dev/pts

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

这些语句的添加在busybox的/doc/mdev.txt中可以找到。

 

③添加对热插拔事件的响应,实现U盘和SD卡的自动挂载。

Vi /etc/mdev.conf
       sd[a-z][0-9]      0:0 666        @/etc/mdev/udisk_insert                        

         sd[a-z]                   0:0 666          $/etc/mdev/udisk_remove

红色部分,是一个脚本,脚本内容可以根据我们的需要定制,可以实现挂载,卸载或其他一些功能。

注:@表示是在插入(创建设备结点)后执行后面的脚本,$表示在拔出(删除设备结点)前执行后面的脚本。

如下是自动挂载和卸载的脚本名称及其内容:

#!/bin/sh

if [ -d /sys/block/*/$MDEV ]  ; then

  mkdir -p /media/$MDEV

  mount /dev/$MDEV /media/$MDEV 

fi

根文件系统中的etc/mdev/udisk_remove文件内容:
        #!/bin/sh
        umount -l /media/$MDEV
        rm -rf /media/$MDEV
 
        #!/bin/sh
        umount -l /media/sd*
        rm -rf /media/sd*

修改为红色部分后能够自动挂载

以上两个脚本需要可执行权限:chmod +x  /etc/mdev/udisk_insert

               chmod +x etc/mdev/udisk_remove

/***********************************************************************************************************************************************************************************/

2.udev支持 

        linux传统上使用静态设备创建的方法,在dev下创建了大量的节点,而不管这些节点相应的硬件设备是否存在。采用udev的方法,系统检测到设备才会去创建这些设备对应的节点。

        这里我们简单的说一下udev的工作原理:

        udev是依赖于sysfs的,当系统中添加一个新的设备后,内核检测到后就会产生一个hotplug event并查找/proc/sys/kernel/hotplug去找出管理设备连接的用户空间程序,若udev已经启动,内核会通知udev去检测sysfs中关于这个新设备的信息并创建设备节点。如/dev/vcs,在/sys/class/tty/vcs/dev存放的是”7:0”,既/dev/vcs的主次设备号。并且udev还会根据/etc/udev/rules.d中的规则文件实现一些相应的功能。

下面我们介绍一下如何实现设备节点的自动创建及u盘或sd卡的自动挂载。

因为文件系统中默认是没有对udev进行支持的,所以我们移植一个udev。

1.下载udev源码udev-100.tar.bz2,并解压

网址:http://www.us.kernel.org/pub/linux/utils/kernel/hotplug

2.交叉编译。

修改makefile,具体修改如下:

        cross = arm-linux-

保存退出。

然后执行命令:make 进行编译,然后执行arm-linux-strip udev udevd udevstart udevinfo udevtest,并拷贝这些文件到目标板根文件/bin目录下面。

3.添加udev的支持

下面三种方法功能相同

        (1)并修改etc/init.d/rcs脚本,然后添加如下命令:

        /bin/mount -t sysfs sysfs /sys 

        /bin/mount -t tmpfs tmpfs /dev

        /bin/udevd --daemon

        /bin/udevstart

        (2)如果linuxrc是二进制文件的话 

        rm /linuxrc

        vi /linuxrc

        添加如下内容

        /bin/mount -t sysfs sysfs /sys

        /bin/mount -t tmpfs tmpfs /dev

        /bin/udevd --daemon

        /bin/udevstart

        exec /sbin/init

        (3)修改/etc/fstab为

        #device mount-point type options dump fsck order

        proc /proc proc defaults 0 0

        tmpfs /tmp tmpfs defaults 0 0

        sysfs /sys sysfs defaults 0 0

        tmpfs /dev tmpfs defaults 0 0

        修改/etc/init.d/rcs,添加如下内容

/bin/udevd --daemon

/bin/udevstart

        重新启动系统,文件系统就能够自动创建节点。

 

4.在/etc下创建udev目录

5.在/etc/udev下穿件目录rules.d和文件udev.conf

6.在udev.conf中添加如下内容

# udev.conf

        # the initial syslog(3) priority: "err", "info", "debug" or its

        # numerical equivalent. for runtime debugging, the daemons internal

        # state can be changed with: "udevcontrol log_priority=<value>".

        udev_log="err"

7.在rules.d下创建规则文件

如实现u盘自动挂载

        vim 11-add-usb.rules

添加如下内容

        action!="add",goto="farsight"

        kernel=="sd[a-z][0-9]",run+="/sbin/mount-usb.sh %k"

        label="farsight"

这个文件中action后是说明是什么事件,kernel后是说明是什么设备比如sda1,mmcblk0p1等,run这个设备插入后去执行哪个程序%k是传入这个程序的参数,这里%k=kernel的值也就是sda1等http://www.woaidiannao.com。

在/sbin/下创建mount-usb.sh文件添加如下内容 计算机

        #!/bin/sh

        /bin/mount -t vfat /dev/$1 /tmp

        sync

修改文件权限为其添加可执行的权限。

这样就实现了u盘的自动挂载,下面附上u盘的卸载规则文件和sd卡的文件

usb卸载

11-add-remove.rules

        action !="remove",goto="farsight"

        subsystem!="block",goto="farsight"

        kernel=="sd[a-z][0-9]",run+="/sbin/umount-usb.sh"

        label="farsight"

umount-usb.sh

        #!/bin/sh

        sync

        umount /tmp/

sd卡挂载

12-add-sd.rules

action!="add",goto="farsight"

        kernel=="mmcblk[0-9]p[0-9]",run+="/sbin/mount-sd.sh %k"

        label="farsight"

mount-sd.sh

        #!/bin/sh

        /bin/mount -t vfat /dev/$1 /tmp

        sync

 

sd卸载

12-remove-sd.rules

        action !="remove",goto="farsight"

        subsystem!="block",goto="farsight"

        kernel=="mmcblk*",run+="/sbin/umount-sd.sh"

        label="farsight"

umount-sd.sh

        #!/bin/sh

        sync

        /bin/umount /tmp/

 

mdev的hotplug模式

1, busybox 添加mdev支持

mdev hotplug

2, 在/etc/rc.d/rcS中添加

#mount filesystem

/bin/mount -a

#start mdev

echo /sbin/mdev > /proc/sys/kernel/hotplug    #设置系统的hotplug程序为mdev

mdev –s

/etc/fstab的内容如下:

proc    /proc   proc    defaults    0   0

none    /tmp    ramfs   defaults        0       0

mdev    /dev    ramfs   defaults        0       0

sysfs   /sys    sysfs   defaults        0       0

执行mdev -s :以‘-s’为参数调用位于 /sbin目录写的mdev(其实是个链接,作用是传递参数给/bin目录下的busybox程序并调用它),mdev扫描 /sys/class 和 /sys/block 中所有的类设备目录,如果在目录中含有名为“dev”的文件,且文件中包含的是设备号,则mdev就利用这些信息为这个设备在/dev 下创建设备节点文件。一般只在启动时才执行一次 “mdev -s”。

热插拔事件:由于启动时运行了命令:echo /sbin/mdev > /proc/sys/kernel/hotplug ,那么当有热插拔事件产生时,内核就会调用位于 /sbin目录的mdev。这时mdev通过环境变量中的 ACTION 和 DEVPATH,来确定此次热插拔事件的动作以及影响了/sys中的那个目录。接着会看看这个目录中是否有“dev”的属性文件,如果有就利用这些信息为这个设备在/dev 下创建设备节点文件。

解决使用mdev时“cannot create /proc/sys/kernel/hotplug:nonexistent directory”错误

确保编译内核时编译如下选项:

CONFIG_PROC_FS=y

CONFIG_PROC_SYSCTL=y

CONFIG_HOTPLUG=y

CONFIG_NET=y

如果CONFIG_HOTPLUG和CONFIG_NET不选或没全选上的话,/proc/sys/kernel下将不会创建hotplug文件.(参见kernel/sysctl.c)

解读CPU模式hotplug、ondemand等的意义

【hotplug】热拔插模式:
→和ondemand模式差不多,当有高需求时直接跳到最高频率,当需求见效时逐级降低频率,
但关屏时就单核低频运行,省电。

【ondemand】按需模式:
→按需调节cpu频率,不操作手机的时候控制在最低频率,滑屏或进入应用后会迅速提升至最
高频率,当空闲时迅速降低频率,性能较稳定,但因频率变化幅度过大,省电方面只有一般的水
平。是一种在电池和性能之间趋向平衡的默认模式,但是对于智能手机来说,ondemand在性
能表现方面略有欠缺。

【userspace】用户模式:
→任何情况下都会控制CPU运行在配置的频率范围内,配置中的用户自己添加的省电设置。
在此情景模式下,降低CPU最大运行频率可以延长电池待机时间,但同时也会降低机器的唤
醒速度,建议最好不使用该选项。

【interactive】交互模式:
→和ondemand相似,规则是“快升慢降”,注重响应速度、性能,当有高需求时迅速跳到高频率,
当低需求时逐渐降低频率,相比ondemand费电

【performance】高性能模式:
→高性能模式,按你设定范围的最高频率运行,即使系统负载非常低cpu的频率也为最高。性能
很好,因为CPU本身不需要资源去调整频率,但是电量消耗较快,温度也高一些。

猜你喜欢

转载自www.cnblogs.com/klb561/p/9245883.html