Android 系统启动流程源码分析

一、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.rhkb.cn/news/324236.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鹦鹉优化算法原理及代码实现

鹦鹉(Pyrrhura Molinae)表现出四种不同的行为特征:觅食、停留、交流和对陌生人的恐惧。这些行为(如图1所示)在现实环境中构成了我们设计PO动机的基础。 觅食:驯化的鹦鹉(Pyrrhura Molinae)的觅食行为令人着迷,因为个体选择在食物丰富的小群体…

支付宝小程序如何去除页面下拉回弹

描述:支付宝小程序页面下拉时会产生回弹,如果页面上有拖拽功能,会有影响 解决方法: 页面xx.config.js中设置:allowsBounceVertical: “NO” 官方文档:https://opensupport.alipay.com/support/FAQ/7110b5d…

VM虚拟机安装调试(步骤如下图)

VM虚拟机安装调试 随着一顿安装操作,还有enter键敲下,出现如下界面。

深入理解线程的两阶段终止模式:确保线程安全退出

序言 在多线程编程中,线程的安全退出是一个重要的问题。在实际应用中,我们经常需要确保线程在退出时能够完成必要的清理工作,同时避免因资源泄漏或状态不一致而导致的问题。线程的两阶段终止模式是一种解决这个问题的有效方法。本文将深入探…

python之并发编程

python之并发编程 线程的创建方式线程的创建方式(方法包装)线程的创建方式(类包装)join()【让主线程等待子线程结束】守护线程【主线程结束,子线程就结束】 锁多线程操作同一个对象(未使用线程同步)多线程操作同一个对象(增加互斥锁,使用线程同步)死锁案…

[muduo网络库]——muduo库三大核心组件之 Poller/EpollPoller类(剖析muduo网络库核心部分、设计思想)

接着上文,[muduo网络库]——muduo库三大核心组件之Channel类(剖析muduo网络库核心部分、设计思想),本章我们来学习muduo网络库中第二大核心组件Poller/EpollPoller类。 先回顾一下三大核心组件之间的关系。 接着我们进入正题。 P…

Java入门——类和对象(上)

经读者反映与笔者考虑,近期以及往后内容更新将主要以java为主,望读者周知、见谅。 类与对象是什么? C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 JAVA是基于面向对…

java中的并发编程

1、上下文切换 即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现 这个机制。这个时间片特别短,一般是几十毫秒,所以会让我们觉得好多任务同时进行。 CPU通过时间片分配算法来循环执行任务,当前任务执…

Java面试——MyBatis

优质博文:IT-BLOG-CN 一、MyBatis 与 JDBC 的区别 【1】JDBC 是 Java 提供操作数据库的 API;MyBatis 是一个持久层 ORM 框架,底层是对 JDBC 的封装。 【2】使用 JDBC 需要连接数据库,注册驱动和数据库信息工作量大,每…

QT 小项目:登录注册账号和忘记密码(下一章实现远程登录)

一、环境搭建 参考上一章环境 二、项目工程目录 三、主要源程序如下: registeraccountwindow.cpp 窗口初始化: void registeraccountWindow::reginit() {//去掉?号this->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButt…

牛客小白月赛93

B交换数字 题目&#xff1a; 思路&#xff1a;我们可以知道&#xff0c;a*b% mod (a%mod) * (b%mod) 代码&#xff1a; void solve(){int n;cin >> n;string a, b;cin >> a >> b;for(int i 0;i < n;i )if(a[i] > b[i])swap(a[i], b[i]);int num1…

LeetCode 209 长度最小的子数组(滑动窗口and暴力)

、 法一&#xff1a;滑动窗口 //使用滑动窗口来解决问题 //滑动窗口的核心点有&#xff1a; /*1.窗口内是什么&#xff1f;2.如何移动窗口的起始位置&#xff1f;3.如何移动窗口的结束位置&#xff1f;4.两个指针&#xff0c;怎么判断哪个指针是终止指针&#xff0c;哪个指针…

推荐4个可用的github国内镜像

Github是全球最大的代码托管云平台&#xff0c;超过1亿用户在平台上分享代码及数据&#xff0c;深受生物信息学软件开发者的喜爱&#xff0c;并且现在发表文章&#xff0c;若涉及到代码&#xff0c;编辑还要求我们把代码及数据存放在github上&#xff0c;以便检查数据的真实性和…

C++ BuilderXE 计算程序运行时间精确到毫秒

#include <time.h> // //计算时间 clock_t start,end,dtStart; startclock(); // ProgressBar1->Percent0; // // ProgressBar1->Percenti/DDnum*100; // Application->ProcessMessages(); // //操作完成计时 …

重生我是嵌入式大能之串口调试UART

什么是串口 串口是一种在数据通讯中广泛使用的通讯接口&#xff0c;通常我们叫做UART (通用异步收发传输器Universal Asynchronous Receiver/Transmitter)&#xff0c;其具有数据传输速度稳定、可靠性高、适用范围广等优点。在嵌入式系统中&#xff0c;串口常用于与外部设备进…

基于OpenCV对胸部CT图像的预处理

1 . 传作灵感 胸部CT中所包含的噪声比较多&#xff0c;基于OpenCV简单的做一些处理&#xff0c;降低后续模型训练的难度。 2. 图像的合成 在语义分割任务中有的时候需要将原图&#xff08;imput&#xff09;和标注数据&#xff08;groudtruth&#xff09;合成一幅图像&#x…

陪玩系统APP小程序H5音视频社交系统陪玩系统源码,陪玩app源码,陪玩源码搭建陪玩社交系统开发(现成,可定制)线下陪玩系统项目开发搭建

线下陪玩系统项目的设计 在需求分析完成后&#xff0c;接下来进行系统设计。系统设计主要包括以下几个部分&#xff1a; 1. 数据库设计&#xff1a;根据需求分析的结果&#xff0c;设计数据库结构&#xff0c;包括用户信息表、服务信息表、订单信息表等。 2. 界面设计&#…

「 网络安全常用术语解读 」SBOM主流格式CycloneDX详解

CycloneDX是软件供应链的现代标准。CycloneDX物料清单&#xff08;BOM&#xff09;可以表示软件、硬件、服务和其他类型资产的全栈库存。该规范由OWASP基金会发起并领导&#xff0c;由Ecma International标准化&#xff0c;并得到全球信息安全界的支持&#xff0c;如今CycloneD…

postman工具使用

一、配置每个接口都有公共的请求头 1.1 新建一个collect集合 my test 1.2 在pre-request script 输入配置 pm.request.addHeader("uid:24011"); pm.request.addHeader("version:2.0.0"); pm.request.addHeader("timezone:8"); pm.request.ad…

如何在 CentOS 上安装并配置 Redis

如何在 CentOS 上安装并配置 Redis 但是太阳&#xff0c;他每时每刻都是夕阳也都是旭日。当他熄灭着走下山去收尽苍凉残照之际&#xff0c;正是他在另一面燃烧着爬上山巅散烈烈朝晖之时。 ——史铁生 环境准备 本教程将在 CentOS 7 或 CentOS 8 上进行。确保你的系统已更新到最…