Android守护进程——Vold (Volume Daemon)

news2025/7/16 14:15:21

简介

介绍:Vold 是用来管理 android 系统的存储设备,如U盘、SD卡、磁盘等移动设备的热插拔、挂载、卸载、格式化

框架结构:Vold 在系统中以守护进程存在,是一个单独的进程。处于Kernel和Framework之间,是两个层级连接的桥梁。下图是Vold在Android系统的整体架构
在这里插入图片描述

组成

重要模块

NetLinkManager(简称NM):内部建立了 socket 连接,主要作用是接收来自 Kernel 的 Uevent 消息。例如SD卡的插拔等动作都会引起 Kernel 向 NM 发送 Uevent 消息
NetlinkHandler:负责解析内核的 Uevent ,它本质上是一个SocketListener类,它们的继承关系,即:NetlinkHandler、NetlinkListener和SocketListener继承关系如下:

VolumeManager模块(简称VM):Android13 中是VM处理完从NM接收到的NetlinkEvent后,通过binder将消息传递给StorageManagerService 进行下一步处理,然后 VM 根据 StorageManagerService 返回的消息管理卷
VoldNativeService模块:主要是与 StorageManagerService 进行通信,继承 BinderService 类,启动过程中主要注册了接口,使其他服务可以通过IVold可以找到,然后启动线程
StorageManager 模块:Framework 层的API,用于APP和其它系统组件访问存储相关的功能。它是 StorageManagerService 的客户端,通过 Binder 调用 StorageManagerService 提供的 API

Vold 启动流程

与其说是Vold启动流程,更不如说是Android存储的初始化工作,Vold的主要功能,就是存储区的管理。Android 的初始化工作可以大致分为三个阶段:

  • 清理环境,因为Android是支持多用户的,启动时的可能是另一个用户,所以需要把之前的用户数据清理干净
  • 启动存储服务,如Vold、StorageManager等等
  • 挂载emulated存储(用于模拟SD卡,历史原因,下面章节会着重介绍)

第一个用户态进程init
• init.rc 启动 Vold 进程

//init.rc  片段
service vold /system/bin/vold \
--blkid_context =u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 \
--fsck_context =u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
class core
ioprio be 2
task_profiles ProcessCapacityHigh
shutdown critical
group root reserved_disk
reboot_on_failure reboot,vold-failed
// adb shell -> ps -A | grep vold
130|shenoo:/mnt/media_rw # ps -A | grep vold // vold 的父进程PID=1(init)
root           471     1 11001604  9596 binder_wait_for_work 0 S vold

Vold 启动

在这里插入图片描述
动VolumeManager:

  1. VM 会先卸载掉对应文件夹中的所有东西,使之处于一个干净的状态;
  2. 通过VolumeBase基类智能指针new了一个EmulatedVolume对象,同时构造出内置存储目录(/data/media);
  3. 在create函数中,执行了doCreate,doCreate是虚函数,在EmulatedVolume中并没有实现,所以最终还是调用了基类函数,也就直接返回了。之后的listener则是StorageManager服务,但是由于Vold启动较早,SystemServer还没有启动StorageManager,所以这里getListener()得到的是空,后面StorageManager启动完成后会重新触发。
  4. 设置了当前存储设备的状态为unmounted。
  5. 最后Vold会创建一个虚拟磁盘

• 启动VoldNativeService:VoldNativeService依赖的是aidl接口逻辑,连接着StorageManager和vold。它继承自BinderService,启动过程中主要注册了接口,使其他服务可以通过 IVold 可以找到,然后启动线程。
• 启动NetlinkManager:启动过程中内部建立了一个socket连接,用于接收所有的uevent事件,最后会new一个NetlinkHandler对象,并执行start函数。然后调用NetlinkListener父类的startListener函数去监听event。
• 总之,Vold启动完成后,后续Vold会监听kernel的uevent事件,然后处理转发通过Callback通知到StorageManager,而Framework的服务以及App则可以通过StorageManager去使用Vold处理Command

