vold分析

转:来源于网络,忘记地方了,有知道地方的,请提醒下我

1. Vold 简介

1.1 udev的由来
udev 是 Linux2.6 内核里的一个功能,它替代了原来的 devfs,成为当前 Linux 预设的设备管理工具。udev 以守护进程的形式运行,通过侦听内核发出来的 uevent 来管理 /dev目录下的设备文件。不像之前的设备管理工具,udev 在用户空间 (user space) 运行,而不在内核空间 (kernel space) 运行。
devfs 存在的主要的问题是它处理设备检测、创建和命名的方式,其中设备节点的命名可能是最严重的问题。一般可接受的方式是,如果设备名 是可配置的,那么设备命名策略应该由系统管理员决定,而不是由某些开发者强制规定。devfs 文件系统还存在竞争条件(race conditions) 的问题,这是它天生的设计缺陷,不对内核做彻底的修改就无法修正这个问题。所以udef应运而生。
udev能够实现所有devfs实现的功能。具有以下优点:
1) dynamic replacement for /dev。作为devfs的替代者,传统的devfs不能动态分配major和minor的值,而major和minor非常有限,很快就会用完了。 udev能够像DHCP动态分配IP地址一样去动态分配major和minor。
2) device naming。提供设备命名持久化的机制。传统设备命名方式不具直观性,像/dev/hda1这样的名字肯定没有boot_disk这样的名字直观。udev能够像DNS解析域名一样去给设备指定一个有意义的名称。
3) API to access info about current system devices 。提供了一组易用的API去操作sysfs,避免重复实现同样的代码,
但udev运行在用户模式中,而devfs运行在内核中。udev只支持linux-2.6内核,因为udev严重依赖于sysfs文件系统提供的信息,而sysfs文件系统只在linux-2.6内核中才有。
1.2 Vold的产生
Vold的全称是Volume Daemon。在android中,取代udev的是vold,我们这里不去过多的讨论为什么android不继续使用udev,但要知道vold的机制和udev是一样的,理解了udev,也就理解了vold。android一出生就没有尊守传统linux的许多标准,当然也不能指望udev能很好的服务于android。android小区的选择是别起炉灶,为android定做一套udev,这就是vold了。无论是udev还是vold,都是基于sysfs的,sysfs为内核与用户层的通讯提供了一种全新的方式,并将这种方式加以规范。kernel层能检测到有新的设备接入,并能为之加载相应的驱动,但如何通知用户层呢?这就是sysfs的工作,内核中的sysfs机制要求当有新的驱动加载时给用户层发送相应的event.但这些event只尽告知的义务,具体怎么处理,这就是vold的事了。对于用户层而言,我们无需关心sysfs的
细节,只要知道sysfs 能向用户层提供什么就行了。首先,我们要知道如何接收来自内核的
event.Netlink socket 大家应该不会陌生吧,socket 这套东西不仅能用于网络间的通讯,
也用能用于进程间的通讯,像这种内核态与用户沟通的活,自然也少不了它。关于这个部分,
我们将在Vold 通信仲介绍。关于Vold 的主要作用,如下图所示:
NativeDaemonConnector
MountService Java空间
C++空间
Volume Daemon
Linux Kernel
sysfs
uevent Function call
庫函數
onEvent Command
command onEvent
Volume Daemon 简介
Android 的volume 服务主要是用来管理usb/sd 卡等外部存储设备。平台可以对外部存
储设备进行操作和轮询状态,当外部存储设备状态发生变化时,volume 服务也会实时报
告平台。
2. Vold 功能分析
2.1. Vold 启动
Volume Daemon 实在android init 进程中启动的(关于android 启动有其他同事介绍)。在init
进程中将解析init.rc 文件。在该文件中有启动Vold 的配置。见下图:
在这里将启动Vold Daemon,并且创建一个socket。改socket 主要是为了与framework 层通
信。
2.2 Vold 内部架构
NetLinkManager
CommandListener
Volume
DirectVolume
AutoVolume
SocketListener
VolumeManager
Vold(Volume Daemon)的内部框架如上图所示。Vold 处理过程大致分为三步:创建连
结、引导和事件处理。下面将结合上图对vold 工作流程进行详细分析。
2.2.1. 创建连结
在vold作为一个守护进程,一方面接受驱动的信息,并把信息传给应用层;另一方面接受上层的命令并完成相应。所以这里的连结一共有两条:
1) vold socket: 负责vold与framework层的信息传递;
2) 接受sysfs uevent的socket: 负责接受kernel的信息;
Vold socket是在init进程启动Volume Daemon时创建的,这是一个用于和framework层通信的socket,在android系统中叫做Localsocket,framework曾通过JNI机制调用C/C++空间函数,具体过程如下图:
在framework层的NativeDaemonConnector类中调用下面代码
其中mSocket值为“vold”表示要获得socket的名字,该socket上上所述,是在vold被init的时候创建的,并且保存为全局变量。在socket.connect()中调用LocalSocketImpl.create_native()方法。改方法通过一个函数对应表,调用相应的C/C++函数。该表如下所示:
关于JNI由其他同事详细介绍,这里不展开,只要知道用Java JNI机制调用的是C/C++函数。这个framework层和Vold中分别持有同一个socket实例,这样上层通信就建立起来了。
而与内核通信的socket是在vold main函数中创建的。在main函数中,vold将创建两个单例,VolumeManager和NetLinkManager,与内核通信的socket就在其中创建。这样Volume Daemon与Kernel、framework层的通信框架就建立了。关于Volume Daemon的内部通行将在下一节中详细解释。
2.2.2. 引导
这里主要是在vold启动时,对现有外设存储设备的处理。首先,要载入并解析vold.fstab。vold.fstab如下图所示:
图中红色部分标记可配置的部分。我们在Porting的时候可以设置,系统可以挂载USB Storage 端口的数目。配置格式为:
dev_mount命令 标签 挂载点 子分区 设备在sysfs文件系统下的路径(可多个)
以Android X86 froyo中的vold.fstab为例,它仅仅为系统配置了一个外接USB Storage埠,如上图红色部分所示,其意义对应下表。
dev_mount命令:
dev_mount

你可能感兴趣的:(android,vold分析)