详解Linux实现U盘自动挂载(图文教程)

1.当我们每次插入u盘后,都会自动创键U盘的设备节点/dev/sda%d

这是因为里面调用了device_create()实现的, busybox的mdev机制就会根据主次设备号等信息,在/dev下创建设备节点,如下图所示:

而想使用上面的sda1设备节点,读写数据时,还需要使用mount /dev/sda1 /mnt,来挂载u盘才行,会显得非常麻烦,如下图所示:

2.其实,可以在/etc/mdev.conf文件里加入一行语句就能实现自动装载u盘,也可以在里面干其它与设备节点相关的事

2.1而/etc/mdev.conf又是什么?

它是属于mdev的一个配置文件,而mdev之前就讲过了,它主要的功能是管理/dev目录底下的设备节点

当系统中有自动注册设备节点的时候,mdev就会调用/etc/mdev.conf一次, 该文件可以实现与设备节点相关的事,比如自动装载usb,打印创建的设备节点信息等

3.我们首先来分析device_create(),是如何来调用到/etc/mdev.conf的,后面再讲如何使用mdev.conf(也可以直接跳过,直接看下面第4小节,如何使用)

(PS: 之前创建字符设备节点用的class_device_create(),其实是和device_create功能差不多)

3.1 device_create()最终调用了:device_create()->device_register()->device_add():

device_create()-
>device_register()
->device_add()
函数如下所示:
int class_device_add(struct class_device *class_dev)
{
 ... ... kobject_uevent(&class_dev->kobj, KOBJ_ADD);
 // KOBJ_ADD是一个枚举值
//调用了kobject_uevent_env(kobj, action, NULL);
// action=KOBJ_ADD
}

3.2 device_create()->device_register()->device_add()->kobject_uevent_env()函数如下所示:

int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,char *envp_ext[])
{
  char **envp;
  char *buffer;
  char *scratch;
  int i = 0;
  ... ...
  /* 通过KOBJ_ADD获取字符串"add",所以action_string="add" */
  action_string = action_to_string(action);    // action=KOBJ_ADD

  /* environment index */
  envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);  //分配一个环境变量索引值
  /* environment values */
    buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);  //分配一个环境变量缓冲值
/* event environemnt for helper process only */
/*设置环境变量*/
  envp[i++] = "HOME=/";
  envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
  scratch = buffer;
  envp [i++] = scratch;
  scratch += sprintf(scratch, "ACTION=%s", action_string) + 1; //"ACTION= add"
  envp [i++] = scratch;
  scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
  envp [i++] = scratch;
  scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
  ... ...
  /*调用应用程序,比如mdev*/
  if (uevent_helper[0]) {
   char *argv [3];
    argv [0] = uevent_helper;  // uevent_helper[]= "/sbin/hotplug";
    argv [1] = (char *)subsystem;
    argv [2] = NULL;
    call_usermodehelper (argv[0], argv, envp, 0);  //调用应用程序,根据传入的环境变量参数来创建设备节点
  }
}

从上面的代码和注释来看,最终通过*argv[], *envp[]两个字符串数组里面存的环境变量参数来创建设备节点的

3.2接下来便在kobject_uevent_env()函数里添加打印信息, 然后重新烧内核:

3.3然后我们以注册一个按键驱动为例

输入 insmod key.ko,打印了以下语句:

class_device: argv[0]=/sbin/mdev        //调用mdev
class_device: argv[1]=sixth_dev      //类名
class_device: envp[0]=HOME=/
class_device: envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
class_device: envp[2]=ACTION=add          //add:表示添加设备节点,  若=remove:表示卸载设备节点
class_device: envp[3]=DEVPATH=/class/sixth_dev/buttons   //设备的路径
class_device: envp[4]=SUBSYSTEM=sixth_dev       //类名
class_device: envp[5]=SEQNUM=745
class_device: envp[6]=MAJOR=252       //主设备号
class_device: envp[7]=MINOR=0

3.4最终这些参数根据/sbin/mdev就进入了busybox的mdev.c的mdev_main()函数里:

int mdev_main(int argc, char **argv)
{
... ...
action = getenv("ACTION");     //获取传进来的执行参数,它等于“add”,则表示创建设备节点
env_path = getenv("DEVPATH");     //获取设备的路径“/class/sixth_dev/buttons”
sprintf(temp, "/sys%s", env_path); //指定temp (真正设备路径)为“/sys/class/sixth_dev/buttons”
if (!strcmp(action, "remove"))   //卸载设备节点
     make_device(temp, 1);
else if (!strcmp(action, "add")) {  //创建设备节点
      make_device(temp, 0);
 ... ...
}

3.5最终调用mdev_main ()->make_device()函数来创建/卸载设备节点,该函数如下所示:

static void make_device(char *path, int delete) //delete=0:创建, delete=1:卸载
{
  /*判断创建的设备节点是否是有效的设备*/
  if (!delete) {
    strcat(path, "/dev");
    len = open_read_close(path, temp + 1, 64);
    *temp++ = 0;
    if (len < 1) return;
  }
device_name = bb_basename(path); //通过设备路径,来获取要创建/卸载的设备节点名称
      //例: path =“/sys /class/sixth_dev/buttons”,那么device_name=“buttons”
type = path[5]=='c' ? S_IFCHR : S_IFBLK;  //判断如果是在/sys/class/目录下,那么就是字符设备
            //因为块设备,是存在/sys/block/目录下的
/* 如果配置了支持mdev.conf选项,那么就解析里边内容并执行 */
 if (ENABLE_FEATURE_MDEV_CONF) {
  /* mmap the config file */
fd = open("/etc/mdev.conf", O_RDONLY);  //调用/etc/mdev.conf配置文件
       ... ...   //开始操作 mdev.conf配置文件
}
  if (!delete) {     //如果是创建设备节点
    if (sscanf(temp, "%d:%d", &major, &minor) != 2) return; //获取主次设备号
        /*调用mknod ()创建字符设备节点*/
if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
      bb_perror_msg_and_die("mknod %s", device_name);
    if (major == root_major && minor == root_minor)
      symlink(device_name, "root");
    /*若配置了支持mdev.conf选项,则调用chown命令来改变属主,默认uid和gid=0 */
    if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid);
}
  if (delete) unlink(device_name);   //如果是卸载设备节点
}

从上面的代码和注释分析到,要使用mdev.conf配置文件,还需要配置busybox的menuconfig, 使mdev支持mdev.conf选项才行

如下图,进入busybox目录,然后输入make menuconfig,发现我们已经配置过了该选项了

4.接下来,便来看看如何使用mdev.conf, 参考busybox-1.7.0/docs/mdev.txt文档

使用方法如下所示:

the format:

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

The special characters have the meaning:

@ Run after creating the device.

$ Run before removing the device.

* Run both after creating and before removing the device.

大概就是:

配置文件格式:

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

各个参数代表的含义如下:

deviceregex:

正则表达式,来表达哪一个设备,正则表达式讲解链接:https://deerchao.net/tutorials/regex/regex.htm

uid:

owner (uid,gid:注册设备节点时,就会被chown命令调用,来改变设备的属主,默认都填0即可)

gid:

组ID

octalpermissions:

以八进制表示的权限值,会被chmod命令调用,来更改设备的访问权限,默认填660即可

@ :创建设备节点之后执行命令

$ : 删除设备节点之前执行命令

* :创建设备节点之后和删除设备节点之前执行命令

command :要执行的命令

5.接下来便来使用mdev.conf,实现u盘自动装载

vi /etc/mdev.conf

添加以下一句:

sda[1-9]+ 0:0 660 * if [ $ACTION = "add" ]; then mount /dev/$MDEV /mnt; else umount /mnt; fi

[1-9]:匹配1~9的数字,

+ : 重复匹配一次或更多次

$ACTION=="add" :表示注册设备节点,否则就是注销设备节点

/dev/$MDEV    :表示要创建/注销的那个设备节点

所以当我们插上u盘,自动创建了/dev/sda1时,mdev便会进入/etc/mdev.conf配置文件,然后执行mount /dev/ 命令,即可自动装载U盘,如下图所示:

输入ls /dev/sda1 -l,可以看到都是通过mdev.conf里配置信息来创建的设备节点,如下图所示:

而取出u盘时,同样自动umount /mnt来卸载。

总结