int main(int argc, char** argv) {
    ... //忽略部分代码
    ATRACE_BEGIN("main");
    VolumeManager* vm;
    NetlinkManager* nm;
    parse_args(argc, argv); //解析传递的参数
    ...
    mkdir("/dev/block/vold", 0755);
    ...    
    //创建 VolumeManager 实例
    if (!(vm = VolumeManager::Instance())) {
        LOG(ERROR) << "Unable to create VolumeManager";
        exit(1);
    }
    //创建 NetlinkManager 实例
    if (!(nm = NetlinkManager::Instance())) {
        LOG(ERROR) << "Unable to create NetlinkManager";
        exit(1);
    }

    if (android::base::GetBoolProperty("vold.debug", false)) {
        vm->setDebug(true);
    }
    //启动 VolumeManager
    if (vm->start()) {
        PLOG(ERROR) << "Unable to start VolumeManager";
        exit(1);
    }
    ...
    VoldConfigs configs = {};
    if (process_config(vm, &configs)) {
        PLOG(ERROR) << "Error reading configuration... continuing anyways";
    }
    ...
    android::hardware::configureRpcThreadpool(1, false /* callerWillJoin */);
    ...
    //VoldNativeService它是一个binder服务,start方法会把它发布到ServiceManager中
    if (android::vold::VoldNativeService::start() != android::OK) {
        LOG(ERROR) << "Unable to start VoldNativeService";
        exit(1);
    }
    ...
    //启动 NetlinkManager
    if (nm->start()) {
        PLOG(ERROR) << "Unable to start NetlinkManager";
        exit(1);
    }
    ...
    android::IPCThreadState::self()->joinThreadPool();//加入线程池
    LOG(INFO) << "vold shutting down";
    exit(0);
}

启动 storaged 服务
此外,系统还会启动与Vold息息相关的服务,比如它的上游服务——StorageManagerService,大致流程如下:

init.rc  ->  Zygote  ->  SystemServer  ->  StorageManagerService

具体:
• 开机后,安卓启动的第一个用户态进程是init,init进程会fork出zygote进程,zygote又fork出 system server
zygote fork system server

 zygoteServer = new ZygoteServer(isPrimaryZygote);

• SystemServer 启动函数入口
zygote 启动服务

     /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
•	SystemServer().run()会启动各种service

通过 run() 启动各种服务

