Android SDCard Mount 流程分析

本篇大纲 
android 系统如何开机启动监听mount服务 
默认设备节点在Android 系统的哪个目录 
vold.fstab 配置文件的分析  
vold 里面启动页面main做了些什么 
android 系统如何开机启动监听mount服务 
android sdcard 热插拔监测和执行操作是由一个启动文件vold  所统领的,系统开机会读取初始化配置文件init.rc,该文件位于比如我的板子是:device/ti/omap3evm/init.rc,具体根据自己平台查找。里面有一个是默认启动vold 服务的代码,如下: 

service vold /system/bin/vold 
    socket vold stream 0660 root mount 
    ioprio be 2  
 如果要对该文件做出修改之类,要重新编一下boot.img 镜像文件,烧录进android 系统,之后可以在android的文件系统根目录找到init.rc文件。上述代码为启动vold 启动文件,也可以在init.rc 增加多一些我们想要的文件目录,比如增加一个可以存放多分区挂载的目录等,这个是后话。 

  

 默认设备节点在Android 系统的哪个目录 
 usbdisk 或者 sdcard 热插拔的时候,kernel 会发出命令执行mount或者unmount 操作,但这都是驱动级的。而mount 目录会在android 的文件系统目录下:/dev/block/vold 这个目录由vold 生成,用来存放所有的usbdisk 或者 sdcard 的设备节点。代码位于main里面最优先执行: 

  

mkdir("/dev/block/vold", 0755);  
  

 可以根据这个目录找到如下节点: 

sh-4.1# ls /dev/block/vold/ 
179:0  179:1  8:0    8:1    8:2    8:3    8:4  
节点的小介绍: 

0代表当前的整个设备,1代码当前设备的分区名称代号。 

所以你会发现,sdcard只有一个分区它却生成了两个如:179:0 179:1 

而usbdisk 有四个分区,它会生成五个设备节点: 8:0    8:1    8:2    8:3    8:4  就是这个原因。 

  

  

 vold.fstab 配置文件的分析 
vold 里面会通过指定文件来读取预先配置好的sdcard或者多分区配置文件,该文件位于 

/system/core/rootdir/etc/vold.fstab 
如以下的配置文件为: 

dev_mount sdcard /mnt/sdcard auto /devices/platform/goldfish_mmc.0 /devices/platform/msm_sdcc.2/mmc_host/mmc1 
  

 dev_mount 代表挂载格式 

 sdcard 代表挂载的标签 

/mnt/sdcard 代表挂载点 

 auto 为自定义选项可以为任何,但必须在main 里面自己判断比如这里的意思为自动挂载 

后面两个目录为设备路径,第一个如果被占用会选择第二个 

  

配置文件可以根据自己的需要编写,并不是固定的,但最好遵循google vold 启动文件代码的格式编写,要不然会给我们修改代码或者增加多分区功能带来不小的麻烦,如以下我自己编写的多分区挂载支持vold.fstab 配置文件: 

  

dev_mount sdcard external /mnt/sdcard auto /devices/platform/mmci-omap-hs.0/mmc_host/mmc0 /devices/platform/mmci-omap-hs.0/mmc_host/mmc1 
dev_mount usb1 external /mnt/usbdisk/usb1-disk%d all /devices/platform/ehci-omap.0/usb1/1-2/1-2.1/ 
dev_mount usb2 external /mnt/usbdisk/usb2-disk%d all /devices/platform/ehci-omap.0/usb1/1-2/1-2.2/ 
dev_mount usb3 external /mnt/usbdisk/usb3-disk%d all /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/ 
 该文件修改后经系统编译会在android 系统目录里/system/etc/vold.fstab找到。 

 /devices/platform/ehci-omap.0/usb1/1-2/1-2.1/  代表要挂载的USB口。 

vold.fstab 只是一个单纯的配置文件,具体的读取和取数据还 是要靠main里面的process_config函数。看代码,里面正有一段用来读取配置文件: 

  if (!(fp = fopen("/etc/vold.fstab", "r"))) { 
        return -1; 
    } 
在这个函数里面会根据读取到的数据存放起来,然后满足条件时执行操作。比如代码里面的: 

  


if (!strcmp(type, "dev_mount")) { 
            DirectVolume *dv = NULL; 
            char *part; 

            if (!(part = strtok_r(NULL, delim, &save_ptr))) { 
                SLOGE("Error parsing partition"); 
                goto out_syntax; 
            } 
            if (strcmp(part, "auto") && atoi(part) == 0) { 
                SLOGE("Partition must either be ’auto’ or 1 based index instead of ’%s’", part); 
                goto out_syntax; 
            } 

            if (!strcmp(part, "auto")) { 
                dv = new DirectVolume(vm, label, mount_point, -1); 
            } else { 
                dv = new DirectVolume(vm, label, mount_point, atoi(part)); 
            } 

            while ((sysfs_path = strtok_r(NULL, delim, &save_ptr))) { 
                if (*sysfs_path != ’/’) { 
                    /* If the first character is not a ’/’, it must be flags */ 
                    break; 
                } 
                if (dv->addPath(sysfs_path)) { 
                    SLOGE("Failed to add devpath %s to volume %s", sysfs_path, 
                         label); 
                    goto out_fail; 
                } 
            } 

            /* If sysfs_path is non-null at this point, then it contains 
             * the optional flags for this volume 
             */ 
            if (sysfs_path) 
                flags = parse_mount_flags(sysfs_path); 
            else 
                flags = 0; 
            dv->setFlags(flags); 

            vm->addVolume(dv); 
        } 

  

DirectVolume后面会讲到,执行mount 和unmount 都是它在做。 

另外,有时后读取配置文件会有问题,这是因为它读取是通过指标下标递增的方式在读,如果有问题可以跟踪打印一下配置文件,看哪里需要修改。 

你可能感兴趣的:(Android SDCard Mount 流程分析)