天天看点

Android系统启动流程完整分析(一)

接触Android也有几年了,最近想对Android系统的启动流程做一个完整的分析总结,以便后续学习 。

(1)Android架构介绍

我们先来看一下Android文档给的一份系统架构图。

Android系统启动流程完整分析(一)

从以上可以看到,Android大体上被分为4个模块(Kernel,Hal/Native,Java Framework,Apps)。

接下来我们从系统启动的角度来看两种更加详细的图。

Android系统启动流程完整分析(一)
Android系统启动流程完整分析(一)

从上图可以看出,系统启动我们底层将其主要分为三个部分。

  • Android设备上电后,首先会从处理器片上ROM的启动引导代码开始执行,片上ROM会寻找Bootloader代码,并加载到内存。
  • Bootloader开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存。
  • Linux内核开始启动,初始化各种软硬件环境,加载驱动程序,挂载根文件系统,并执行init程序,由此开启Android的世界。

每一层的作用不做介绍,这里主要讲涉及的镜像有boot.img、system.img、vendor.img、recovery.img、userdata.img、cache.img,与平台相关的镜像有lk.bin(MTK)、preloader.img(MTK)、logo.bin(MTK)等,通常来说,修改kernel层通常编译boot.img即可,修改Framework层或Native层主要是编译system.img。

(2)Android启动概述

概述:Loader > Kernel > Native > Framework > Application

细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher

  • Loader层主要包括Boot Rom和Boot Loader
  • Kernel层主要是Android内核层
  • Native层主要是包括init进程以及其fork出来的用户空间的守护进程、HAL层、开机动画等
  • Framework层主要是AMS和PMS等Service的初始化
  • Application层主要指SystemUI、Launcher的启动

kernel的C启动阶段可以理解为真正的启动阶段,Linux下有3个特殊的进程,idle(swapper)进程(PID = 0)、init进程(PID = 1)和kthreadd(PID = 2)。

  • idle(swapper)进程由系统自动创建,运行在内核态

    idle进程其pid=0,其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。

    完成加载系统后,演变为进程调度、交换,常常被称为交换进程。

  • init进程由idle通过kernel_thread创建,在内核空间完成初始化后,加载init程序,并最终转变为用户空间的init进程

    由0进程创建,完成系统的初始化,是系统中所有其它用户进程的祖先进程。

    Linux中的所有进程都是有init进程创建并运行的。首先Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。

    在系统启动完成后,init将变为守护进程监视系统其他进程。

  • kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间,负责所有内核线程的调度和管理

    它的任务就是管理和调度其他内核线程kernel_thread,会循环执行一个kthreadd的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread,当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程。

以上进程可以通过如下图片展示:

Android系统启动流程完整分析(一)

可通过ps -A(查询进程)和ps -T -p xxx(查询xxx进程中的线程数)命令来查看Android系统相关进程。

//ps -A
USER           PID  PPID     VSZ    RSS WCHAN            ADDR S NAME                       
root             1     0   68444   3052 0                   0 S init
root             2     0       0      0 0                   0 S [kthreadd]

root             3     2       0      0 0                   0 I [rcu_gp]
root             4     2       0      0 0                   0 I [kworker/0:0]
root             5     2       0      0 0                   0 I [kworker/0:0H]
root            13     2       0      0 0                   0 S [watchdog/0]
root            14     2       0      0 0                   0 S [cpuhp/0]
root            15     2       0      0 0                   0 S [cpuhp/1]
...

root           459     1   34620    872 0                   0 S init
root           461     1   36156   3544 0                   0 S ueventd
system         478     1   29772   1532 0                   0 S servicemanager
system         479     1 2132152   3036 0                   0 S hwservicemanager
root           609     1 2487788   5064 0                   0 S netd
root           610     1 5495940  86496 0                   0 S zygote64
root           611     1 1813256  69932 0                   0 S zygote
root           626     1   30980   2292 0                   0 S healthd
audioserver    685     1 2396272   8056 0                   0 S audioserver
system         686     1   86580   2332 0                   0 S displayservice
system         691     1 3022164  23440 0                   0 S surfaceflinger
cameraserver   782     1   43032   4820 0                   0 S cameraserver
media          805     1  183008   5824 0                   0 S mediaserver
system        1268   775 10563968 372340 0                  0 S system_server
shell         7278     1  108560   3672 0                   0 S adbd
shell         7279     1   77376    776 0                   0 S hdbd
           
root           610     1 5495940  86496 0                   0 S zygote64
system        1695   610 6086164 108188 0                   0 S com.android.settings
u0_a26        1719   610 7740036 246752 0                   0 S com.android.systemui
radio         2138   610 6634868 104272 0                   0 S com.android.phone
u0_a22        3363   610 6435100 121448 0                   0 S com.android.gallery3d
nfc           3447   610 5734092  61980 0                   0 S com.android.nfc
u0_a11        4170   610 5711704  68868 0                   0 S android.process.media
u0_a18        4303   610 6470168 140176 0                   0 S com.google.android.gms
...
           
//ps -T -p xxx
USER           PID   TID  PPID     VSZ    RSS WCHAN            ADDR S CMD            
system        1268  1268   610 10943004 318288 0                  0 S system_server
system        1268  1342   610 10943004 318288 0                  0 S android.display
system        1268  1343   610 10943004 318288 0                  0 S android.anim
system        1268  1347   610 10943004 318288 0                  0 S watchdog
system        1268  1364   610 10943004 318288 0                  0 S ActivityManagerService
system        1268  1412   610 10943004 318288 0                  0 S PowerManagerService
system        1268  1427   610 10943004 318288 0                  0 S PackageManagerService
system        1268  1517   610 10943004 318288 0                  0 S SensorService
system        1268  1535   610 10943004 318288 0                  0 S AlarmManager
system        1268  1571   610 10943004 318288 0                  0 S WifiService
system        1268  2212   610 10943004 318288 0                  0 S SoundPool
...
           

当 Linux 内核启动后会初始化各种软硬件环境,加载驱动程序,挂载根文件系统,Linux 内核加载的最后阶段会启动执行第一个用户空间进程 init 进程。

继续阅读