779      private void run() {
            .......
955          // Start services.
956          try {
957              t.traceBegin("StartServices");
958              startBootstrapServices(t);
               .....
962          } catch (Throwable ex) {
963              Slog.e("System", "******************************************");
964              Slog.e("System", "************ Failure starting system services", ex);
965              throw ex;
966          }
            ........

• 在startBootstrapServices函数里会启动 ActivityManager
StartActivityManager

1073      private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
            .......
1144          t.traceBegin("StartActivityManager");
1145          // TODO: Might need to move after migration to WM.
1146          ActivityTaskManagerService atm = mSystemServiceManager.startService(
1147                  ActivityTaskManagerService.Lifecycle.class).getService();
1148          mActivityManagerService = ActivityManagerService.Lifecycle.startService(
1149                  mSystemServiceManager, atm);
1150          mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
1151          mActivityManagerService.setInstaller(installer);
1152          mWindowManagerGlobalLock = atm.getGlobalLock();
1153          t.traceEnd();

启动systemReady()函数

 2829          // We now tell the activity manager it is okay to run third party
2830          // code.  It will call back into us once it has gotten to the state
2831          // where third party code can really run (but before it has actually
2832          // started launching the initial applications), for us to complete our
2833          // initialization.
2834          mActivityManagerService.systemReady(() -> {
2835              Slog.i(TAG, "Making services ready");
2836              t.traceBegin("StartActivityManagerReadyPhase");
2837              mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
2838              t.traceEnd();
2839              t.traceBegin("StartObservingNativeCrashes");

systemReady 实现

8264      /**
8265       * Ready. Set. Go!
8266       */
8267      public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
8268          t.traceBegin("PhaseActivityManagerReady");
8269          mSystemServiceManager.preSystemReady();
8392          // On Automotive / Headless System User Mode, at this point the system user has already been
8393          // started and unlocked, and some of the tasks we do here have already been done. So skip
8394          // those in that case. The duplicate system user start is guarded in SystemServiceManager.
8395          // TODO(b/242195409): this workaround shouldn't be necessary once we move the headless-user
8396          // start logic to UserManager-land.
8397          mSystemServiceManager.onUserStarting(t, currentUserId);

处理 H_BOOT_COMPLETED 消息

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2338112.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3+vite 实现.env全局配置

首先创建.env文件 VUE_APP_BASE_APIhttp://127.0.0.1/dev-api 然后引入依赖&#xff1a; pnpm install dotenv --save-dev 引入完成后&#xff0c;在vite.config.js配置文件内加入以下内容&#xff1a; const env dotenv.config({ path: ./.env }).parsed define: { // 将…

AI 组件库是什么?如何影响UI的开发?

AI组件库是基于人工智能技术构建的、面向用户界面&#xff08;UI&#xff09;开发的预制模块集合。它们结合了传统UI组件&#xff08;如按钮、表单、图表&#xff09;与AI能力&#xff08;如机器学习、自然语言处理、计算机视觉&#xff09;&#xff0c;旨在简化开发流程并增强…

OpenCV day6

函数内容接上文&#xff1a;OpenCV day4-CSDN博客 , OpenCV day5-CSDN博客 目录 平滑&#xff08;模糊&#xff09; 25.cv2.blur()&#xff1a; 26.cv2.boxFilter(): 27.cv2.GaussianBlur()&#xff1a; 28.cv2.medianBlur(): 29.cv2.bilateralFilter()&#xff1a; 锐…

【AI飞】AutoIT入门七(实战):python操控autoit解决csf视频批量转换(有点难,AI都不会)

背景&#xff1a; 终极目标&#xff1a;通过python调用大模型&#xff0c;获得结果&#xff0c;然后根据返回信息&#xff0c;控制AutoIT操作电脑软件&#xff0c;执行具体工作。让AI更具有执行力。 已完成部分&#xff1a; 关于python调用大模型的&#xff0c;可以参考之前的…

MARA/MARC表 PSTAT字段

最近要开发一个维护物料视图的功能。其中PSTAT字段是来记录已经维护的视图的。这里记录一下视图和其对应的字母。 MARA还有个VPSTA&#xff08;完整状态&#xff09;字段&#xff0c;不过在我试的时候每次PSTAT出现一个它就增加一个&#xff0c;不知道具体是为什么。 最近一直…

学习型组织与系统思考

真正的学习型组织不是只关注个人的学习&#xff0c;而是关注整个系统的学习。—彼得圣吉 在这两年里&#xff0c;越来越多的企业开始询问是否可以将系统思考的内容内化给自己的内训师&#xff0c;进而在公司内部进行教学。我非常理解企业这样做的动机&#xff0c;毕竟内部讲师…

支持mingw g++14.2 的c++23 功能print的vscode tasks.json生成调试

在mingw14.2版本中, print库的功能默认没有开启, 生成可执行文件的tasks.json里要显式加-lstdcexp, 注意放置顺序. tasks.json (支持mingw g14.2 c23的print ) {"version": "2.0.0","tasks": [{"type": "cppbuild","…

守护者进程小练习

守护者进程含义 定义&#xff1a;守护进程&#xff08;Daemon&#xff09;是运行在后台的特殊进程&#xff0c;独立于控制终端&#xff0c;周期性执行任务或等待事件触发。它通常以 root 权限运行&#xff0c;名称常以 d 结尾&#xff08;如 sshd, crond&#xff09;。 特性&a…

opencv函数展示3

一、图像平滑&#xff08;模糊&#xff09; 线性滤波&#xff08;速度快&#xff09;&#xff1a; 1.cv2.blur() 2.cv2.boxFilter() 3.cv2.GaussianBlur() 非线性滤波&#xff08;速度慢但效果好&#xff09;&#xff1a; 4.cv2.medianBlur() 5.cv2.bilateralFilter() 二、锐…

遥感技术赋能电力设施监控:应用案例篇

目前主流的电力巡检手段利用无人机能够通过设定灵活航线进行低空飞行、搭载不同的采集设备&#xff0c;能够从不同角度对输电线进行贴近拍摄&#xff0c;但缺陷是偏远山区无人机飞行技术要求高&#xff0c;成本高&#xff0c;且飞行的无人机也可能会对输电线产生破坏。 星图云开…

SpringAI+DeepSeek大模型应用开发——5 ChatPDF

ChatPDF 知识库 RAG检索增强 由于训练大模型非常耗时&#xff0c;再加上训练语料本身比较滞后&#xff0c;所以大模型存在知识限制问题&#xff1a; 知识数据比较落后&#xff0c;往往是几个月之前的&#xff1b;不包含太过专业领域或者企业私有的数据&#xff1b; 为了解决…

yolov8 框架自带模型体验功能

简介 YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本&#xff0c;目前支持图像分类、物体检测和实例分割任务。 YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c…

Android --- SystemUI启动流程

1.main 函数入口&#xff0c;调用SystemServer().run()方法 代码路径:frameworks/base/services/java/com/android/server/SystemServer.java 2.run 方法中有3种服务的启动&#xff0c;我们主要看StartOtherService 代码路径:frameworks/base/services/java/com/android/se…

【SpringMVC】深入解析自定义拦截器、注册配置拦截器、拦截路径方法及常见拦截路径、排除拦截路径、拦截器的执行流程

拦截器 上个章节我们完成了强制登录的功能, 后端程序根据Session来判断用户是否登录, 但是实现方法是比较麻烦的&#xff1a; 需要修改每个接口的处理逻辑需要修改每个接口的返回结果接口定义修改, 前端代码也需要跟着修改 有没有更简单的办法, 统一拦截所有的请求, 并进行Se…

基于VS Code 为核心平台的python语言智能体开发平台搭建

以下是基于 VS Code 为核心平台&#xff0c;整合 Node-RED、Gradio、Docker Desktop 的智能体可视化开发平台优化方案&#xff0c;聚焦工具链深度集成与开发效率提升&#xff1a; 一、核心架构设计 #mermaid-svg-f8l9kYPAlJ2TlpGF {font-family:"trebuchet ms",verd…

使用最新threejs复刻经典贪吃蛇游戏的3D版,附完整源码

基类Entity 建立基类Entity&#xff0c;实现投影能力、动画入场效果&#xff08;从小变大的弹性动画&#xff09;、计算自己在地图格位置的方法。 // 导入gsap动画库&#xff08;用于创建补间动画&#xff09; import gsap from gsap// 定义Entity基类 export default class …

论坛测试报告

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

zset.

zset 有序集合 zset 保留了 set 不能有重复元素的特点 zset 中的每个元素都有一个唯一的浮点类型的分数&#xff08;score&#xff09;与之关联&#xff0c;使得 zset 内部的元素是可以维护有序性的。但是这个有序不是用下标作为排序依据的&#xff0c;而是根据分数&#xf…

Windows 部署 DeepSeek 详细教程

一、准备工作 系统要求&#xff1a; 建议Windows 10 22H2 或更高版本&#xff0c;家庭版或专业版上网环境&#xff1a; 建议科学上网&#xff0c;国内访问部分网站会很慢设备要求&#xff1a; 内存8G以上、关闭防火墙 二、安装Ollama 官网链接: https://ollama.com/downloadg…

过去十年前端框架演变与技术驱动因素剖析

一、技术演进脉络&#xff08;2013-2023&#xff09; 2013-2015&#xff1a;结构化需求催生框架雏形 早期的jQuery虽然解决了跨浏览器兼容性问题&#xff08;如IE8兼容性处理&#xff09;&#xff0c;但其松散的代码组织方式难以支撑复杂应用开发。Backbone.js的出现首次引入M…