Android 系统启动流程源码分析

news2024/11/28 20:33:47

一、Init进程启动

是一个由内核启动的用户级进程。内核自行启动之后,就通过启动一个用户级程序init的方式,完成引导进程。

启动的代码init.c中的main函数执行过程:system\core\init.c中:
在这里插入图片描述
主要下面两个重要的过程:
1、rc文件解析
在这里插入图片描述

进入解析函数,把解析出来的东西放入相应的类型(List)
在这里插入图片描述

2、执行command和processes
进入死循环:执行execute_one_command和restart_processes
在这里插入图片描述

第二个原函数调用关系如下
在这里插入图片描述

准备启动service:service_start_if_needed
在这里插入图片描述

启动service的主要入口函数:service_start
在这里插入图片描述

创建进程函数:fork
在这里插入图片描述

执行新的service:execve
在这里插入图片描述

下面启动zygote为例子,在init.rc有这样一段描述
在这里插入图片描述

而svc->args[0]的值就是上面反选的代码。
函数execve(执行文件)说明: execve()用来执行参数filename字符串所代表的文件路径,第二个参数系利用数组指针来传递给执行文件,最后一个参数则为传递给执行文件的新环境变量数组。
返回值 如果执行成功则函数不会返回,执行失败则直接返回-1。

上面是sercice启动,下面在再举个action启动流程的例子
在这里触发,加入到action队列:
在这里插入图片描述

在init.c中main函数有这样一段代码:表示执行action队列
在这里插入图片描述

init.rc有这样一段描述
在这里插入图片描述

单执行到early-init的时候,就会启动这个函数.rc的start对应do_start,看下面代码片段:
在这里插入图片描述

进入do_start函数:
在这里插入图片描述

把参数early-init传入service_start函数,启动init进程,由于kernel启动的时候就已经启动了init进程,所以直接进入init进程的main函数了,看下面描述就会明白:
在这里插入图片描述

因为ueventd 和 Init 在同一个可执行文件下,因此在启动ueventd进程时,进程入口函数依然是main,进入main函数:
在这里插入图片描述
然后进入ueventd_main函数,完成!

二、启动serviceManager

在脚本文件Init.rc的描述,其中/system/bin/servicemanager adb shell 在小机端可以看到:
在这里插入图片描述

看看下面就知道对应源码的位置了:
在这里插入图片描述

打开Android.mk内容如下:
在这里插入图片描述
看到了: LOCAL_MODULE := servicemanager,而servicemanager就是上述.rc的servicemanager对应,所以源码就是service_manager.c;最后,使用include $(BUILD_EXECUTABLE)表示以一个可执行程序的方式进行编译。

源码的位置为:frameworks\base\cmds\servicemanager\service_manager.c
在这里插入图片描述
servicemanager用来管理系统中所有的binder service,不管是本地的c++实现的还是java语言实现的都需要这个进程来统一管理,最主要的管理就是,注册添加服务,获取服务。所有的Service使用前都必须先在servicemanager中进行注册。主要函数如下:
do_find_service( )
do_add_service( )
svcmgr_handler( )

三、Zygote进程启动

Zygote这个进程是非常重要的一个进程,Zygote进程的建立是真正的Android运行空间,初始化建立的Service都是Navtive service。

在脚本文件init.rc的描述
在这里插入图片描述源码的位置为:frameworks\base\cmds\app_process\app_main.cpp
参数为:–zygote --start-system-server
在这里插入图片描述

接着就到了AndroidRuntime类了,代码调用了:
在这里插入图片描述

调用代码位置:Frameworks\base\core\jni\AndroidRuntime.cpp
在这里插入图片描述

再往下就调用了静态main函数
在这里插入图片描述

进入的代码位置为:frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
在这里插入图片描述
Zygote就建立好了,利用Socket通讯,接收请求,Fork应用程序进程,进入Zygote进程服务框架中。

上述中的main函数,是在另外一个.so中,名为:libandroid_runtime.so,是一个共享库。在app_process加载的时候,就把这个.so编译进来了,看下面代码:
在这里插入图片描述

再看libandroid_runtime.so是在哪里编译出来的:Frameworks\base\core\jni\Android.mk,代码片段如下:
在这里插入图片描述
通过上面的共享库和资源加载preload(),整个虚拟机的资源都是共享的,当有fork出其他的虚拟机时候,就可以节省资源了,提高了效率!

