如何使用Linux系统下的mdev实现动态更新设备节点及动态挂载U盘

嵌入式技术

1343人已加入

描述

    大家好,我是ST。

    今天主要聊一聊,如何使用Linux系统下的mdev实现动态更新设备节点及动态挂载U盘。

 

第一:mdev基本简介

    Linux传统上使用静态设备创建的方法,在dev/下创建了大量的节点,而不管这些节点相应的硬件设备是否存在。Linux2.6内核是开始引入可在用户空间执行的udev,允许用户不必再关心主,次设备号,在系统检测到设备的热拔插(hotplug)事件才动态的在/dev下建立和删除相应的设备节点文件。简言之,udev的主要功能是实时的创建和删除设备节点。如果希望像Windows系统一样,在设备插入时系统能够识别设备并自动挂载,可以通过在用户空间创建udev规则并编写脚本文件来实现。mdev实际上是嵌入式应用开发中udev的简化版,其作用与udev相同,即在系统启动时或发生热拔插事件时,自动产生驱动程序所需要的节点文件。

文件系统

第二:使能mdev功能

    要使用mdev需要内核支持sysfs文件系统,为了减少对flash的读写,还要支持tmpfs文件系统。对于动态更新来说,你也需要开启内核的热插拔功能。配置内核支持选项如下:

CONFIG_EMIBEDDED=y

CONFIG_SYSFS=y

CONFIG_TMPFS=y

在启动脚本如/etc/init.d/rcS中添加如下内容:

mount -t tmpfs tmpfs /dev  -o size=64k,mode=0755
mkdir /dev/pts /dev/shm
chmod 777 /dev/shm
mount -t devpts devpts /dev/pts
touch /dev/mdev.seq
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
mdev -s

mdev扫描/sys/class和/sys/block中所有的类设备目录,如果在目录中含有名为"dev"的文件,且文件中包含的是设备号,则mdev就利用这些信息为这个设备在/dev下创建设备节点文件。一般只在启动时才执行一次"mdev -s"。

第三:mdev配置方法

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

mdev有一个可以操作的配置文件:/etc /mdev .cfg

 <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>

特殊字符的意义如下:

 @:在创建设备节点后运行命令。

 $:在删除设备节点前运行命令。

*:在创建设备节点和删除设备节点前都运行命令。

Command :对应的shell—般位于letc/mdev目录

为了利用脚本(如Shell脚本automout.sh)实现u盘在嵌入式系统上的自动挂载,在mdev规则文件/sbin/automount.sh中加入以下一行匹配规则使mdev在找到匹配行时可以执行用户自定义的命令( shell脚本中的内容):

sd[a-z][0-9]* 0:0 0600 */sbin/automount.sh $MDEV

 

第四:自动挂载Shell脚本

shell是 Linux系统中一个重要的层次,它是用户与系统交互的界面,如我们使用Linux最常用的终端其实就是一种shell。shell最常见的使用方式是作为命令解释程序出现,以特定的前导符(如s)接收用户输入的命令并进行分析,然后创建子进程来实现命令所规定的功能。在子进程终止工作后,shell 则再次向用户发出命令输入提示符。此外,Shell作为一种高级的编程语言,具有变量、关键字、各种控制语句及自己的语法结构,通过编写shell脚本程序可以直接在Linux系统中解释执行而无须编译。通过mdev规则实现u盘自动挂载的 shell脚本automount主要内容如下:

#! /bin/sh
destdir=/mnt/sdcard/


umount_partition()
{
        if grep -qs "^/dev/$1 " /proc/mounts ; then
                umount -lf "${destdir}";
        fi
}


mount_partition()
{
        if [ ! -d "${destdir}" ]; then
            mkdir "${destdir}"
        fi
        if ! mount -t auto "/dev/$1" "${destdir}" -o nodev,noexec,nosuid; then
                # failed to mount
                exit 1
        fi
}


check_if_boot_dev()
{
                ret_val=`cat /proc/cmdline | grep "androidboot.bootdevice" |wc -l`
                if  [ $ret_val -eq 1 ]; then
                    boot_dev=`cat /proc/cmdline | awk '{ for ( n=1; n<=NF; n++ ) if($n ~ "androidboot.bootdevice") print $n }' | awk '{split($0,a, "=");print a[2]
                    real_sysfs_path=`realpath /sys/class/block/$1`
                    ret_val=`echo $real_sysfs_path | grep /sys/devices/ | grep $boot_dev | wc -l`
                fi
                echo $ret_val
}




create_symlink()
{
                real_sysfs_path=`realpath /sys/class/block/$1`
                partition_name=`cat $real_sysfs_path/uevent | awk '{ for ( n=1; n<=NF; n++ ) if($n ~ "PARTNAME") print $n }' | awk '{split($0,a, "=");print a[2]}'
                mkdir -p /dev/block/bootdevice/by-name/
                partition_name=/dev/block/bootdevice/by-name/$partition_name
                target_dev=/dev/$1
                ln -s $target_dev $partition_name
}


case "${ACTION}" in
add|"")
        result=`check_if_boot_dev $1`
        if [ $result -eq 1 ]; then
                 create_symlink $1 &
        else
                 umount_partition ${1}
                 mount_partition ${1}
        fi
        ;;
remove)
        umount_partition ${1}
        ;;
esac

总结:Linux系统中,mdev设备节点动态加载的过程,在实际开发中应用非常广发。

 

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分