本文目录:
(一)整体概述
(二)BootLoader
(三)Kernel初始化
(四)Init初始化介绍
(a)Init.rc
(b)boottanim启动
(c)Surfaceflinger启动
(五)Zygote启动介绍
(a)app_process
(b)AppRuntime
(c)ZygoteInit
(六)SystemServer启动介绍
(a)AMS启动
(b)PackageMS启动
(七)Launcher启动介绍
(a)SystemUI启动
(b)Launcher启动
(八)Log抓取与分析方法
(九)总结及参考
概述:Loader > Kernel > Native > Framework > Application
细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher
Ø Loader层主要包括Boot Rom和Boot Loader;
Ø Kernel层主要是Android内核层,启动0号和1号进程;
Ø Native层主要是包括init进程以及其fork出来的用户空间的守护进程、HAL层、开机动画等;
Ø Framework层主要是AMS和PMS等Service的初始化;
Ø Application层主要指SystemUI、Launcher的启动;
(二)BootLoader
Bootloader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
调用流程:
crt0.S > kmain > arch_init > target_init > apps_init > aboot_init
详细步骤如下:
Ø 在crt0.s中:
n 主要完成CPU初始化,禁用mmu,禁用cache,初始化异常向量表等操作,最后直接跳转到kmain中;
n MTK平台:alps/vendor/mediatek/proprietary/bootable/bootloader/lk/arch/{paltform}/crt0.S
Ø 在kmain方法中
n MTK平台:alps/vendor/mediatek/proprietary/bootable/bootloader/lk/kernel/main.c
n 初始化线程系统 > 初始化mmu,设置异常向量基地址 > 初始化硬件时钟、主板等 > 初始化uart端口 > 内核堆栈初始化(用于kmalloc等函数的内存分配) > 初始化定时器 > 初始化内核定时器 > 判断是否定义ENABLE_NANDWRITE:如果是运行bootstrap2线程;如果不是则在timer_init之后执行bootstrap_nandwrite。
Ø Bootstrap2中执行arch_init > target_init > apps_init:
n arch_init:打印信息;
n target_init:
u 从共享内存中读写xbl提供的pmic信息;
u 初始化spmi总线,用于cpu和pmic通信;
u 初始化ap与rpm通信通道;
u 初始化按键;
u 判断内核是否签名,当使用的是签名的内核时,需要初始化加密解密引擎;
u 判断是从usf还是emmc启动;
u 获取分区表信息;
u 判断电池电压是否过低,过低则进入预充电和tz通信;
u 初始化emmc或ufs中的rpmb用户加解密认证分区;
u 运行keymaster。
n app_init:功能的初始化,并调用aboot_init
Ø aboot_init:在about.c中
n 根据target_is_emmc_boot()判断是否是从emmc存储设备上启动,然后分别获取对应存储设备的页大小和页掩码;
n 取得设备的device_info信息,保存到device变量中;
n 初始化lcd驱动,显示手机开机后的第一幅图片;
n 获取emmc或者flash芯片的产品序列号,最后在启动kernel时通过cmdline中的androidboot.serialno参数传给内核;
n 检查按键判断是进入recovery还是fastboot;
n 检查重启模式;
n 跳转到kernel。
(三)kernel初始化
概述:Loader > Kernel > Native > Framework > Application 细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher |
分为三部分:zImage解压缩、kernel的汇编启动阶段、kernel的C启动阶段。
内核启动引导地址由bootp.lds决定,内核启动执行的第一条代码在head.S文件中,主要功能是实现压缩内核的解压和跳转内核vmlinux内核的入口。
在kernel的C启动阶段可以理解为真正的启动阶段,从head.S中可知,最终调用的是kernel/init/main.c的start_kernel()函数。
在start_kernel()函数中执行了大量的初始化操作,如:
Ø setup_arch():板级初始化等。
Ø sched_init():初始化处理器的可运行队列,设置系统初始化进程,即0号进程;
Ø softirq_init():内核软中断机制初始化函数;
Ø console_init():初始化系统的控制台结构;
Ø rest_init():调用kernel_thread()创建1号内核线程,调用schedule()函数切换当前进程,在调用该函数之前,Linux系统中只有两个进程,即0号进程init_task和1号进程kernel_init,其中kernel_init进程也是刚创建的。调用该函数后,1号进程将会执行。
Kernel进程:
Linux下有3个特殊的进程:
Ø idle(swapper)进程,由系统自动创建,运行在内核态:
其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为父进程。
(四)Init初始化介绍
概述:Loader > Kernel > Native > Framework > Application 细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher |
Init进程是Linux内核启动后创建的第一个用户空间的进程,init在初始化工程中会启动很多重要的守护进程。
代码位于:alps/system/core/init/init.cpp
此外,该文件的main函数入口也是ueventd和watchdog守护进程的入口,通过参数控制。
默认情况下,一个进程创建出来的文件和文件夹属性都是022,使用umask()函数能设置文件属性的掩码,参数为0 时表示进程创建的文件属性是0777。接着创建一些基本的目录包括dev, proc, sys,等,同时把分区mount到对应的目录。
Init进程会调用property_init创建一个共享区域来存储属性值,初始化完后,获取kernel传过来的cmdline去设置一些属性,然后初始化SELinux和安全上下文,接着会通过property_load_boot_defaults去加载default.prop等文件初始化系统属性。
初始化属性和SELinux后,接着解析init.rc的文件内容,通过init.rc相关语法配置和启动进程以及启动的顺序。
Main()函数最后会进入一个死循环,每次循环都会去调用ExecuteOneCommand执行命令列表中的一条命令,如果服务挂了还会调用restart_processes重启服务。
Init进程初始化系统后,会化身为守护进程来处理子进程的死亡信号,修改属性的请求和组合键事件。
l 【Init.rc】
该文件位于: alps/system/core/rootdir/init.rc
在init.cpp中,启动init.rc各个阶段的顺序是early-init > init > late_init, 在late_init中又会去触发其他阶段的启动,所以各个阶段在init中启动的顺序如下:
early_init > init > late_init > early-fs > post-fs > late_fs > post-fs-data > zygote-start > boot > on property
各阶段的作用分别是:
Ø on early-init:设置init进程以及它创建的子进程的优先级,设置init进程的安全环境;
Ø on init:设置全局环境,为cpu accounting创建cgroup(资源控制)挂载点;
Ø on fs:挂载mtd分区;
Ø on post-fs:改变系统目录的访问权限
Ø on post-fs-data:改变/data目录以及它的子目录的访问权限
Ø on boot:基本网络的初始化,内存管理等等
Ø service servicemanager:启动系统管理器管理所有的本地服务,比如位置、音频、Shared preference等
Ø service zygote:启动zygote作为应用进程
在boot阶段会启动class为hal和core的服务。
Init.rc中支持的命令实现在builtins.cpp中,具体语法可参考文件:alps/system/core/init/READMe.md。
l 【bootanim启动】:bootanim意思是boot animation翻译为“开机动画”
Bootanim.rc中定义了bootanim属于core服务,但是设置了disable说明bootanim不是自启动的服务,需要别的服务进行唤醒。
l 【surfaceflinger启动】flinger翻译为“护圈”
代码里搜索bootanim,可以看到是surfaceflinger服务将bootanim启动,surfaceflinger属于core服务,自启动服务,在init进程的on boot阶段会启动surfaceflinger,surfaceflinger最后会启动startPropertySetThread从而启动bootanim。
surfaceFlinger服务的main函数入口在main_surfaceflinger,主要操作有:
Ø 启动Hidl服务,主要是DisplayService
Ø 启动线程池;
Ø 初始化surfaceflinger和GpuService注册到serviceManager;
Ø 启动surfaceFlinger线程。
启动函数在开机过程中只会执行一次。
(五)Zygote启动介绍
概述:Loader > Kernel > Native > Framework > Application 细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher |
在init执行过程中,在on late-init阶段,会trigger[引发] zygote-start(如下图示) , on zygote-start会根据当前的加密状态选择启动服务。
(六)SystemServer启动介绍
SystemServer主要从zygoteInit.java文件的 forkSystemServer()函数开始分析,主要是设置参数,然后调用zygote的forkSystemServer方法,再判断是否有SecondaryZygote启动,有则等待其启动,无则返回。
Zygote的forkSystemServer方法主要是调用了native方法nativeForkSystemServer,在native层进行fork动作,并设置pid, gid, seLinux安全上下文等,最后启动com.android.server.SystemServer。
SystemServer是一个Java类,从main函数入口分析,主要调用run方法,工作是:
Ø 调整时间,如果系统时间比1970要早,调整到1970;
Ø 设置语言;
Ø 调整虚拟机堆内存大小和内存利用率;
Ø 初始化Looper为mainLooper;
Ø 装载库libandroid_server.so;
Ø 初始化系统Context;
Ø 创建SystemServiceManager负责系统Service启动;
Ø 创建和启动Java服务,包含AMS,WMS,PMS,IMS等,主要分在三个函数中进行的;
n 启动引导程序服务startBootstrapServices():
u 会初始化一个watchdog实例,并启动watchdog子线程;
u 读取系统配置,初始化线程池,最大32个;
u 平台兼容性设置platformCompat;
u 启动Installer,为了有权限能创建重要的一些目录,如/data/user等;
u 为了获取设备id,启动DeviceIdentifiersPolicyService;
u UriGrantsManagerService;
u AMS;
u 在PMS之前要启动DataLoaderManagerService,IncrementalService;
u 启动pMS,powerManagerService;
u 启动ThermalManagerService;
u 初始化powerManagerService;
u 启动RecoverySystemService;
u 到此为止,OS启动和运行的基本要素基本集齐,注册一个healthObserver,为的是如果陷入runtime restart loop时,可以有一个救援队(rescue party)来救援,watchdog有监控;
u 启动ledService;
u 启动助手服务SidekickService;
u 启动DisplayManagerService;
u 启动PMS, packageManagerService,有watchdog监控;
u PMS启动后,注册二进制文件报告器,该报告器会捕捉所有由系统加载的二进制文件,这些二进制文件会被BackgroundDexOptService优化;
u 至此,完成PMS启动;
u 再启动UserManagerService,至此,以上所有服务都是由systemServiceManager调用startService()方法启动;
u 接下来,将ActivityManagerService设置为系统进程,并启动。
u 初始化watchdog,并用ActivityManager实例启动,并开始监听reboot。
n 启动核心服务startCoreServices()
u 启动系统配置服务systemConfigService;
u 启动电池服务batteryService,如果跟踪电池电量,需要LightService;
u 启动跟踪应用使用状态服务UsageService;
u 启动webViewUpdateService, CacheDeviceStateService跟踪和缓存设备状态, BinderCallsStateService跟踪CPU在binder 调用的时间, LooperStatesService跟踪在handlers中的传递消息的时间, RollbackManagerService管理apk的回滚,bugreportorMS捕捉bugreport的服务, GPUService 是GPU和GPU驱动的服务。
n 启动其他服务OtherServices(),下面列出主要的几项:
u DropBoxManagerService,主要记录errors和log;
u 闹钟alarmManagerService, IMS (InputManagerService), WMS (WindowManagerService)……
u 在所有的与显示相关的服务都启动完之后,make display ready;
u 接下来启动一些生物识别相关的服务;
u 启动完成后,开始启动app进程,并且systemServiceManager.startBootPhase()各种服务,各种服务ready;
u Ready之后,启动各个服务的第三方代码,让各个服务running:
Ø 调用Looper.loop(),进入处理消息的循环。
SystemServer主要从zygoteInit.java文件的 forkSystemServer()函数开始分析,主要是设置参数,然后调用zygote的forkSystemServer方法,再判断是否有SecondaryZygote启动,有则等待其启动,无则返回。
Zygote的forkSystemServer方法主要是调用了native方法nativeForkSystemServer,在native层进行fork动作,并设置pid, gid, seLinux安全上下文等,最后启动com.android.server.SystemServer。
SystemServer是一个Java类,从main函数入口分析,主要调用run方法,工作是:
Ø 调整时间,如果系统时间比1970要早,调整到1970;
Ø 设置语言;
Ø 调整虚拟机堆内存大小和内存利用率;
Ø 初始化Looper为mainLooper;
Ø 装载库libandroid_server.so;
Ø 初始化系统Context;
Ø 创建SystemServiceManager负责系统Service启动;
Ø 创建和启动Java服务,包含AMS,WMS,PMS,IMS等,主要分在三个函数中进行的;
n 启动引导程序服务startBootstrapServices():
u 会初始化一个watchdog实例,并启动watchdog子线程;
u 读取系统配置,初始化线程池,最大32个;
u 平台兼容性设置platformCompat;
u 启动Installer,为了有权限能创建重要的一些目录,如/data/user等;
u 为了获取设备id,启动DeviceIdentifiersPolicyService;
u UriGrantsManagerService;
u AMS;
u 在PMS之前要启动DataLoaderManagerService,IncrementalService;
u 启动pMS,powerManagerService;
u 启动ThermalManagerService;
u 初始化powerManagerService;
u 启动RecoverySystemService;
u 到此为止,OS启动和运行的基本要素基本集齐,注册一个healthObserver,为的是如果陷入runtime restart loop时,可以有一个救援队(rescue party)来救援,watchdog有监控;
u 启动ledService;
u 启动助手服务SidekickService;
u 启动DisplayManagerService;
u 启动PMS, packageManagerService,有watchdog监控;
u PMS启动后,注册二进制文件报告器,该报告器会捕捉所有由系统加载的二进制文件,这些二进制文件会被BackgroundDexOptService优化;
u 至此,完成PMS启动;
u 再启动UserManagerService,至此,以上所有服务都是由systemServiceManager调用startService()方法启动;
u 接下来,将ActivityManagerService设置为系统进程,并启动。
u 初始化watchdog,并用ActivityManager实例启动,并开始监听reboot。
n 启动核心服务startCoreServices()
u 启动系统配置服务systemConfigService;
u 启动电池服务batteryService,如果跟踪电池电量,需要LightService;
u 启动跟踪应用使用状态服务UsageService;
u 启动webViewUpdateService, CacheDeviceStateService跟踪和缓存设备状态, BinderCallsStateService跟踪CPU在binder 调用的时间, LooperStatesService跟踪在handlers中的传递消息的时间, RollbackManagerService管理apk的回滚,bugreportorMS捕捉bugreport的服务, GPUService 是GPU和GPU驱动的服务。
n 启动其他服务OtherServices(),下面列出主要的几项:
u DropBoxManagerService,主要记录errors和log;
u 闹钟alarmManagerService, IMS (InputManagerService), WMS (WindowManagerService)……
u 在所有的与显示相关的服务都启动完之后,make display ready;
u 接下来启动一些生物识别相关的服务;
u 启动完成后,开始启动app进程,并且systemServiceManager.startBootPhase()各种服务,各种服务ready;
u Ready之后,启动各个服务的第三方代码,让各个服务running:
Ø 调用Looper.loop(),进入处理消息的循环。
(七)Launcher启动介绍
后续持续更新中,尽情期待