Android9 Pie
1 概览
Android开机流程,从init
进程开始到home
App启动,如下面的流程图所示。
2 流程
2.1 init
2.1.1 简介
Android基于Linux,系统中第一个进程为init进程,一切都从init进程开始。
开机通电后,从SoC ROM
的固定位置开始执行,加载BootLoader
到RAM
,然后初始化Linux Kernel
,启动用户空间的init进程,进程ID为1
,父进程ID为0
。同时还启动一个kthreadd内核守护进程,进程ID为2
,父进程ID也为0
,这里对kthreadd不作过多介绍。
init进程会fork
一系列子进程,如常见的zygote
进程,而zygote
进程是sysemserver
进程、systemui
、home
等App的父进程。
2.1.2 两个阶段
init相关源码目录:
system/core/init
从Android.mk
和Android.bp
可以看出,init包括两个阶段,init_first_stage
和init_second_stage
。
init_first_stage的main函数位于init_first_stage.cpp
,首先初始化文件系统,然后通过syscall
来reboot bootloader,最后通过execv
来执行/system/bin/init
。
init_second_stage的main函数位于main.cpp
,具体实现为libinit
静态库的init.cpp
中的main函数,首先初始化属性系统,然后设置selinux
,接着通过epoll
和socket
启动属性服务,后面是通过ActionManager
和ServiceList
分析init.rc
、fork一系列进程,最后通过epoll
进入while(true)
。
2.1.3 init.rc
Android中有很多的init.rc
,由init进程解析。init.rc有其特有的语法格式,包括action
、command
、service
、option
、import
五种类型,详细用法可参照system/core/init/README.md
。
首先从system/core/rootdir/init.rc
开始,导入了其它文件:
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
最前面的是early-init
,做一些简单的配置工作,启动ueventd
:
on early-init
# Set init and its forked children's oom_adj.
write /proc/1/oom_score_adj -1000
xxx
start ueventd
接着是init
,同样是做一些文件系统相关的初始化工作,启动logd
、servicemanager
等:
on init
sysclktz 0
xxx
# Start logd before any other services run to ensure we capture all of their logs.
start logd
# Start essential services.
start servicemanager
start hwservicemanager
start vndservicemanager
servicemanager是一个很重要的进程,是Binder
的基础。
接着是late-init
,做一些文件系统相关的工作,启动zygote
等核心系统服务:
# Mount filesystems and start core system services.
on late-init
trigger early-fs
xxx
# Now we can start zygote for devices with file based encryption
trigger zygote-start
xxx
trigger early-boot
trigger boot
除了上面提到的,还涉及许多其它的内容。
2.2 zygote
2.2.1 init.rc
zygote
也有自己的init.rc,有如下几个版本:
system/core/rootdir/init.zygote32_64.rc
system/core/rootdir/init.zygote32.rc
system/core/rootdir/init.zygote64_32.rc
system/core/rootdir/init.zygote64.rc
以zygote64为例,内容如下:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
可以看出,zygote由app_process
启动,同时还会启动systemserver
,创建用于zygote和systemserver通信的socket
。
2.2.2 app_process
app_process
源码位置:
frameworks/base/cmds/app_process
实现通过类AppRuntime
完成,包括VmCreated
、Started
、ZygoteInit
、Exit
四个阶段:
class AppRuntime : public AndroidRuntime
{
public:
virtual void onVmCreated(JNIEnv* env) {}
virtual void onStarted() {}
virtual void onZygoteInit() {}
virtual void onExit(int code) {}
};
在main函数的最后,启动Java类ZygoteInit
:
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
2.2.3 ZygoteInit
ZygoteInit
相关的有如下几个文件:
frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
frameworks/base/core/java/com/android/internal/os/ZygoteSecurityException.java
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
frameworks/base/core/java/com/android/internal/os/Zygote.java
frameworks/base/core/java/com/android/internal/os/WebViewZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteConnectionConstants.java
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
frameworks/base/core/java/android/webkit/WebViewZygote.java
frameworks/base/core/java/android/os/ChildZygoteProcess.java
frameworks/base/core/java/android/os/ZygoteProcess.java
下面来看一下ZygoteInit.java中做了哪些事情。
- 创建ZygoteServer
- 开启DDMS
- preload Class、Resource、HAL、OpenGL、SO、TextResources等
- 通过ZygoteHooks请求Dalvik虚拟机执行gc、finalize
- fork systemserver (native实现)
- 进入ZygoteServer的select loop
2.3 systemserver
2.3.1 简介
systemserver
源码:
frameworks/base/services/java/com/android/server/SystemServer.java
systemserver启动后,分阶段启动一些服务,如常见的PMS
、AMS
、WMS
、IMS
等,这些服务由ServiceManager
进行管理。
2.3.2 system ready
随后在AMS的systemReady中启动systemui
:
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(() -> {
xxx
traceBeginAndSlog("StartSystemUI");
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
traceEnd();
xxx
}, BOOT_TIMINGS_TRACE_LOG);
static final void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
接着启动home
:
startHomeActivityLocked(currentUserId, "systemReady");
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
// For ANR debugging to verify if the user activity is the one that actually
// launched.
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
mActivityStartController.startHomeActivity(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
至此,home即launcher启动完毕。
2.3.3 boot completed
最后,系统会发送广播BOOT_COMPLETED
。
2.4 App
2.4.1 systemui
systemui
代码位置:
frameworks/base/packages/SystemUI
systemui是Android的系统界面,提供了各种各样的服务,详见如下配置文件:
SystemUI/res/values/config.xml
<!-- SystemUI Services: The classes of the stuff to start. -->
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.Dependency</item>
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.SystemBars</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
<item>com.android.systemui.keyboard.KeyboardUI</item>
<item>com.android.systemui.pip.PipUI</item>
<item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
<item>@string/config_systemUIVendorServiceComponent</item>
<item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
<item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>
<!-- SystemUI vender service, used in config_systemUIServiceComponents. -->
<string name="config_systemUIVendorServiceComponent" translatable="false">com.android.systemui.VendorServices</string>
2.4.2 home
home即launcher,原来的名称是Home,现在为Launcher2、Launcher3,代码目录:
packages/apps/Launcher2
packages/apps/Launcher3
Android中有多个home,不过在makefile中通过编译选项覆盖,如下Launcher3中的makefile,编译时覆盖了Home和Launcher2:
packages/apps/Launcher3/Android.mk
LOCAL_OVERRIDES_PACKAGES := Home Launcher2