VOLD

loading 分享 2026-10-31 下载文档

VOLD Overview

VOLD的全称是Volume Daemon,取代了原来Linux系统中的udev。它主要是用来处理Android系统中的热插拔存储设备,比如MMC,USB等。作为一个守护进程,它一方面接收内核传递上来的驱动的信息,另一方面接收上层下达的命令并完成相应处理。总的来说,可以将VOLD的工作流程分为三个部分,监听,引导和事件处理。它的工作机制如下图所示。

VOLD通过NetlinkManager类中的onEvent方法来接收来自内核的事件信息。该方法最终会通过VolumeManager调用DirectVolume下的handleBlockEvent来处理Add,Remove以及Change等不同的事件。它会根据具体事件,向MountService服务发送VolumeDiskInserted或者VolumeDiskRemove等message。MountService通过一个nativeDaemon Connector获得这些message,再发送doCommand(“mount”)或者doCommand(“unmount”)命令给VOLD层。

另一方面,VOLD又通过commandListener来监听FrameWork层MountService发出的命令。命令会被VolumeManager处理并最终调用Volume中的方法实现mount或者unmount的动作。

至此,VOLD的监听与事件处理的大致流程就介绍完了。由上可知,VOLD实现一个mount或者unmount的动作是和MountService紧密的结合在一起的。然而根据

Android init流程,VOLD与MountService不可能同时完成初始化。而且内核发出的驱动信息也可能早于VOLD初始化的完成。为此,VOLD当然还需要实现一个引导的功能,

以保证相关存储设备能加载成功。 VOLD Work Flow

VOLD的source coed在Android/system/vold目录下。系统进行init时会从main.cpp的main函数开始执行。它一开始就会声明三个指针,分别是

*vm(VolumeManager), *cl(CommandListener)以及*nm(NetlinkManager)。它们指向各自的实例化对象。vm用来管理所有的volume对象;cl用来监听framework下发的消息,并分析命令以便相应处理;nm用来监听内核传递上来的驱动事件。然后VOLD会在/dev/block下建立一个名为vold的目录。之后所有添加上来的设备都会在该目录下建立一个节点以方便管理。

接下来一个很重要的步骤是调用process_config函数以完成上文提到的引导功能。它会来解析target device etc目录下vold.fstab配置文件的内容,获得预先设置的volume信息,然后通过DirectVolume将它们添加到刚刚初始化的vm实例的容器中。

vold.fstab文件内容如下:

Format: dev_mount

#wmt sd

dev_mount sdcard /storage/sdcard1 auto /devices/platform/sdmmc.0

#wmt nand

dev_mount yaffs2 /data auto /devices/virtual/mtd/mtd17/mtdblock17

#wmt usb

dev_mount udisk /storage/udisk auto /devices/pci0000:00/0000:00

解析成功之后,VOLD会调用coldboot函数对所有/sys/block/下的设备发一个add命令,模拟实现一次热插入的动作。因为此时netlinkmanager已经实例化,它就可以监听到add命令带来的uevent事件。

此时,NetlinkHandler的onEvent会响应这个uevent事件。该函数会调用vm下的handleBlockEvent进行处理。Vm的handleBLockEvent函数会遍历容器中所有的directvolume对象。根据保存在directvolume的sysfs_path名称和此时uevent传递上来的dev路径来判断是否需要处理。如果需要处理,则会更改volume的state并发送一个VolumeDiskInserted的消息给上层。

需要说明的是,如果是普通的热插拔,发送VolumeDiskInserted消息时

MountService服务业已启动。它会根据nativeDaemon Connector获得这些消息,并对VOLD发出mount的命令。然后VOLD的CommandListener会监听到这个命令并通过VolumeManger调用volume的mountVol函数完成具体的功能。

但是引导过程中,MountService并没有初始化。所以这个VolumeDiskInserted的消息自然无法得到相应。而且MountService在初始化后,也无法知道VOLD刚刚是否向其发送过消息。为解决这一问题,在MountService初始化nativeDaemon Connector的时候,会读取一个描述有关存储设备的storage list。该storage list根据vold.fstab内容而来,大致如下:

xmlns:android=\

android:storageDescription=\ android:primary=\ android:emulated=\

android:mtpReserve=\

android:storageDescription=\ android:removable=\

android:maxFileSize=\

android:storageDescription=\ android:removable=\

android:maxFileSize=\

android:storageDescription=\ android:removable=\

android:maxFileSize=\

程序会解析这个xml文件,并将每一个item的内容存储在内存中。然后它会通过MountService向VOLD发送一个volume list的命令。VOLD会根据volume list这个命令将vm中所有的directvolume项返回给MountService。之后再根据directvolume项保存的mount_point和MountService中的mountPoint做对比,将符合的mountPoint添加到MountService中。MountService初始化的最后,会调用一个handleSystemReady的函数。这个函数会将存储在MountService中的mountPoint作为路径名称发送给VOLD用来完成挂载。

CommandListener的监听函数会调用runCommand函数进行响应。该函数会根据MountService传递来的不同命令实现具体操作。比如此时,上层传递下来的就是volume mount mountPoint的command。它就会调用VolumeManger中的mountVolume(path)完成具体操作。

mountVolume会根据传递进来的path名称在vm容器中寻找init时候添加进来的directvolume项,然后再调用该项的mountVol函数来完成实际的mount过程。

mountVol在DirectVolume中实现。它会根据directvolume存储的信息,调用mount命令完成具体的操作。

mount(fsPath, mountPoint, \


VOLD.doc 将本文的Word文档下载到电脑
搜索更多关于: VOLD 的文档
相关推荐
相关阅读