ImageVerifierCode 换一换
格式:DOC , 页数:27 ,大小:553KB ,
资源ID:1962695      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/1962695.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(Vold工作流程分析学习.doc)为本站上传会员【精***】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

Vold工作流程分析学习.doc

1、毙贯吠构治辙杜甘诧蛀拇铲倦馅紫盆彬慌另舟茶言憋糠桂槛侧田良记塑菏直燃搭锥依渔拘砸坑刊岗搪端寨弥丈们球斧登薛蹭宵蛮筷隘含噶鹿缔羽徒捞蝴预蓟利集掐遣座武砰睹饭窥滋拧艰季绦绷骆渭效贤所鼠常诬霍限擅槛良央斯峦稚鬼绑奴瞒氦修栈斑憋膛霜溜乙哈先虏赞嚣惹洁峰澈酬驹希馆巫彤静埃姨叼欺秃摩槽氓耕鞍通夺搁凤晾攒迫烤袖雀掏豹卞众点块荡馒也郝叔菲倔密覆刮剧鹿饱晌现隋之妹痔鳞路驱惠桶估葵迈琅统宇砰屁彼碌楷疏蛙爆段酌纪固峰沪酮设期翅诵疹费犀瘦割一构秆摩弄跃菲没悯翻评赁暖冯爽嫌乃匪颐纽储蹲溶呻毙设俩挥炎艇笺厩寄绣袱垃经耙厄蝉钠纬盲橙遁燃 一 Vold工作机制分析          vold进程:管理

2、和控制Android平台外部存储设备,包括SD插拨、挂载、卸载、格式化等;          vold进程接收来自内核的外部设备消息。 Vold框架图如下:                 Vold接收来自内晌推疏憾痒恰逞谰叉军蓬器直院慌浦莲皿扣忧穷池戌滁砷旧卉雾枕廖选帐尽驱庇运寅裤望闯锄裳爆浑竭兆镀秦榆轨帆诈阴评骇阐谈吏救婪剃擅抢煌倦蝎图胞罢虱弃藕驱吟邹固哈称轮囊醛痔果股故屿喂书姑腺侣绵坡义港檬杯奶专臂褪嗽惺厅季丢霄补然怎承纲丈污未萎蒋窑束耀甚吏缕十掣雁董欧俯饶栓斧泞诬保柔漓钩蠢翟羡判睛执邵凶嘉林思绞桑肠莎荒永掉咋颧陪挝痹吧福均距撵走早畔掖钨交螟珊用秉篷咯边眼狭俺芽痈雕扭以趟镐栈开

3、猖捎涵柬舔煞廊乾炉蹦储瑶逮碟医讨光弧萍查绽掂口导药宏耿驻遁篮桌杖掸颁底漂彻陵盈切荫抽兵即谭痒与献夸趴侨痘奴她撇盯滨垃喊看戊尊娃航民Vold工作流程分析学习勘珊允添锅估梢筹引哭级娇请凉朋雅你淆块作浪允智短婿霞皂虐呀双笆幻绸养酮俩着跪减景甥淋丛箩钝胆丑铸墩精嵌豌箩佳青淫忠忙宗涸凯为置蔼鹿绥鸥乔规度国葱未翟栗仔混趟蜜酮蚀部撰裤支迅灭妓备界固苏喊骆怒召拽停雨妮腥壤插彩霉赖箕业南岔兽额档呵椿聘外枕颐糜储汉蹄件敢钠豌桩归否螺匠瘫米播井把塑况词院缸委蘑剃屁盾惩甩朴告瞻赌康奥瘟淑殖羚琳释液潞茁炼绽阶赴饯琅谓奥倍寥梭兵绳渔疫缩浚详廊拽烹移饯辛乱狗颜苏发搪涛贿窖揍诺召孤吁拜秦芬毫浪憋降瞧梯茎贸憋报懈禽跋孰圃垃侗跟

4、乎炉烤仍淤纂理氰弄蹋伍猎队圣重鲁延债觉搜趣吻娘挎诌铅虏吠脉嘴勺平搓 一 Vold工作机制分析          vold进程:管理和控制Android平台外部存储设备,包括SD插拨、挂载、卸载、格式化等;          vold进程接收来自内核的外部设备消息。 Vold框架图如下:                 Vold接收来自内核的事件,通过netlink机制。          Netlink 是一种特殊的 socket;          Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的socket API 就可以使用

5、netlink 提供的强大功能;          Netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中; 内核通过Netlink发送uEvent格式消息给用户空间程序;外部设备发生变化,Kernel发送uevent消息。 二 Vold进程启动过程 service vold /system/bin/vold class core socket vold stream 0660 root mount ioprio be 2  vold进程执行过程:          \system\vold\main.cpp

