Android 12 init流程分析
前言
- 刚开始接触需要了解的概念
- 理解过程遇到了什么问题
- 代码的位置和流程分析
- 如何分析和调试遇到的问题
基本的概念
-
.rc 文件
这个文件在Android framework 中服务相关代码可以看到。类似surfaceflinger.rc 、mediaserver.rc等等。 在这些rc里面定义了某一个service,如下面的surfaceFlinger.rc定义了surfaceflinger 这样一个service,其应用程序的路径在/system/bin/surfaceflinger,是属于core 这一类别,还有其他详细的信息在后面说明
service surfaceflinger /system/bin/surfaceflingerclass core animation
经常在看rc文件会产生相关的问题:
-
rc文件在哪里解析的?
rc文件在init进程的第二阶段进行解析,init进程启动后没有马上就开启rc文件的解析。会先进行一些必要准备工作。
-
rc中定义的service进程是怎么启动的?
rc中定义service 一般是一个应用程序,执行这个应用程序,就是执行程序里面的main。 在init进程启动后解析到service名字后开始执行,但是service不是解析到一个service标签就执行一个,跟service所处的阶段的标记有关系。比如是在early-init、init、late-init等等。某个标记里面所有的service都解析出来了会一个个生成进程去执行。
-
怎么理解rc文件定义的各个项?
主要是几个关键值的确认
on:定义条件比如on init,表示在init这个条件成立的时间执行 -
init中各个标签init early-init 等等是什么时候执行的?
首先在代码中是按照early-init、init、late-init这样的顺序去执行的,在 init.rc中就按照下面的顺序去trigger一系列的标签。这些标签定义的service就有了先后关系。比如init标签定义的service是需要等early-init中所有的service 执行后在执行,但这边并不会等待sevice执行而是起一个进程去执行。除了exec_start 执行的serivice, exec_start执行的 服务需要等待这个服务执行完成才能执行排在他之后的。一般是用在相互之间有依赖关系的服务。
on late-inittrigger early-fstrigger fstrigger post-fstrigger late-fstrigger post-fs-datatrigger load_persist_props_actiontrigger load_bpf_programstrigger zygote-starttrigger firmware_mounts_completetrigger early-boottrigger boot
-
-
init 进程
init 进程是Android 启动的第一个进程,启动过程中从内核空间到用户空间启动的第一个进程,进程号为1。
- init进程执行了哪些流程?如果目标是缩短某个服务的启动时间,要关注哪些方面?
如果关注启动的时间,那么要找到某个服务之前的所有服务,看哪些是必要。同时要特别注意那么exec_start的服务。
- init 读取各个路径下的rc文件 如何看哪些是会耗时的?
android init默认有相关的日志,需要在kernel中去掉打印速率的限制。 - android 系统下面的各个路径什么时候创建,怎么创建的?
跟具体的目录相关,一部分如system/vendor 在init第一阶段,一部分在init.rc文件 - property属性服务什么时候启动的,在什么阶段能够获取到设置的某个属性的值。
- apex是什么? 如何影响开机时间?
init进程流程
-
main函数,init进程也是一个bin,其名字就是init.bin。对于一个bin一般就存在一个mian 函数,main函数肯定就可以传递执行的参数。 在init的main函数里面也是一样的。默认从kernel起来的时候是没有参数的,这个时候执行的 FirstStageMain.
-
FirstStageMain 执行完调用main传递 selinux_setup ,执行 SetupSelinux 。 SetupSelinux 执行完调用main传递 second_stage 执行 second_stage 。所以init的流程就可以分为这样三个流程。
-
FirstStageMain
- DoFirstStageMount: 初始化一些必须的分区 主要去解析/proc/device-tree/firmware/android/fstab, 得到"/system", “/vendor”, "/odm"三个目录的挂载信息
-
second_stage
-
新建epoll并初始化子进程终止信号处理函数,
-
建立属性服务property_service
-
解析init.rc等文件,启动android系统各种各样的服务
-
-
总结
- first 完成目录的创建 基本的文件目录的挂载 system、vendror 等目录解析
- system/etc/init、vendor/etc/init下所有的.rc文件
- rc文件,重要的init.rc 和其他分散在各个目录的services相关的rc
- 按照early-init init late-init这几个标签的先后顺序 执行标签中的任务比如创建文件夹 修改权限等。
- services 的start,start是启动一个进程来进行相关服务执行,不会等待服务执行完成
- exec_start必须等待服务执行完成之后才进行下一个services。用后续服务需要依赖的关键服务
property_service
问题:在rc文件中类似下面需要property属性来判断执行时机的service。最快可以在init的什么时候执行。
换句话就是最快什么时候getprop可以从系统中获取到属性。
on property:vold.decrypt=trigger_shutdown_frameworkclass_reset late_startclass_reset mainclass_reset_post_data coreclass_reset_post_data hal
- init.rc定义 on late-init 中的trigger load_persist_props_action会启动属性服务执行
- 其调用builtins do_load_persist_props,发送消息到propertyserviceThread 中进行处理
- 线程中会进行一系列的权限检查 然后调用PropertySet进行设置,这个时候系统就可以获取到这个属性设置属性的时候
- 同时会唤醒init进程的主线程 然后将on依赖于属性的action 放入到执行队列中进行执行。
总结:在late-init 之后才可以获取属性的值。
APEX
- Android官网的说明
- Android Pony EXpress (APEX) 是 Android 10 中引入的一种容器格式,用于较低级别系统模块的安装流程中。此格式可帮助更新不适用于标准 Android 应用模型的系统组件。一些示例组件包括原生服务和原生库、硬件抽象层 (HAL))、运行时 (ART) 以及类库。
- APEX 管理器(即
apexd
)是一个独立的原生进程,负责验证、安装和卸载 APEX 文件。此进程已启动,并在引导序列早期准备就绪。APEX 文件通常预安装在设备的/system/apex
下。如果没有可用的更新,APEX 管理器默认使用这些软件包。
对于init来说,就是有些系统库是通过APEX的服务来解压 生成的。如果没有apex的服务,会缺失某个库导致依赖于apex的服务起不来。
-
early init的时候启动 apexd-bootstrap 这个服务。
-
而在post-fs-data中启动apex完整的服务,这个是在late init中在trigger load_persist_props_action之前。
-
apex的启动过程 会告知其他服务apex已经启动,会设置 apexd.status的属性为ready。
问题调试
-
log打印
修改kernel下面的代码 重新编译kernel。这样有关启动阶段的action和耗时都会打印出来。
依据下面的log就可以分析相关的耗时问题。
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index e2534757a4f14..5cbb6f17e2b8d 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -734,8 +734,8 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)/* Ratelimit when not explicitly enabled. */if (!(devkmsg_log & DEVKMSG_LOG_MASK_ON)) { - if (!___ratelimit(&user->rs, current->comm)) - return ret; + // if (!___ratelimit(&user->rs, current->comm)) + // return ret;}
Line 1968: [ 6.297233][ T1] init: Service 'boringssl_self_test32' (pid 307) exited with status 0 waiting took 0.079000 secondsLine 1974: [ 6.364255][ T1] init: Service 'boringssl_self_test64' (pid 309) exited with status 0 waiting took 0.065000 secondsLine 1994: [ 6.508128][ T1] init: Service 'boringssl_self_test32_vendor' (pid 314) exited with status 0 waiting took 0.025000 secondsLine 2000: [ 6.522300][ T1] init: Service 'boringssl_self_test64_vendor' (pid 315) exited with status 0 waiting took 0.011000 seconds
surfaceFlinger.rc 文件解析
service surfaceflinger /system/bin/surfaceflingerclass core animationuser systemgroup graphics drmrpc readproccapabilities SYS_NICEonrestart restart --only-if-running zygotetask_profiles HighPerformancesocket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
service surfaceflinger /system/bin/surfaceflinger
: 定义了一个名为 “surfaceflinger” 的服务,并指定了服务的可执行文件路径为 “/system/bin/surfaceflinger”。class core animation
: 指定了服务的 class(类别),在这里是 “core” 和 “animation”。这些类别用于权限控制和进程调度。user system
: 指定了运行服务的用户为 “system”。group graphics drmrpc readproc
: 指定了服务所属的用户组。在这里,服务属于 “graphics”、“drmrpc” 和 “readproc” 用户组。capabilities SYS_NICE
: 指定了服务的特殊权限,这里是 “SYS_NICE”。它允许服务在调度上具有更高的优先级。onrestart restart --only-if-running zygote
: 指定了在服务重新启动时要执行的命令。这里是当 zygote 进程正在运行时才重新启动服务。task_profiles HighPerformance
: 指定了任务配置文件(task profile)为 “HighPerformance”。这可以影响服务的资源分配和调度。socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
: 定义了一个名为 “pdx/system/vr/display/client” 的 UNIX 域套接字(socket),并指定了套接字的权限、所有者和安全上下文。socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
: 定义了一个名为 “pdx/system/vr/display/manager” 的 UNIX 域套接字(socket),并指定了套接字的权限、所有者和安全上下文。
基本是其他的rc文件包含的内容也类似。
相关文章:
Android 12 init流程分析
前言 刚开始接触需要了解的概念理解过程遇到了什么问题代码的位置和流程分析如何分析和调试遇到的问题 基本的概念 .rc 文件 这个文件在Android framework 中服务相关代码可以看到。类似surfaceflinger.rc 、mediaserver.rc等等。 在这些rc里面定义了某一个service࿰…...

【Python小技巧】Python操控Chrome浏览器实现网页打开、切换、关闭(送独家Chrome操作打包类源码、Chrome浏览器Cookie在哪里?)
文章目录 前言一、什么时候需要用Python控制浏览器?二、下载Chrome浏览器驱动文件1. 安装Chrome浏览器并查看版本2. 下载浏览器驱动文件3. 解压到python编译器目录(python.exe所在目录) 三、Python控制Chrome浏览器(附源代码&…...

数据在内存中的存储
目录 一、数据类型的介绍 1.C语言基本内置类型 2.类型基本归类 1.整形 2.浮点型 3.构造类型 4.指针类型 二、整形在内存中的存储 三、浮点数在内次中的存储 1.存储形式 2.对M、E的特殊规定 (1)对M的特殊规定 (2)对E的…...

Rust in Action笔记 第三章 复合数据类型
通过#[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZI50wIh1-1685693144796)(null)]),不带感叹号的#[allow]仅为下一行代码提供属性,属性有多种分类,文中出现的allow属性称为诊断属性(Diag…...

算法基础学习笔记——⑬高斯消元\组合计数\容斥原理
✨博主:命运之光 ✨专栏:算法基础学习 目录 ✨高斯消元 ✨组合计数 🍓通过预处理逆元的方式求组合数: 🍓Lucas定理: 🍓分解质因数法求组合数: 前言:算法学习笔记记录日常分享,需…...

渗透测试辅助工具箱
0x01 说明 渗透测试辅助工具箱 运行条件:jdk8 双击即可运行 反弹shell,命令生成器,自动编码,输入对应IP端口即可,实现一劳永逸,集成一些小工具,辅助渗透,提高效率 输入框说明 L…...

chatgpt赋能python:Python后退命令:如何让你的程序退回到之前的状态
Python后退命令:如何让你的程序退回到之前的状态 Python是一种高级编程语言,因其易读易懂而闻名于世。Python中有很多命令用于编写程序,其中一项重要的命令是后退命令。本文将介绍Python后退命令的使用方法,并为您提供详细的步骤…...
OJ练习第127题——统计范围内的元音字符串数
统计范围内的元音字符串数 力扣链接:2559. 统计范围内的元音字符串数 题目描述 给你一个下标从 0 开始的字符串数组 words 以及一个二维整数数组 queries 。 每个查询 queries[i] [li, ri] 会要求我们统计在 words 中下标在 li 到 ri 范围内(包含 这…...

图片优化: CssSprites与Base64编码
文章目录 1 css sprites1.1 CSS Sprites是什么1.2 为什么需要css sprites1.3 优势1.4 使用原理1.5 DEMO 2 图片Base64编码 1 css sprites 1.1 CSS Sprites是什么 CSS Sprites是一种网页图片应用处理方式。 又被解释为: CSS精灵CSS图像拼合CSS贴图定位CSS图片精灵…...
JavaScript中的Map、WeakMap和Object的区别
Map Map是一种新的数据结构,它允许使用任何数据类型(包括对象和基本数据类型)作为键。 Map的一些特性包括: 保持键的插入顺序:当遍历Map时,键值对会按照插入顺序返回。键可以是任意类型:与Obj…...

华为OD机试之打印机队列(Java源码)
打印机队列 题目描述 有5台打印机打印文件,每台打印机有自己的待打印队列。 因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的代先级,其中 数字越大优先级越高 打印机会从自己的待打印队列中选择优先级最高的文件来打印。 如…...

分享一个国内免费的ChatGPT网站,手机电脑通用,免费无限制,支持AI绘画
背景 ChatGPT作为一种基于人工智能技术的自然语言处理工具,近期的热度直接沸腾🌋。 作为一个AI爱好者,翻遍了各大基于ChatGPT的网站,终于找到一个免费!免登陆!手机电脑通用!国内可直接对话的C…...
【面向对象编程1】——类和对象——如桃花来
目录索引 面向过程和面向对象的区别:面向过程:面向对象:总结: 类和对象:定义类:语法: 创建对象:实例演示: 魔法方法:__init __方法:__ del __方法…...

chat聊天系统消息消费时遇到的问题及优化思路(二)
1、前言 考虑下面几个条件下如何提升kafka的消费速度 消息要求严格有序,如chat聊天消息业务处理速度慢,如处理一条数据需要100ms分片不合理,如有的分区很闲,有的分区消息数量积压 2、解决方案 1、顺序问题 关于消息消费时存在…...

js正则中的match()
在前端开发中,正则表达式是一大利器。所以我们这次就来讨论下match()方法。 match本身是JavaScript语言中字符串对象的一个方法,该方法的签名是 match([string] | [RegExp]) 它的参数既可以是一个字符串,也可以是一个正则表达式。该方法绝…...

Apache 配置和应用
目录 构建虚拟 Web 主机 Options指令解释 Options指令常用选项 AllowOverride指令解释: 地址限制策略: httpd服务支持的虚拟主机类型包括以下三种: 基于域名的虚拟主机 1.为虚拟主机提供域名解析 2.为虚拟主机准备网页文档 3.添加虚拟…...
实现PyTorch/ONNX自定义节点操作的TensorRT部署
参考一 下面是基本步骤: 加载训练好的bev transformer网络权重参数: import torch from model import Modelmodel Model() model.load_state_dict(torch.load("path/to/weights"))定义新的自定义操作: import torch from torc…...

Shamir 秘密共享、GMW和BGW方案
一、Shamir秘密共享 Shamir秘密共享方案是一种将秘密拆分成多份并分配给多个参与者保存,只有在满足特定条件下才能恢复原始秘密的密码学方案。它具有良好的容错性、加法同态性和无条件安全性等特点。 具体地,Shamir秘密共享方案可以概括为以下步骤&…...

Day56【动态规划】583.两个字符串的删除操作、72.编辑距离
583.两个字符串的删除操作 力扣题目链接/文章讲解 视频讲解 1、确定 dp 数组下标及值含义 dp[i][j]:以下标 i 为结尾的字符串 word1,和以下标 j 为结尾的字符串 word2,想要达到相等,所需要删除元素的最少次数为 dp[i][j] 2、…...

Arnold图像置乱的MATLAB实现
这件事情的起因是这样的,我需要研究一下各种图像置乱的算法。然后在知乎上找到了一篇关于Arnold变化的文章,但是呢,这个人实际上是卖资料,代做大作业的。详细的代码根部不给你,则给我气坏了,必须要手动实现…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...