Android vold进程一 Vold启动和NetlinkManager数据获取

本文介绍了Android系统中vold进程的作用,它作为外部存储设备的管控中心,处理来自内核的uevent消息。NetlinkManager接收并转发这些消息给VolumeManager,再由CommandListener与MountService交互。主要涉及NetlinkManager的启动、工作原理以及与VolumeManager的数据传递。同时,文章还提及了vold的启动流程和主要涉及的文件。
摘要由CSDN通过智能技术生成

一、vold简介:
  vold进程接收来自内核的外部设备消息,用于管理和控制Android平台外部存储设备,包括SD插拨、挂载、卸载、格式化等;当外部设备发生变化时,内核通过Netlink发送uEvent格式的消息给用户空间程序,Netlink 是一种基于异步通信机制,在内核与用户应用间进行双向数据传输的特殊 socket,用户态应用使用标准的socket API 就可以使用 netlink 提供的强大功能。
  Vold主要由三个模块组成:NetlinkManager、VolumeManager和CommandListener,其中三者的的关系如下图所示:
这里写图片描述
  Vold是native程序,用于管理和控制Android平台外部存储设备的管控中心,是一个后台运行的进程。它与Java层的MountService交互,Vold接收来自kernel的uevent消息,然后向上层转发,MountService接收来自vold的消息,同时也可以向vold发送控制命令。
  NetlinkManager模块专门接收来自Linux内核uevent消息,并将消息转发给VolumeManager处理,VolumeManager模块接着又把相关信息通过CommandListener发送给MountService,MountService根据收到的消息会发送相应的处理命令给VolumeManager,VolumeManager接收到命令后直接对外部存储设备进行操作。
  CommandListener模块内部封装一个Socket用于跨进程通信,Java层的客户端MountService就是通过该Socket和服务端Vold进行通信的。
  
总结如下:
Linux Kernel:通过uevent向Vold的NetlinkManager发送Uevent事件;
NetlinkManager:接收来自Kernel的Uevent事件,再转发给VolumeManager;
VolumeManager:接收来自NetlinkManager的事件,再转发给CommandListener进行处理;
CommandListener:接收来自VolumeManager的事件,通过socket通信方式发送给MountService;
MountService:接收来自CommandListener的事件。

涉及的主要文件:
Framework层主要看MountService.java和NativeDaemonConnector.java;
Native层主要看NetlinkManager.cpp, NetlinkHandler.cpp, VolumeManager.cpp,CommandListener.cpp

二、Vold的启动流程
1、Vold的主程序在/system/vold/main.cpp目录中,直接看main.cpp::main()函数:

int main(int argc, char** argv) {
    VolumeManager *vm;
    CommandListener *cl;
    CryptCommandListener *ccl;
    NetlinkManager *nm;
    //解析vold.rc中定义的blkid和fsck相关的参数
    parse_args(argc, argv);
    //获取external/sepolicy/file_contexts中的权限
    sehandle = selinux_android_file_context_handle();
    // Quickly throw a CLOEXEC on the socket we just inherited from init
    //拿到init进程创建的名为vold的socket进程,并为它设置FD_CLOEXEC标志位
    fcntl(android_get_control_socket("vold"), F_SETFD, FD_CLOEXEC);
    fcntl(android_get_control_socket("cryptd"), F_SETFD, FD_CLOEXEC);

    //创建vold目录,用于存放所有subdisk和sdcard的挂载点信息
    mkdir("/dev/block/vold", 0755);
    //1.创建VolumeManager
    (vm = VolumeManager::Instance();
    //2.创建NetlinkManager
    nm = NetlinkManager::Instance();

    //3.创建CommandListener和CryptCommandListener
    cl = new CommandListener();
    ccl = new CryptCommandListener();
    vm->setBroadcaster((SocketListener *) cl);
    nm->setBroadcaster((SocketListener *) cl);   
    //4.启动VolumeManager
    vm->start();
    //根据配置文件fstab.mt6735初始化VolumeManager 
    process_config(vm);

    //5.启动NetlinkManager,处理来自kernel的usb/sdcard插拔消息     
    nm->start()

    //6.应用层往/sys/block目录下的uevent文件写"add\n"指令,
    //触发kernel向上发送Uevent消息,获取设备的当前信息
    coldboot_sent_uevent_count_only = true;
    coldboot("/sys/block");
    coldboot_sent_uevent_count_only = false;
    coldboot("/sys/block"); 

    get_is_nvram_in_data();

    //7.启动CommandListener
    cl->startListener();

    //8.启动CryptCommandListener
    ccl->startListener();

    exit(0);
}

2、NetlinkManager分析
(1)在主程序中,NetlinkManager主要做了以下三项工作:
  a.构造NetlinkManager实例:nm = NetlinkManager::Instance();
  b.设置广播监听事件:nm->setBroadcaster((SocketListener *) cl);
  c.启动NetlinkManager:nm->start();
  下面详细分析:

(2)构造构造NetlinkManager实例

NetlinkManager *NetlinkManager::Instance() {
    if (!sInstance)
        //采用单例模式来创建NetlinkManager实例
        sInstance = new NetlinkManager();
    return sInstance;
}

NetlinkManager::NetlinkManager() {
    mBroadcaster = NULL;//初始化mBroadcaster&
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值