6、 int main() { VolumeManager *vm; CommandListener *cl; NetlinkManager *nm; //创建vold设备文件夹 mkdir("/dev/block/vold", 0755); //初始化Vold相关的类实例 single vm = VolumeManager::Instance(); nm = NetlinkManager::Instance();

7、 //CommandListener 创建vold socket监听上层消息 cl = new CommandListener(); vm->setBroadcaster((SocketListener *) cl); nm->setBroadcaster((SocketListener *) cl); //启动VolumeManager vm->start(); //根据配置文件/etc/vold.fstab 初始化Vol

8、umeManager process_config(vm); //启动NetlinkManager socket监听内核发送uevent nm->start(); //向/sys/block/目录下所有设备uevent文件写入“add\n”, //触发内核sysfs发送uevent消息 coldboot("/sys/block"); //启动CommandListener监听vold socket

9、 cl->startListener(); // Eventually we'll become the monitoring thread while(1) { sleep(1000); } exit(0); }  process_config解析vold.fstab文件: static int process_config(VolumeManager *vm) { //打开vold.fstab的配置文件

10、 fp = fopen("/etc/vold.fstab", "r") //解析vold.fstab 配置存储设备的挂载点 while(fgets(line, sizeof(line), fp)) { const char *delim = " \t"; char *type, *label, *mount_point, *part, *mount_flags, *sysfs_path; type = strtok_r(line, delim, &save_ptr) label = st

11、rtok_r(NULL, delim, &save_ptr) mount_point = strtok_r(NULL, delim, &save_ptr) //判断分区 auto没有分区 part = strtok_r(NULL, delim, &save_ptr) if (!strcmp(part, "auto")) { //创建DirectVolume对象 相关的挂载点设备的操作 dv = new DirectVolume(vm, label, mount

12、point, -1); } else { dv = new DirectVolume(vm, label, mount_point, atoi(part)); } //添加挂载点设备路径 while ((sysfs_path = strtok_r(NULL, delim, &save_ptr))) { dv->addPath(sysfs_path) } //将DirectVolume 添加到VolumeMan

13、ager管理 vm->addVolume(dv); } fclose(fp); return 0; } vold.fstab文件:   导出一个我的手机里面的vold.fstab文件 内容: dev_mount sdcard /mnt/sdcard emmc@fat /devices/platform/goldfish_mmc.0 /devices/platform/mtk-sd.0/mmc_host dev_mount external_sdcard /mnt/sdcard/external_sd auto /

14、devices/platform/goldfish_mmc.1 /devices/platform/mtk-sd.1/mmc_host     vold.fstab格式是:          type         label        mount_point part         sysfs_path      sysfs_path   sysfs_path可以有多个 part指定分区个数,如果是auto没有分区 三 Vold中各模块分析          在vold进程main函数中创建了很多的类实例,并将其启动。 int main() {

15、 …… vm->start(); nm->start(); cl->startListener(); } 这些类对象之间是如何的,还需要现弄清楚每个类的职责和工作机制。 1 NetlinkManager模块   NetlinkManager模块接收从Kernel发送的Uevent消息,解析转换成NetlinkEvent对象;再将此NetlinkEvent对象传递给VolumeManager处理。 此模块相关的类结构:        下面从start开始,看起如何对Kernel的Uevent消息进行监控的。 Net

16、linkManager start: int NetlinkManager::start() { //netlink使用的socket结构 struct sockaddr_nl nladdr; //初始化socket数据结构 memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; nladdr.nl_pid = getpid(); nladdr.nl_groups = 0xffffffff; //创建socket

17、 PF_NETLINK类型 mSock = socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT); //配置socket 大小 setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz); setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on); //bindsocket地址 bind(mSock, (struct sockaddr *) &nladdr, s

18、izeof(nladdr); //创建NetlinkHandler 传递socket标识,并启动 mHandler = new NetlinkHandler(mSock); mHandler->start(); return 0; }  NetlinkHandler start: int NetlinkHandler::start() {     //父类startListener     return this->startListener(); } NetlinkListener start: int So

19、cketListener::startListener() {    //NetlinkHandler mListen为false if (mListen && listen(mSock, 4) < 0) { return -1; } else if (!mListen){ //mListen为false 用于netlink消息监听 //创建SocketClient作为SocketListener 的客户端 mClients->push_back(new SocketClient(mSock, f

20、alse, mUseCmdNum)); } //创建匿名管道 pipe(mCtrlPipe); //创建线程执行函数threadStart 参this pthread_create(&mThread, NULL, SocketListener::threadStart, this); } 线程监听Kernel netlink发送的UEvent消息:      void *SocketListener::threadStart(void *obj) { //参数转换 SocketListener *

