1、Android的开机启动流程

Android的层次框架图,如下所示:

图片清晰地展示了Android的五层架构,从上到下依次是:应用层、应用框架层、库层、运行时层以及Linux内核层。Android的启动流程是自下向上的,大体上可以分为三个阶段:1、BootLoader引导启动内核;2、启动Linux内核;3、启动Android系统。

Android的启动流程如下所示:

接下来具体地描述一下启动过程:

Step 1. Boot Rom

当长按电源开机的时候,引导芯片开始从固化在ROM的预设代码开始执行,然后将加载引导程序到RAM中。

Step 2. BootLoader

BootLoader又称为引导程序,它在运行操作系统之前运行的一段程序,是运行的第一个程序。主要的功能有检查RAM、初始化一些硬件外设等功能,它最终的目的是启动操作系统。

文件的路径为:

/bootable/bootloader/

BootLoader的最主要功能是将操作系统进行启动,把操作系统的镜像文件拷贝到RAM中去,然后跳转到它的入口处去执行,我们称之为启动加载模式,该过程没有用户的介入,是它正常的工作模式,其步骤如下:

Stage 1:

(1)硬件初始化,为Stage 2的执行以及随后内核的运行准备好基本的硬件环境;

(2)为加载Stage 2准备RAM空间,为了获得更好的执行速度,通常把Stage 2加载到RAM中执行;

(3)复制Stage 2的代码到RAM中;

(4)设置好堆栈;

(5)跳转到Stage 2的C程序入口。

Stage 2:

(1)初始化本阶段要使用的硬件设备;

(2)检测系统内存映射;

(3)将内核镜像和根文件系统从ROM读到RAM中;

(4)为内核设置好启动参数;

(5)启动内核。

Step 3. 初始化Kernel

接着就开始进入C语言编写的结构无关的代码了,这个入口的函数是start_kernel函数,该函数完成了内核的大部分初始化工作,实际上,可以将start_kernel函数看作是内核的main函数。start_kernel函数执行到最后调用了rest_init函数进行后续的初始化,该函数的最主要任务就是启动内核线程kernel_init。kernel_init函数将完成设备驱动程序的初始化,并调用init_post函数启动用户空间的init进程,到init_post函数为止,内核的初始化已经基本完成。

文件路径:

/kernel/init/main.c

Step 4. init进程

当初始化内核之后,就会启动一个相当重要的祖先进程,也就是init进程,在Linux系统中,所有的进程都是由init进程直接或间接fork出来的。init进程负责创建系统中最关键的几个子进程,尤其是Zygote进程,另外,它还提供了property service,类似于Windows系统的注册表服务。

在Android系统中,会有一个init.rc脚本,init进程一旦启动就会读取并解析这个脚本文件,把其中的元素整理成自己的数据结构(链表)。

文件路径:

/system/core/init/init.c
/system/core/rootdir/init.rc
/system/core/init/readme.txt

Step 5. Zygote进程

当init进程创建之后,会fork出一个Zygote进程,这个进程是所有Java进程的父进程。我们知道,Linux是基于C的,而Android是基于Java的(底层也是C),所有这里就会fork出一个Zygote Java进程用来fork出其它的进程。在Zygote开启的时候,会调用ZygoteInit.main()进行初始化。

接下来,看一段ZygoteInit.main()的源码:

public static void main(String argv[]) {

......

    // 加载zygote的时候,会传入参数,startSystemServer变为true
boolean startSystemServer = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
} ...... // 启动的SystemServer进程
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
......
}

源码的文件路径:

/framework/base/core/java/com/android/internal/os/ZygoteInit.java

Step 6. SystemServer进程

前面的ZygoteInit.java文件中,通过startSystemServer()函数fork出了SystemServer进程,这个进程在整个Android系统中非常重要,它和Zygote进程一样,是Android Framework层的两大重要进程。系统里面的服务都是在这个进程里面开启的,例如AWS、WindowsManager等都是由这个SystemServer进程fork出来的。

在下面的代码中,可以看到服务如何开启并具体开启了哪些服务:

public final class SystemServer {

    // The main entry point from zygote.
public static void main(String[] args) {
new SystemServer().run();
} public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
} private void run() { ...... // 初始化原生服务库
System.loadLibrary("android_servers");
nativeInit(); // 初始化系统上下文
createSystemContext(); // 创建SystemServiceManager对象
mSystemServiceManager = new SystemServiceManager(mSystemContext); // 开启服务
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} ...... // Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
} //初始化系统上下文对象mSystemContext,并设置默认的主题。
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
} //在这里开启了几个核心的服务,因为这些服务之间相互依赖,所以都放在了这个方法里面。
private void startBootstrapServices() { ...... //初始化ActivityManagerService
mActivityManagerService = mSystemServiceManager
.startService(ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager); //初始化PowerManagerService,因为其他服务需要依赖这个Service,因此需要尽快的初始化
mPowerManagerService = mSystemServiceManager
.startService(PowerManagerService.class); // 现在电源管理已经开启,ActivityManagerService负责电源管理功能
mActivityManagerService.initPowerManagement(); // 开启DisplayManagerService
mDisplayManagerService = mSystemServiceManager
.startService(DisplayManagerService.class); // 开启PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext,mInstaller,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); ......
} private void startCoreServices() {...}// 启动一些基本服务。 private void startOtherServices() {...}// 启动其他服务。
}

源文件文件路径:

/framework/base/core/java/com/android/server/SystemServer.java

Step 7. Home Activity

在上面的ActivityManagerService开启之后,会调用finishBooting()函数,完成引导过程,同时发送开机广播"ACTION_BOOT_COMPLETED"。

下面是finishBooting()源码:

final void finishBooting() {

......
final int userId = mStartedUsers.keyAt(i);
Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
broadcastIntentLocked(...);
...... }

文件路径:

/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

之后就会开启系统的主程序-Launcher程序,完成系统界面的加载与显示。

文章转载之:

https://www.jianshu.com/p/45cf56172d22

Android的开机启动流程的更多相关文章

  1. Android系统开机启动流程及init进程浅析

    Android系统启动概述 Android系统开机流程基于Linux系统,总体可分为三个阶段: Boot Loader引导程序启动Linux内核启动Android系统启动,Launcher/app启动 ...

  2. Android N 的开机启动流程概述

    原地址:https://blog.csdn.net/h655370/article/details/77727554 图片展示了Android的五层架构,从上到下依次是:应用层,应用框架层,库层,运行 ...

  3. android开机启动流程说明

    android开机启动流程说明 第一步:启动linux 1.Bootloader 2.Kernel 第二步android系统启动:入口为init.rc(system\core\rootdir) 1./ ...

  4. Cocos2d-x3.3RC0的Android编译Activity启动流程分析

    本文将从引擎源代码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,以下是具体分析. 1.引擎源代码Jni.部分Java层和C++层代码分析 watermark/2 ...

  5. linux系统下开机启动流程

    在了解开机启动流程之前,还是得先了解一些磁盘的基本知识.磁盘主要由盘片,机械手臂,磁头,主轴马达构成.盘片就是存储数据的物理单位了.然后盘片上我们可以分成扇区(sector)和柱面(cylinder) ...

  6. Linux 开机启动流程

    Linux的开机启动流程 1.开机BIOS自检                                             --> 检查CPU,硬盘等硬件信息 2.MBR[Major ...

  7. Android process 的启动流程

    Android process 的启动流程 1.android启动时所运行的进程: USER    PID     PPID    VSIZE    RSS    WCHAN         PC   ...

  8. (转)CentOS 7系统详细开机启动流程和关机流程

    CentOS 7系统详细开机启动流程和关机流程 原文:http://blog.csdn.net/yuesichiu/article/details/51350654 名称 bootup - 系统启动流 ...

  9. Linux的开机启动流程

    Linux的开机启动流程 1.开机BIOS自检                                             --> 检查CPU,硬盘等硬件信息 2.MBR[Major ...

随机推荐

  1. desktoplayer.exe病毒及d:\w7rtm\base\wcp\sil\merged\ntu\ntsystem.cpp的解决方案

    1 前言 该病毒,使用360普通杀毒杀不出来,而且会伴随以下问题: a.电脑蓝屏问题[多图] b.fsc/scannow CbS.log d:\w7rtm\base\wcp\sil\merged\nt ...

  2. redis的两种持久化方案

    前言 人生在于折腾系列,网络,多线程等系列博客楼主还在继续折腾也不会放弃.缓存的知识其实并不仅仅在于简单的增删改查,我觉得有必要全面深入的学习一波.记录学习的过程与体悟. RDB 什么是RDB 对re ...

  3. 【转】Why BIOS loads MBR into 0x7C00 in x86 ?

    最近在读Linux的grub的stage1中看到“BIOS执行INT 0x19,加载MBR内容至0x7c00,然后跳转执行”,为什么一定是0x7c00这个地址. 作者刚好在下面推荐了这篇文件,刚好顺手 ...

  4. win中Oracle简易客户端和plsql的配置

    连接数据库有2种方式:在本机安装Oracle数据库或者是安装一个oracle简易客户端 当然,简易客户端跟oracle数据库比较少了一些功能 连接方式: 1)简易连接 sqlplus scott/ti ...

  5. CENTOS安装xwindow

    CentOS6安装图形界面 [root@centos6~]# yum -y install xorg* [root@centos6 ~]# yum -y groupinstall "X Wi ...

  6. 解决Mac下SourceTree每次都让输入密码的问题

    在Mac上操作sourcetree当pull和push时每次都是让输入密码,非常烦人,虽然大概知道是因为SSH什么的问题,但搜索百度也没发现解决办法. 于是乎搜索谷歌,发现如下解决办法. Source ...

  7. Kth Minimum Clique(2019年牛客多校第二场D题+k小团+bitset)

    目录 题目链接 题意 思路 代码 题目链接 传送门 题意 找第\(k\)小团. 思路 用\(bitset\)来标记每个结点与哪些结点直接有边,然后进行\(bfs\),在判断新加入的点与现在有的点是否都 ...

  8. scrapy 改 scrapy-redis

    1.spider 修改 class CgysSpider(scrapy.Spider): name = 'clispider' start_urls = ['https://search.bilibi ...

  9. SpringBoot——IDEA使用 Spring Initializer快速创建项目【四】

    前言 使用Spring Initializer快速创建项目 步骤 首先肯定是打开我们的IDEA的编辑器呀~ 创建项目 File -> New -> Project Spring Initi ...

  10. vector、ArryList、LinkedList的区别与联系

    vector.ArryList.LinkedList的区别与联系 vectory类:底层 采用数组结构算法,使用了线程锁(synchronized),线程安全,但是性能相对ArryList比较低. A ...