当我们按下电源键,Android 究竟做了些什么?

栏目: IOS · Android · 发布时间: 5年前

内容简介:相信我们对Android系统都不陌生,而Android系统博大精深,被各种各样的智能设备承载的同时,我们会否好奇过,如此复杂的Android究竟是怎么运作起来的呢?借本文给大家分享,笔者对Android 系统启动流程的整体理解~下面是Android启动的核心步骤流程图,看文字的时候,记得回来对照图来理解喔,希望阅读全文后,回观流程图,会有恍然大悟的感觉,那么文章的目的就达到啦~系统从 ROM 中开始启动,加载引导程序到 RAM ,然后执行。

相信我们对Android系统都不陌生,而Android系统博大精深,被各种各样的智能设备承载的同时,我们会否好奇过,如此复杂的Android究竟是怎么运作起来的呢?借本文给大家分享,笔者对Android 系统启动流程的整体理解~

hi, I'm Android

现在,按下电源键

下面是Android启动的核心步骤流程图,看文字的时候,记得回来对照图来理解喔,希望阅读全文后,回观流程图,会有恍然大悟的感觉,那么文章的目的就达到啦~

整体流程

一、启动电源及系统启动

系统从 ROM 中开始启动,加载引导程序到 RAM ,然后执行。

二、引导程序

引导程序是 Android 操作系统开始运行前的一个小程序,因此它需要针对特定主板与芯片, 并不是 Android 操作系统的一部分 。引导程序是 OEM 厂商或运行商进行 加锁、限制 的地方。

1 两个阶段

  1. 检测外部 RAM 以及为第二阶段加载程序
  2. 设置网络、内存等,搭建内核运行环境(为了达到特殊目的时,引导程序可以根据配置参数或者输入数据来设置内核)

2 引导程序的加载器

Android引导程序可以在\bootable\bootloader\legacy\usbloader找到,传统的加载器包含的两个文件:

  1. init.s 初始化 堆栈 ,清零 BSS段 ,会调用 main.c 中的 _main()函数 ( bss segment: 通常是指用来存放程序中 未初始化的全局变量 的一块内存区域;BSS - Block Started by Symbol。BSS段属于静态内存分配)
  2. main.c 初始化硬件,创建 linux 标签

三、内核启动

Android 内核启动方式类似桌面 linux,主要步骤:

1. 设置缓存

2. 被保护存储器

3. 计划列表

4. 加载驱动

当内核完成系统设置,接下来即将启动系统的第一个进程 -- init 进程

四、init 进程

作为 Android 系统的第一个进程,其PID为0,通过解析 init.rc 脚本 来构建出系统初始运行形态,这一阶段中,“Android” logo 会显示出来

(系统中, 大多数系统服务程序 都是在 该脚本 中描述并被相继启动的)

init.rc 由 4种类型声明 组成: Actions、Commands、Services、Options

  • Actions: 响应某事件的过程。当“trigger”所描述的触发事件产生时,则依次执行各种“command” 源码角度: 系统会对 init.rc 中各 “trigger” 进行匹配,当发现符合条件的 Action,就将它加入 “命令执行队列” 尾部(除非 Action 已存在队列中),然后系统再对这些命令按顺序进行。on <trigger> ##触发条件 <command1> ##执行命令 <command2> ##可执行多个命令 ...
  • Commands: 命令将在所属事件发生时被一个个执行
  • Services: 可执行程序,它们在特定选项的约束下会被 init 程序运行或者重启(Service 可以在配置中指定 是否需要退出重启 ,那么,当 Service 出现异常 crash 时,可有机会复原)service <name><pathname> [<argument>]* <option> <option>
  • Options: 对 service 的约束选项

五和六、 ServiceManager、Zygote、SystemServer

科普:Daemons - 守护进程

init进程通过解析 init.rc 来陆续启动其他关键的系统服务进程,其中最重要的是 ServiceManager、Zygote 和 SystemServer 三者,下面我们逐一解析:

1 ServiceManager -- Binder 机制支撑者

概述:ServiceManager 是 Binder 机制 中的 支撑者 ,负责某 Binder 服务注册信息 到底层 Binder 驱动分配的值 解析。

