接触Android也有几年了,最近想对Android系统的启动流程做一个完整的分析总结,以便后续学习 。
(1)Android架构介绍
我们先来看一下Android文档给的一份系统架构图。

从以上可以看到,Android大体上被分为4个模块(Kernel,Hal/Native,Java Framework,Apps)。
接下来我们从系统启动的角度来看两种更加详细的图。
从上图可以看出,系统启动我们底层将其主要分为三个部分。
- 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为父进程。
以上进程可以通过如下图片展示:
可通过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 进程。