Linux自动挂载/卸载U盘

版权声明:本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,欢迎转载,但转载请注明来自hceng blog(www.hceng.cn),并保持转载后文章内容的完整。本人保留所有版权相关权利。 https://blog.csdn.net/hceng_linux/article/details/89838911

CSDN仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
本博文对应地址: https://hceng.cn/2017/04/22/Linux自动挂载卸载U盘/

记录在mdev机制下不能自动卸载U盘的解决方法。

加载USB驱动有两种方式:
**  一是将模块编译到内核,再把新内核下载到开发板。
  二是将驱动作为模块,内核启动后再加载驱动模块。**

  • 在主机中编译模块,在Linux中的/work/hceng/linux-3.4.2目录下执行:
    {% codeblock lang:shell %}
    $ make moudles
    {% endcodeblock %}
  • 复制主机生成的drivers/usb/storage/usb-storage.ko到开发板中:
    {% codeblock lang:shell %}
    cp drivers/usb/storage/usb-storage.ko /work/hceng/nfs_rootfs
    {% endcodeblock %}
  • 在开发板中,加载USB驱动模块:
    {% codeblock lang:shell %}
    $ insmod usb-storage.ko
    {% endcodeblock %}
  • 然后在开发板插上U盘后,再手动挂载U盘即可访问数据:
    {% codeblock lang:shell %}
    $ mount /dev/sda1 /mnt
    {% endcodeblock %}

这里存在两个问题,一是需要手动加载usb-storage.ko,二是需要手动挂载U盘。

  • 第一个问题通过将模块加载命令放在启动脚本里实现开机自动加载,/etc/init.d/rcS,加入如下命令:
    {% codeblock lang:shell %}
    insmod usb-storage.ko
    {% endcodeblock %}
  • 第二个问题利用mdev机制进行自动挂载U盘,首先修改/etc/medv.conf,将下面代码加入行底:
    {% codeblock lang:shell %}
    sd[a-z][0-9] 0:0 666 @/etc/mdev/udisk_insert
    sd[a-z] 0:0 666 $/etc/mdev/udisk_remove
    {% endcodeblock %}
      在/bin/hotplug.sh中把 “case $MDEV in”修改成如下:
    {% codeblock lang:shell %}
    case $MDEV in
    sd[a-z][0-9])
    DEVNAME=udisk
    MOUNTPOINT=/udisk
    ;;
    sda1)
    DEVNAME=udisk
    MOUNTPOINT=/udisk
    ;;
    {% endcodeblock %}

完成上面的设置后,U盘确实能够自动挂载,但拔U盘却不能自动卸载,这样会导致下次插入U盘相应的节点会自动增加,且访问原来的节点报错。

查阅相关资料并无解决方案,多次实验后,发现插上U盘后会自动在/sys/bus/usb/devices/1-1:1.0下生成U盘的信息文件,利用这一点进行检测U盘,在无奈的情况下写了个程序解决这个问题,代码如下:
{% codeblock lang:c [usb.c] https://github.com/hceng/learn/tree/master/auto_usb%}
/检查是否有U盘插上,没有则卸载一次/media/sda1,保证下次自动挂载U盘正常/
/定时器相关/
static int count = 0;
static struct itimerval oldtv;
static unsigned char usb_umount_ok = 0;
void set_timer()
{
struct itimerval itv;
itv.it_interval.tv_sec = 1;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, &oldtv);
}

/查看/sys/bus/usb/devices/目录下是否有1-1,有则表示有U盘/
static unsigned int judge_usb(void)
{
FILE *fd;
fd = fopen("/sys/bus/usb/devices/1-1/version",“r”);

if(fd == NULL) 
    return 0;  
else fclose(fd);
    usb_umount_ok = 0;
    return 1;

}

/检查usb是否拔出,从而确定是否卸载/
static void colse_usb(void)
{
if(!judge_usb() && usb_umount_ok==0)
{
system(“cd /;umount /media/sda1;rm -r /media/sd*;echo umount usb ok!”);
usb_umount_ok = 1;
}

}

void signal_handler(int m)
{
colse_usb();
}

int main(void)
{
signal(SIGALRM, signal_handler);
set_timer();
while(1);

return 0;

}

{% endcodeblock %}
  编译后,运行测试,最后再放在上述启动脚本里:
{% codeblock lang:shell %}
arm-linux-gcc -o usb usb.c
./app/usb&
{% endcodeblock %}

搞定。

猜你喜欢

转载自blog.csdn.net/hceng_linux/article/details/89838911