四、SystemServer启动

在Zygote进程进入循环之前,调用了startSystemServer( )
在这里插入图片描述
在这里插入图片描述

调用代码位置:frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从startSystemServer开始执行并没有去调用SystemServer的任何方法,只是通过反射获取了main方法,付给了MethodAndArgsCaller,并抛出了MethodAndArgsCaller异常。
此异常是在哪里处理的呢?回到startSystemServer( )函数的调用处:在ZygoteInit的main函数中:
在这里插入图片描述

如果startSystemServer抛出了异常,跳过执行ZygoteInit进程的循环,这是怎么回事呢?
在startSystemServer中异常是由handleSystemServerProcess抛出。
在这里插入图片描述

MethodAndArgsCaller run函数:调用前面所提到的
//SystemServer main方法
m = cl.getMethod(“main”, new Class[] { String[].class });
在这里插入图片描述

启动了进程SystemServer。
在这里插入图片描述

init1代码位置为:frameworks\base\services\jni\com_android_server_SystemServer.cpp
在这里插入图片描述
在这里插入图片描述

在systme_init()中有调用:init2
在这里插入图片描述

再回到init2
在这里插入图片描述
在这里插入图片描述

在类ServerThread启动了大量的服务,可以仔细看看有哪些服务;关键可以到到这些:
在这里插入图片描述
在这里插入图片描述
一切就绪,只差Home启动界面!

五、Home启动

在systemReady中调用了下面函数:
在这里插入图片描述
看下面代码重点:
//Launcher
在这里插入图片描述
然后就启动了Home界面,完成了整个Android启动流程。

六、附件

整个流程如下:
在这里插入图片描述

ps查看开机启动的进程:(看看pid和ppid的关系)

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

觉得本文对您有用,麻烦点赞、关注、收藏,您的肯定是我创作的无限动力,谢谢!!!

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

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

相关文章

每日OJ题_贪心算法三⑤_力扣134. 加油站

目录 力扣134. 加油站 解析代码 力扣134. 加油站 134. 加油站 难度 中等 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一…

基于51单片机的ADC0804的电压表设计(仿真+源码+设计资料)

目录 1、前言 2、资料内容 3、仿真图 4、程序 资料下载地址:基于51单片机的ADC0804的电压表设计(仿真源码设计资料) 1、前言 最近看网上有很少的ADC0804的设计了,都由0809代替,但是有个别因为成本原因和学校课…

60、郑州大学附属肿瘤医院 :用于预测胃癌患者术后生存的深度学习模型的开发和验证[同学,我们的人生应当是旷野]

馒头老师要说的话: 我近期看了一下北京的脑机公司,大概是我之前对这一行业太过于乐观,北京的BCI公司和研究所,比上海、深圳、杭州甚至是重庆都要少,门槛也要高很多。也有我自己的原因,有时站的太高&#x…

LM4562NA 直插DIP8双运放 音频hifi运算放大器

LM4562NA是一款高性能音频运算放大器,其应用领域主要集中在音频和声音处理方面,包括但不限于: 1. 专业录音设备:在录音棚、广播电台和电视台等专业环境中,用于信号放大和处理,确保高质量的声音录制和传输…

Deep Learning Part Eight--Attention 24.5.4