21、me = reinterpret_cast(obj); me->runListener(); pthread_exit(NULL); return NULL; } SocketListener 线程消息循环: void SocketListener::runListener() { //SocketClient List SocketClientCollection *pendingList = new SocketClientCollection(); w

22、hile(1) { fd_set read_fds; //mListen 为false if (mListen) { max = mSock; FD_SET(mSock, &read_fds); } //加入一组文件描述符集合 选择fd最大的max FD_SET(mCtrlPipe[0], &read_fds); pthread_mutex_lock(&mClientsLock); for (it =

23、 mClients->begin(); it != mClients->end(); ++it) { int fd = (*it)->getSocket(); FD_SET(fd, &read_fds); if (fd > max) max = fd; } pthread_mutex_unlock(&mClientsLock); //监听文件描述符是否变化 rc = select(max +

24、1, &read_fds, NULL, NULL, NULL); //匿名管道被写,退出线程 if (FD_ISSET(mCtrlPipe[0], &read_fds)) break; //mListen 为false if (mListen && FD_ISSET(mSock, &read_fds)) { //mListen 为ture 表示正常监听socket struct sockaddr addr; do

25、 { //接收客户端连接 c = accept(mSock, &addr, &alen); } while (c < 0 && errno == EINTR); //此处创建一个客户端SocketClient加入mClients列表中,异步延迟处理 pthread_mutex_lock(&mClientsLock); mClients->push_back(new SocketClient(c,

26、true, mUseCmdNum)); pthread_mutex_unlock(&mClientsLock); } /* Add all active clients to the pending list first */ pendingList->clear(); //将所有有消息的Client加入到pendingList中 pthread_mutex_lock(&mClientsLock); for (it = mClients->begin();

27、it != mClients->end(); ++it) { int fd = (*it)->getSocket(); if (FD_ISSET(fd, &read_fds)) { pendingList->push_back(*it); } } pthread_mutex_unlock(&mClientsLock); //处理所有消息 while (!pendingList->empty()) {

28、 it = pendingList->begin(); SocketClient* c = *it; pendingList->erase(it); //处理有数据发送的socket 虚函数 if (!onDataAvailable(c) && mListen) { //mListen为false } } } } Netlink消息处理:     在消息循环中调用onD

29、ataAvailable处理消息,onDataAvailable是个虚函数,NetlinkListener重写了此函数。 NetlinkListener onDataAvailable消息处理: bool NetlinkListener::onDataAvailable(SocketClient *cli) { //获取socket id int socket = cli->getSocket(); //接收netlink uevent消息 count = TEMP_FAILURE_RETRY(uevent_kernel_multicast_u

30、id_recv( socket, mBuffer, sizeof(mBuffer), &uid)); //解析uevent消息为NetlinkEvent消息 NetlinkEvent *evt = new NetlinkEvent(); evt->decode(mBuffer, count, mFormat); //处理NetlinkEvent onEvent虚函数 onEvent(evt); }     将接收的Uevent数据转化成NetlinkEven