ServiceManager 由 init 进程解析 rc 脚本时启动,属于 core 类 ,其他同类进程包括:uenetd、console、adbd等。根据 core 组的特性,这些进程会 同时启动或停止 。另外,ServiceManager 配置含有 critical 属性 ,这意味着它是 系统关键进程 (如果进程不幸在4分钟内异常退出超过4次,设备将重启并进入还原模式)。当 ServiceManager 每次重启时,其他关键进程:zygote、media、surfaceflinger 等也会被 restart。

2. Zygote -- “孕育”新线程与进程

Android 中大多数应用进程与系统进程都是通过 Zygote 来生成的。Zygote 同样由 init 解析 rc 脚本时启动,属于 main 类 ,同属 main 类的系统进程有:netd、debuggerd、rild等。Zygote并不是处于独立的程序中的,它所在程序名为 “app_process” ,观察 app_process 主函数实现知道,如果 init.rc 中指定了 --zygote选项,app_process 接下来将启动 “ZygoteInit” ,并传入 “start-system-server” ,这样,ZygoteInit 就会运行在虚拟机上(Dalvik VM)上了。

  • ZygoteInit 函数有两项重要工作
  • 预装载各种系统类
  • 搭建 SystemServer 环境,并启动 SystemServer(大部分的 Android 系统服务都在其中,由 Java 编写)
  • ZygoteInit 流程总结摘自:Gityuan -- Android 系统启动-Zygote 篇
    1. 解析init.zygote.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法;
    2. 调用AndroidRuntime的startVM()方法创建虚拟机,再调用startReg()注册JNI函数;
    3. 通过JNI方式调用ZygoteInit.main(),第一次进入Java世界;
    4. registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求;
    5. preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高ap启动效率;
    6. zygote完毕大部分工作,接下来再通过startSystemServer(),fork得力帮手system_server进程,也是上层framework的运行载体。
    7. zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。

ZygoteInit 结束后,开机Logo就出来了。

(注意:这里并不包括开机动画,而是开机前 “Android” Logo 出现的那个画面,开机动画出现之前还需要进行各种加载,开机动画是在“Android” Logo 出现之后才播放的)

3. SystemServer -- 大部分 Android 系统服务所在地

SystemServer 是 Android 进入 Launcher 前的最后准备,它提供了众多的由“Java”语言编写的 系统服务

如果 init.rc 中为 zygote 指定启动参数 --start-system-server,那么 ZygotyeInit 就会调用 startSystemServer 来进入 SystemServer。

  • startSystemServer函数解析:
  • 首先 ZygoteInit 通过 Zygote.forkSystemServer 来生成一个新的线程(fork),用于承载各种 系统服务 。(源码角度:Zygote 内部由 Native 函数 Dalvik_dalvik_system_Zygote_forkSystemServer 来进一步实现,最终调用底层接口的 fork 接口 来实际产生进程)
  • 根据fork特性,子进程与父进程将获得 相同的代码环境pid为0为子进程 ,否则为父进程;如果是 前者 ,则进一步调用 handleSystemServerProcess(parseArgs) 函数来完成最核心的工作 -- “启动各系统服务” (源码角度:handleSystemServerProcess 方法将 startSystemServer 中的 parsedArgs.remainingArgs 参数传给 RuntimeInit.zygoteInit ,后者又调用 nativeZygoteInit 函数
  • nativeZygoteInit 调用后,接着,三个重要的 static 函数就要被执行了: init1 - 完成本地Service(SurfaceFlinger、AudioFlinger等)启动,完成后调用 init2init2 - 新建一个新的带 Looper 的线程 ServerThread来启动 Java层各 Service

后语

上面对 Android 系统启动做了一个简述,意在给大家展现一个整体流程,其中每个环节涉及的知识点只是浅浅掠过,笔者也尚在学习与探索中,希望在后续再作详细分析。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JSP网站开发四“酷”全书

JSP网站开发四“酷”全书

万峰科技 / 电子工业出版社 / 2005-9 / 49.00元

本书以JSP为开发语言,选取当前最流行、最具代表性的4类网站:新闻站点、论坛、电子商城和博客(Blog)系统为例,详细介绍了使用JSP开发网站的核心技术。掌握了本书所举4类网站的开发技术,将帮助你成为网站开发的“全能冠军”。 本书结合作者多年在网站系统开发方面的经验,从系统的需求分析开始,确定系统的流程与设计,到模块的划分,再到数据加结构的设计,最后开始每个模块编程开发,贯穿了网站开......一起来看看 《JSP网站开发四“酷”全书》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具