01.在翻译、语音识别等将一个时序数据转换为另一个时序数据的任务中,时序数据之间常常存在对应关系 引入了Attention的概念,介绍了Attention的注意力机制: 困难出现,seq2seq的问题引入:固定化长度问题(过于…

LeetCode 面试经典150题 252.会议室

题目:给定一个会议时间安排的数组 intervals ,每个会议时间都会包括开始和结束的时间 intervals[i] [starti, endi] ,请你判断一个人是否能够参加这里面的全部会议。 思路:因为一个人在同一时刻只能参加一个会议,因此…

QGraphicsView实现简易地图10『自适应窗口大小』

前文链接:QGraphicsView实现简易地图9『层级缩放显示底图』 自适应窗口大小 当地图窗口放大或缩小的时候,需要地图能够动态覆盖整个视口。 1、动态演示效果 2、核心代码 注:WHMapView继承自MapViewvoid WHMapView::resize() {if (m_curLev…

Linux\_c输出

第一条Linux_c输出 初界面 : ls # 显示目录下的文件cd # 进入到某个目录 # 比如 我进入了Codels # 发现没有显示, 说明为文件下为空vim cpucdoe.c # 创建一个 .c的源码文件进入到了vim的编辑界面: i # 按i 就可以进行编辑 , 下面显示插入标识在编辑模式下, 可以通…

纯血鸿蒙APP实战开发——底部面板嵌套列表滑动案例

介绍 本示例主要介绍了利用panel实现底部面板内嵌套列表,分阶段滑动效果场景。 效果图预览 使用说明 点击底部“展开”,弹出panel面板。在panel半展开时,手指向上滑动panel高度充满页面,手指向下滑动panel隐藏。在panel完全展开…

netty 高性能架构设计--零拷贝

文章目录 前言一、直接内存1.1 什么是直接内存1.2 代码实现1.3 使用直接内存的优缺点 二、netty 零拷贝设计2.1 netty 直接内存2.2 netty 内存池 三、零拷贝的两种方式 前言 本篇从源码层面剖析 netty 高性能架构设计之零拷贝,并且扩展讲述零拷贝的两种实现方式。 …

免费在线录屏、无需注册、免费可用、无限制

免费在线工具 https://orcc.online/ 在线录屏 https://orcc.online/recorder pdf在线免费转word文档 https://orcc.online/pdf 时间戳转换 https://orcc.online/timestamp Base64 编码解码 https://orcc.online/base64 URL 编码解码 https://orcc.online/url Hash(MD5/SHA…

【C++STL详解(八)】--------stack和queue的模拟实现

目录 前言 一、stack模拟实现 二、queue的模拟实现 前言 前面也介绍了stack和queue的常见接口,我们也知道stack和queue实际上是一种容器适配器,它们只不过是对底层容器的接口进行封装而已,所以模拟实现起来比较简单!一起来看看是…

FastDFS-单机扩容

描述 周一上班收到用户反馈系统异常,紧急排查日志发现报错:FdfsServerException:错误:28,错误信息:没有足够的存储空间。 解决 根据异常信息判断是文件服务器可用内存不够了,首先登录文件服务器,使用df -h命令查看一…

学习和分析各种数据结构所要掌握的一个重要知识——CPU的缓存利用率(命中率)

什么是CPU缓存利用率(命中率),我们首先要把内存搞清楚。 硬盘是什么,内存是什么,高速缓存是什么,寄存器又是什么? 我们要储存数据就要运用到上面的东西。首先里面的硬盘是可以无电存储的&#…

VMware导入ova/ovf虚拟机文件

1.文件-打开-ova文件 2.为新虚拟机起名称 3.等待导入 4.导入完成,可以开始使用 参考链接:VMware导入ova/ovf虚拟机文件

C# OpenCvSharp 图片找茬

C# OpenCvSharp 图片找茬 目录 效果 项目 代码 下载 效果 项目 代码 using OpenCvSharp; using System; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; namespace OpenCvSharp_Demo { public partial class Form1 : Form { …

初期Linux

一,系统分为 1.1window系统 个人 :win7,win8,Win10,Win11服务器版:window server 2003,window server 2008 1.2Linux系统 centos7redhatubantukali 1.3什么是Linux? Linux是基…

深入Django:用户认证与权限控制实战指南

title: 深入Django:用户认证与权限控制实战指南 date: 2024/5/7 18:50:33 updated: 2024/5/7 18:50:33 categories: 后端开发 tags: AuthDecoratorsPermissionsGuardianRESTAuthSessionMgmtMFA 第1章:入门Django与设置 1.1 Django安装与环境配置 在…

26 JavaScript学习:JSON和void

JSON 英文全称 JavaScript Object NotationJSON 是一种轻量级的数据交换格式。JSON是独立的语言JSON 易于理解。 JSON 实例 简单的 JSON 字符串实例: "{\"name\": \"Alice\", \"age\": 25, \"city\": \"San Francisco\&…

Transformer详解:从放弃到入门(三)

上篇文章中我们了解了多头注意力和位置编码,本文我们继续了解Transformer中剩下的其他组件。 层归一化 层归一化想要解决一个问题,这个问题在Batch Normalization的论文中有详细的描述,即深层网络中内部结点在训练过程中分布的变化问题。  …