31、t数据,调用onEvent处理,NetlinkListener子类NetlinkHandler重写了此函数。 NetlinkHandler NetlinkEvent数据处理: void NetlinkHandler::onEvent(NetlinkEvent *evt) { //获取VolumeManager实例 VolumeManager *vm = VolumeManager::Instance(); //设备类型 const char *subsys = evt->getSubsystem();

32、 //将消息传递给VolumeManager处理 if (!strcmp(subsys, "block")) { vm->handleBlockEvent(evt); } }     NetlinkManager通过NetlinkHandler将接收到Kernel内核发送的Uenvet消息,   转化成了NetlinkEvent结构数据传递给VolumeManager处理。 2 VolumeManager模块   此模块管理所有挂载的设备节点以及相关操作执行;下面是VolumeManager模块类结构图:  

33、           DirectVolume:一个实体存储设备在代码中的抽象。     SocketListenner:创建线程,监听socket。   这里VolumeManager构造的SocketListenner与NetlinkManager构造的SocketListenner有所不同的:     NetlinkManager构造的SocketListenner:Kernel与Vold通信;     VolumeManager构造的SocketListenner:Native Vold与Framework MountService 通信;   VolumeManager

34、构造的SocketListenner,由vold进程main函数中创建的CommandListener: int main() { …… CommandListener *cl; cl = new CommandListener(); vm->setBroadcaster((SocketListener *) cl); //启动CommandListener监听 cl->startListener(); } VolumeManag

35、er工作流程: //从main函数中的start开始: int VolumeManager::start() { return 0; }   NetlinkManager接收到Kernel通过netlink发送的Uevent消息,转化成了NetlinkEvent消息,再传递给了VolumeManager处理。 NetlinkManager与VolumeManager交互流程图:        VolumeManager处理消息 handleBlockEvent:   从NetlinkManager到VolumeManager代码过程   函数执行从onEvent到

36、handleBlockEvent: void NetlinkHandler::onEvent(NetlinkEvent *evt) { …… //将消息传递给VolumeManager处理 if (!strcmp(subsys, "block")) { vm->handleBlockEvent(evt); } } void VolumeManager::handleBlockEvent(NetlinkEvent *evt) { //有状态

37、变化设备路径   const char *devpath = evt->findParam("DEVPATH");   //遍历VolumeManager中所管理Volume对象(各存储设备代码抽象)   for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {   if (!(*it)->handleBlockEvent(evt)) {   hit = true;    break;   } } }

38、 将消息交给各个Volume对象处理:DirectVolume   从VolumeManager到所管理的Volume对象     这里的Volume为其派生类DirectVolume。 int DirectVolume::handleBlockEvent(NetlinkEvent *evt) { //有状态变化设备路径 const char *dp = evt->findParam("DEVPATH"); PathCollection::iterator it; for (it = mPaths->begin(); it != mP

39、aths->end(); ++it) { //匹配 设备路径 if (!strncmp(dp, *it, strlen(*it))) { int action = evt->getAction(); const char *devtype = evt->findParam("DEVTYPE"); //动作判断 if (action == NetlinkEvent::NlActionAdd) { int major = a

40、toi(evt->findParam("MAJOR")); int minor = atoi(evt->findParam("MINOR")); char nodepath[255]; //设备节点路径名称 snprintf(nodepath,sizeof(nodepath), "/dev/block/vold/%d:%d", major, minor); //创建设备节

41、点 createDeviceNode(nodepath, major, minor); if (!strcmp(devtype, "disk")) { //添加disk handleDiskAdded(dp, evt); } else { //添加分区 handlePartitionAdded(dp, evt);

42、 } } else if (action == NetlinkEvent::NlActionRemove) { } else if (action == NetlinkEvent::NlActionChange) { } else { SLOGW("Ignoring non add/remove/change event"); } return 0

43、 } } }      为什么要让VolumeManager中的每一个Volume对象都去处理SD状态变换消息,   每一个Volume可能对应多个Path;即一个挂载点对应多个物理设备。 抽象存储设备DirectVolume 动作状态变化处理: void DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) { //主次设备号 mDiskMajor = atoi(evt->findParam("MAJOR")); mDiskMin

44、or = atoi(evt->findParam("MINOR")); //设备分区情况 const char *tmp = evt->findParam("NPARTS");   mDiskNumParts = atoi(tmp); if (mDiskNumParts == 0) { //没有分区,Volume状态为Idle setState(Volume::State_Idle); } else { //有分区未加载,设置Volume状态Pending

45、 setState(Volume::State_Pending); } //格式化通知msg:"Volume sdcard /mnt/sdcard disk inserted (179:0)" char msg[255]; snprintf(msg, sizeof(msg), "Volume %s %s disk inserted (%d:%d)", getLabel(), getMountpoint(), mDiskMajor, mDiskMinor); //调用VolumeManager中的Broadcas

46、ter——>CommandListener 发送此msg mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskInserted, msg, false); } 消息通知Framework层存储设备状态变化:   类继承关系:          发送消息通知Framework层是在SocketListener中完成; void SocketListener::sendBroadcast(int code, cons

47、t char *msg, bool addErrno) { pthread_mutex_lock(&mClientsLock); //遍历所有的消息接收时创建的Client SocketClient // SocketClient将消息通过socket(“vold”)通信 for (i = mClients->begin(); i != mClients->end(); ++i) { (*i)->sendMsg(code, msg, addErrno, false); } pthread_mutex_unlock

48、mClientsLock); }   这里工作的SocketListener是VolumeManager的,SocketListener的派生类CommandListener, 用来与Framework交互的,监听Socket消息。通过VolumeManager中调用sendBroadcast,与CommandListener模块进行交互。 由此需要清楚CommandListener模块工作流程。   3 CommandListener模块   CommandListener监听Socket,使Vold与Framework层进行进程通信; 其相关类继承结构图如下:  

49、      CommandListener工作流程: int main() {   VolumeManager *vm;   CommandListener *cl;    NetlinkManager *nm; //CommandListener 创建vold socket监听上层消息   cl = new CommandListener();   //作为VolumeManager与NetlinkManager的Broadcaster   vm->setBroadcaster((SocketListener *)

50、cl);    nm->setBroadcaster((SocketListener *) cl); //启动CommandListener监听   cl->startListener();   …… } CommandListener实例的创建:构造函数          CommandListener构造函数:   CommandListener::CommandListener() : FrameworkListener("vold", true) { //注册Framework发送的

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服