Android的开机启动流程概述
前言
做Android开发已经有些时日了,一直想系统而深入的去了解Android的启动流程。前前后后花费了很大的功夫去查阅和研究,所以想把微薄的成果记录下来,留做日后回顾。顺便呢,也分享给大家。必定会有很多的疏漏和谬误,欢迎大家在评论区补充和指正。当然,文中不免会有一些摘抄引用,如有侵权,可以联系本人处理。
Android的开机启动流程概述
我相信,只要接触过Android的人,都会看过下面这张图。
Android层次架构图(图片来源于网络,侵权请联系我!)
图片清晰地展示了Android的五层架构,从上到下依次是:应用层,应用框架层,库层,运行时层以及Linux内核层
。而Android的启动流程是自下而上的,大体上分为三个阶段:1. BootLoader引导;2. 启动Kernel;3. 启动Android
。如果再细化一点,则如下图所示:
(图片来源于网络,侵权请联系我!)
接下来我来稍微具体的描述一下这个过程。
Step 1. Boot Rom
当长按开机键的时候,引导芯片开始从固化在ROM的预设代码开始执行。然后加载引导程序到RAM。
Step 2. BootLoader
BootLoader
,又称为引导程序
。它是在操作系统运行之前运行的一段程序,是运行的第一个程序。主要有检查RAM,初始化硬件参数等功能,当然它的最终目的是把操作系统给拉起来。
文件路径: /bootable/bootloader/legacy/
BootLoader的主要功能分析,我摘抄过来,一起看看:
其实Bootloader主要的必须的作用只有一个:就是把操作系统映像文件拷贝到RAM中去,然后跳转到它的入口处去执行,我们称之为启动加载模式,该过程没有用户的介入,是它正常工作的模式。它的步骤如下:
Stage1:
硬件设备初始化。为stage2的执行及随后内核的执行准备好基本的硬件环境
为加载stage2 准备ram空间。为了获得更好的执行速度,通常吧stage2加载到ram中执行
复制stage2的代码到ram中
设置好堆栈
跳转到stage2的c程序入口
Stage2:
初始化本阶段要使用的硬件设备
检测系统内存映射
将内核映像和根文件系统映像从flash读到ram中
为内核设置启动参数
调用内核
(摘自:http://www.cnblogs.com/little221/archive/2012/12/06/2804387.html)
Step 3. 初始化Kernel
接着就进入C语言编写的结构无关的代码了。这个入口的函数是start_kernel
函数。start_kernel
函数完成了内核的大部分初始化工作。实际上,可以将start_kernel
函数看做内核的main函数。start_kernel
函数执行到最后调用了reset_init
函数进行后续的初始化。 reset_init
函数最主要的任务就是启动内核线程kernel_init
。kernel_init
函数将完成设备驱动程序的初始化,并调用init_post
函数启动用户空间的init进程。到init_post
函数为止,内核的初始化已经基本完成。
文件路径:/kernel_imx/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); }......}
文件路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
Step 6. SystemServer进程
前面ZygoteInit.java
里面通过startSystemServer()
fork出了SystemServer进程
,这个进程在整个的Android中非常重要,它和Zygote进程
一样,是Android Framework层的两大重要进程。系统里面重要的服务都是在这个进程里面开启的,例如AMS
, WindowsManager
, PackageManagerService
等等都是由这个SystemServer
fork出来的。在下面SystemServer
的代码中可以看到,这些服务如何开启和具体开启了哪些服务。
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() {...}// 启动其他服务。}
文件路径:/frameworks/base/services/java/com/android/server/SystemServer.java
从上面SystemServer
代码中可以看出,在SystemServer进程开启的时候,就会初始化ActivityManagerService
。同时,会加载本地系统的服务库,调用createSystemContext()创建系统上下文,创建ActivityThread及开启各种服务等等。
Step 7. Home Activity
上面ActivityManagerService
开启之后,会调用finishBooting()
,完成引导过程。同时发送开机广播“ACTION_BOOT_COMPLETED”
。
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程序,完成系统界面的加载与显示。
至此,Android的开机启动流程大概就完成了。
参考资料
- [嵌入式]Bootloader的作用
- 读核笔记-内核初始化-从start_kernel到init
- Android4.4的init进程
- Android启动过程深入解析
- 杂谈——Android从启动到程序运行发生的事情
更多相关文章
- Android进程保活-自“裁”或者耍流氓
- Android进程学习
- Android跨进程通信IPC之15——Binder之native层C++篇--注册服务
- android使程序进程不被LMK杀死
- 通过ddmlib杀死某个android进程的方法
- 杀掉指定进程
- 编译android内核源码