android vold学习总结.doc_第1页
android vold学习总结.doc_第2页
android vold学习总结.doc_第3页
android vold学习总结.doc_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

vold学习总结Vold(volume daemon):源码路径android/system/vold,部分引用代码位于android/system/core/libsysutils/src,android/system/core/include/sysutils/下。它用于管理和控制android平台的外部设备,包括u盘、sd卡等的插入,拔出和格式化等。Vold为守护进程,由init进程启动,Vold的框架如下图所示:Linux kernel与vold进程通过netlink机制进行跨进程通信,vold中的NetlinkManager接收来自linux kernel上报的uevent事件,然后将其转换成一个NetlinkEvent类型,并调用VolumeManager类的相应方法进行处理,VolumeManager会将处理的结果发送给MountService,VolumeManager与MountService之间通过CommandListener机制进行通信,本质是通过socket进行跨进程通信,MountService运行在SystemServer进程中。Uevent事件内容就是一个字符串,linux kernel在下列两种情况下会上报uevent事件:1. 外设状态发生变化触发,当有U盘、sd卡等外设的插拔动作时,都会引起linux kernel上报uevent事件,如果vold在外设状态发生变化之前已经建立了netlink连接,就能收到相应的uevent事件。2. 在/sys目录下会有一个叫做uevent的文件,往该文件中写入特定的数据,也会触发kernel发送和该设备相关的uevent事件,这个由应用层触发,例如vold启动时,会往uevent文件中写入数据,它就会触发linux kernel发送uevent事件,这样vold就能获取设备的当前信息。在etc/目录下有个vold.fstab文件(实际上该文件是在system/etc目录下,它在system/core/rootdir/init.rc中有配置:symlink /system/etc /etc,通过软链接而链接到etc目录下),该文件是android系统与硬件平台交互的接口,用户可以手动配置该文件,在androidsystemcorerootdiretc下有个vold.fstab文件,它描述了vold.fstab文件配置挂载设备的模板,dev_mount 其中part表示分区,值为auto或具体的分区编号,auto表示挂载该设备上的第一个分区(该设备只有一个分区),分区编号表示使用该设备上的第几个分区,sysfs_path表示设备在sys目录下的设备路径(可多个),各个参数之间用全部用空格或tab键隔开。注:sysfs文件系统是linux中一种特殊的文件系统,用于将系统中的设备组织成层次结构,并向用户模式程序提供详细的内核数据结构信息。sysfs_path表示vold监测的路径,当有设备插入时,在监测的路径下会多出一个文件夹,该文件夹中描述了插入设备的各种ID信息。在sys目录下有多个目录:block(系统中的所有块设备)、bus(系统中的所有总线设备)、devices(系统中的所有设备层次结构)、drivers(系统中的所有驱动)等。dev_mount sdcard1 /mnt/sdcard auto /devices/platform/sdhci-tegra.2/mmc_host/mmc1/mmc1当设备中出入sd卡后,在dev/block目录下会多出几个设备节点,表示sd卡驱动已经加载成功,一般会多出两个设备节点mmcblk0和mmcblk0p1节点,其中mmcblk0表示第一个sd卡设备,mmcblk0p1表示第一个sd卡设备的第一个分区,真正挂载到系统中的是mmcblk0p1而非mmcblk0,如果手动使用mount挂载时,不能直接挂载设备,而是选择挂载设备的分区,例如mount -t vfat /dev/block/mmcblk0p1 sdcard关键点:1. Vold的main方法中会调用process_config()方法解析vold.fstab文件,根据文件内容去配置VolumeManager对象。2. 当linux kernel上报一个uevent事件时,NetlinkManager会处理该事件,实际是它是调用NetlinkHandler类处理的,NetlinkHandler类的继承层次关系:NetlinkHandler继承自NetlinkListener,而NetlinkListener又继承自SocketListener。在NetlinkListener类的onDataAvailable()方法中,会将一个原始的uevent事件内容解析为NetlinkEvent类,并调用NetlinkHandler类的onEvent()方法。3. 从kernel上报uevent事件时,vold的处理简单流程为:SocketListener:runListener() -NetlinkListener:onDataAvailable()-NetlinkHandler:onEvent()-VolumeManager:handleBlockEvent()-DirectVolume:handleBlockEvent()-CommandListener:sendBroadcast()。4. vold与MountService进行通信的简单处理流程为:SocketListener:runListener()-FrameworkListener:onDataAvailable()-FrameworkListener:dispatchCommand()-*Cmd: runCommand()。在dispatchCommand()中会根据命令字符串内容不同调用相应的VoldCommand子类的runCommand()进行处理,进而调用VolumeManager的相应方法。经过VolumeManager处理的uevent类型主要有:block、switch、usb_composite、battery、power_supply,在DirectVolume的handleBlockEvent()方法中,会根据设备类型和执行的动作(add/remove/change)执行相应的函数:handleDiskAdded()、handlePartitionAdded()、handleDiskRemoved()、handlePartitionRemoved()等,在这些方法中,最终会调用mVm-getBroadcaster()-sendBroadcast()方法,实际调用了CommandListener类的sendBroadcast()方法,该方法利用socket通信将消息发送给MountService类。5. 当vold发送消息给MountService后,会触发MountService类的onEvent()方法调用(由NativeDaemonConnector调用)。在onEvent()方法中,会发送相应广播消息,并且会调用相应接口触发通知。StorageManager可看做MountService在客户端的代理类。应用程序可以通过调用StorageManager类的相应方法,例如注册监听器获取外设的插拔通知。对于应用程序来说,有两种方式获取外设插拔通知,一是通过StorageManager类的registerListener()注册监听器,二是注册广播接收器接收相应的广播消息。6. MountService.java中会读取storage_list.xml文件(位于framework/res/res/xml/),7. Android系统中使用UeventObserver类可以监控linux kernel上报的uevent事件,利用UeventObserver检测外部设备插拔的设备有:BatteryService:检测充电器的插拔。PhoneWindowManager:检测hdmi的插拔。WiredAccessoryManager:检测有线耳机的插拔。DockObserver:检测底座的插拔。UsbDeviceManager:Android系统作为从设备,连接到主设备pc的检测。读取Uevent事件代码:hardwarelibhardware_legacyueventuevent.c.SocketListener: 处理套接字监听器的基类,vold利用两个socket分别与上层应用和linux kernel进行通信,与上层应用进行通信时,利用的是CommandListener,与linux kernel进行通信利用的是NetlinkHandler,通信机制用的是netlink socket机制。SocketListener的构造函数中指定了两个参数,分别表示socket名字和是否监听套接字(根据定义变量mListen判断)。SocketListener类主要有以下几个方法:startListener():启动监听器,该方法中会创建一个套接字,并启动一个子线程处理socket通信,子线程中会进入一个死循环,然后利用select机制来监听多个套接字,监听套接字有三种:来自客户端的连接请求,客户端发送过来的数据,管道读端。如果变量mListen为false,是不会监听来自客户端的连接请求的。管道读端用于确定是否退出子线程操作。当有客户端发送数据过来时,select()会返回,会调用onDataAvailable()进行处理。onDataAvailable是虚函数,由其子类实现。stopListener():停止监听器,通过往管道中写数据来退出socket通信的子线程。sendBroadcast():遍历所有连接的客户端SocketClient实例,并调用每个实例的sendMsg()方法将消息发送给客户端。FrameworkListener:继承自SocketListener,指定监听套接字变量mListen为true。onDataAvailable()中从socket buffer中获取客户端发送过来的数据,并调用dispatchCommand(),在dispatchCommand()中会解析数据,然后比较command的名字与哪个FrameworkCommand名字匹配,并调用匹配的FrameworkCommand子类的runCommand()方法。该类中还定义了一个registerCmd()方法用于注册各种FrameworkCommand子类。CommandListener:继承自FrameworkListener,在构造函数中指定套接字名称为vold。在CommandListener的头文件中定义了很多种VoldCommand(它继承自FrameworkCommand),这些VoldCommand子类主要有:DumpCmd、VolumeCmd、AsecCmd、ObbCmd、StorageCmd、XwarpCmd、CryptfsCmd、FstrimCmd。其中DumpCmd 类处理打印信息,VolumeCmd处理外部设备Volume的各种操作,例如挂载、卸载、格式化等,AsecCmd处理asec目录相关,安装在sdcard的应用程序相关文件会存放在目录,ObbCmd处理obb文件相关操作(obb文件称为不透明二进制文件,obb文件可能在磁盘上被加密,供应用程序使用,应用程序使用时进行解密,obb文件尺寸一般很大,一般放在sdcard中,不会打包进apk中,它可能被其它应用程序访问和修改)。在CommandListener的构造函数中调用registerCmd()注册了上述8个VoldCommand实例。NetlinkListener:继承自SocketListener,指定监听套接字变量mListen为false,定义了两个虚函数onDataAvailable()和onEvent()。该类主要实现了一个方法onDataAvailable():该方法中会创建一个NetlinkEvent对象,并调用该对象的decode()方法,将其解析为一个NetlinkEvent事件。NetlinkHandler:继承自NetlinkListener,该类中定义了三个方法,start():调用基类SocketListener的startListener(),启动socket监听器。stop():调用基类SocketListener的stopListener(),停止socket监听器。onEvent():处理NetlinkEvent事件,调用VolumeManager:handleBlockEvent(),目前只处理子系统为block的块设备。Volume:处理卷标类。DirectVolume:继承自Volume,该类中的主要方法有handleBlockEvent(),根据上报的NetlinkEve

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论