以上所述是小编给大家介绍的Linux实现U盘自动挂载,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 阿里云云服务器Linux系统挂载数据盘图文教程

    适用系统:Linux(Redhat , CentOS,Debian,Ubuntu) *  Linux的云服务器数据盘未做分区和格式化,可以根据以下步骤进行分区以及格式化操作. 下面的操作将会把数据盘划分为一个分区来使用. 1.查看数据盘 在没有分区和格式化数据盘之前,使用 "df –h"命令,是无法看到数据盘的,可以使用"fdisk -l"命令查看.如下图: 友情提示:若您执行fdisk -l命令,发现没有 /dev/xvdb 标明您的云服务无数据盘,那么您无需进行

  • linux mount挂载共享目录详解

    挂载windows共享目录或FTP: 方式一:包含密码 复制代码 代码如下: sudo mount //192.168.10.22/FTPServer /windows -o username=user,password=abcdefg -t cifs 方式二:密码单独输入 sudo mount //192.168.10.22/FTPServer /windows -o username=user -t cifs password:abcdefg 卸载: umount /FTPServer 挂载

  • 实现批量linux格式化硬盘和挂载硬盘脚本分享

    复制代码 代码如下: #!/bin/bash  PATH=/bin:/sbin:/usr/bin:/usr/sbinexport PATH  i=1while [ $i -lt 13 ]                  #硬盘数量,除系统盘之外是12块doj=`echo $i|awk '{printf "%c",97+$i}'` #系统盘是sda,如果是其它的需要修改脚本 parted /dev/sd$j <<FORMAT               mklabel gp

  • linux命令详解之挂载光驱的方法

    linux的硬件设备在/dev目录下,光驱也是其中./dev/cdrom表示光驱,挂载光驱的方法如下(以root身份): 复制代码 代码如下: mkdir /mnt/cdrommount  -t auto  -o ro  /dev/cdrom    /mnt/cdrom  #不加参数也能自动挂上. 以下是操作的屏幕复制内容: 复制代码 代码如下: linux@cdyemail:/$ ls /mnt   #查看mnt下面有没有cdrom目录 ,这个是随意的目录.cdrom  iso  usb  w

  • LINUX磁盘分区、格式化、挂载、卸载详细过程

    1.一切皆文件 Linux系统有一个理念:"一切皆文件",所以计算机的硬件在linux中也是以"文件"的形式存在于/dev目录中. 图为CentOS 6.5系统中/dev目录的部分内容.不同的计算机显示的内容大同小异. 比如,光驱对应的文件是/dev/cdrom,CPU对应的文件是/dev/cpu.而硬盘对应的是/dev/sd*.第一块硬盘是/dev/sda,第二块磁盘是/dev/sdb. 但是一个磁盘通常又被分成多个分区,所以在磁盘文件的后面加上分区的序号来对应这

  • linux中mount/umount命令的基本用法及开机自动挂载方法

    本文介绍了linux中mount/umount命令的基本用法及开机自动挂载,具体方法如下: mount命令格式如下: 格式:mount [-参数] [设备名称] [挂载点] 其中常用的参数有: -a 安装在/etc/fstab文件中类出的所有文件系统. -f 伪装mount,作出检查设备和目录的样子,但并不真正挂载文件系统. -n 不把安装记录在/etc/mtab 文件中. -r 讲文件系统安装为只读. -v 详细显示安装信息. -w 将文件系统安装为可写,为命令默认情况. -t <文件系统类型

  • linux系统下如何挂载NTFS移动硬盘

    前言 数据迁移是我们经常会遇到的,有时候做大数据量迁移时,为了快速迁移大数据,有可能在Linux服务器上临时挂载NTFS格式的移动硬盘, 一般情况下,Linux是识别不了NTFS格式移动硬盘的(需要重编译Linux核心才能,加挂NTFS分区), 这时候为了能让Linux服务器能够识别NTFS的移动硬盘,就必须安装ntfs-3g(Third Generation Read/Write NTFS Driver)的包. 一.NTFS-3G介绍 NTFS-3G是一个开源项目, NTFS-3G是为Linu

  • 详解Linux实现U盘自动挂载(图文教程)

    1.当我们每次插入u盘后,都会自动创键U盘的设备节点/dev/sda%d 这是因为里面调用了device_create()实现的, busybox的mdev机制就会根据主次设备号等信息,在/dev下创建设备节点,如下图所示: 而想使用上面的sda1设备节点,读写数据时,还需要使用mount /dev/sda1 /mnt,来挂载u盘才行,会显得非常麻烦,如下图所示: 2.其实,可以在/etc/mdev.conf文件里加入一行语句就能实现自动装载u盘,也可以在里面干其它与设备节点相关的事 2.1而/

  • 详解Linux(centos7)下安装OpenSSL安装图文方法

    OpenSSL是一个开源的ssl技术,由于我需要使用php相关功能,需要获取https的文件所以必须安装这个东西了,下面我整理了两种关于OpenSSL安装配置方法. 安装环境:  操作系统:CentOs7安静 OpenSSL Version:openssl-1.0.2j.tar.gz 目前版本最新的SSL地址为http://www.openssl.org/source/openssl-1.0.2j.tar.gz 1.将下载的压缩包放在根目录, 2.在文件夹下解压缩,命令:tar -xzf ope

  • 详解Virtual Box配置CentOS7网络(图文教程)

    之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network Address Translation) Bridged Adapter 桥接模式 Internal 内部网络模式 Host-only Adapter 主机模式 具体的区别网上的资料很多,就不再描述了,下面是一个最直接有效的配置,配置CentOS7虚拟机里面能上外网,而主机与CentOS7虚拟机也

  • 详解 Linux 常用目录的作用

     详解 Linux 常用目录的作用 一 常用一级目录 注意: 1.根目录下的bin和sbin,usr目录下的bin和sbin,这四个目录都是用来保存系统命令的. 2.bin目录下的命令时任何用户都能执行,sbin目录下的命令只有超级用户才能执行. 3.media用来挂载光盘,misc挂载磁带机,mnt挂载U盘.它们都是空目录. 4.proc和sys目录不能直接操作,这两个目录保存的是内存挂载点. 5.可以在家目录root或home,以及tmp目录下随便放内容. 二 实战 [root@localh

  • 详解Linux 主机网络接入配置

    详解Linux 主机网络接入配置 前言: 网络配置是我们在安装好操作系统之后,需要解决的第一步.现时代没有接入网络的主机已然等同于一堆废铁.在网络配置的过程中,通常我们需要配置本机IP地址,缺省网关,DNS,主机名等等.本文主要描述在Linux环境下,主要以传统命令行方式讲解如何将主机接入网络.对于网路配置的新命令如ip,nmcli等等在以后的文章中描述. 一.网络配置概述 主机接入互联网前提:遵循TCP/IP协议栈 配置主机接入TCP/IP网络需要配置的内容:   IP/Netmask   路

  • Android2.3实现SD卡与U盘自动挂载的方法

    本文实例讲述了Android2.3实现SD卡与U盘自动挂载的方法.分享给大家供大家参考,具体如下: 在 s3c6410平台上移植android2.3 过程中SD卡总是不能自动挂载. 查阅相关资料,知道在android2.3中是 vold程序负责检查内核的 sysfs 文件系统,发现有SD卡插入后,自动挂载. 在文件系统目录 /system/etc/  下有一个vold.fstab 文件,该文件是系统与用户硬件平台的交互接口,用户根据自己的平台来配置这个文件,里面内容比较简单,只需要你指定sys下

  • 详解Linux系统配置nginx的负载均衡

    详解Linux系统配置nginx的负载均衡 负载均衡的几种方式: 1.轮询:默认按照时间顺序对所有服务器一个一个的访问,如果有服务器宕机,会自动剔除: 2.weight:服务器的方位几率和weight成正比,这个可以在服务器配置不均的时候进行配置: 3.ip_hash:对每个请求的ip进行hash计算,并按照一定的规则分配对应的服务器(可解决session共享): 4.fair:按照每台服务器的响应时间(rt)来分配请求,rt知道优先分配: 5.url_hash:按照访问url的hash值来分配

  • 详解Linux中查看jdk安装目录、Linux卸载jdk、rpm命令、rm命令参数

    一.查看jdk安装目录 [root@node001 ~]# whereis java java: /usr/bin/java /usr/local/java #java执行路径 [root@node001 ~]# which java /usr/bin/java #查看JDK安装路径 [root@node001 ~]# echo $JAVA_HOME /usr/local/java/jdk1.7.0_80 [root@node001 ~]# echo $PATH /usr/local/sbin:

  • 详解linux 定时任务 crontabs 安装及使用方法

    安装 crontab yum install crontabs centos7 自带了我没有手动去装 启动/关闭 service crond start // 启动服务service crond stop // 关闭服务service crond restart // 重启服务service crond reload // 重新载入配置 查看 crontab 服务是否已设置为开机启动 systemctl list-unit-files | grep enable | grep crond 将 c

  • 详解Linux中zip压缩和unzip解压缩命令及使用详解

    下面给大家介绍下Linux中zip压缩和unzip解压缩命令详解 1.把/home目录下面的mydata目录压缩为mydata.zip zip -r mydata.zip mydata #压缩mydata目录 2.把/home目录下面的mydata.zip解压到mydatabak目录里面 unzip mydata.zip -d mydatabak 3.把/home目录下面的abc文件夹和123.txt压缩成为abc123.zip zip -r abc123.zip abc 123.txt 4.把

随机推荐