Android9 Pie

  • 1 概览
  • 2 流程
  • 2.1 init
  • 2.1.1 简介
  • 2.1.2 两个阶段
  • 2.1.3 init.rc
  • 2.2 zygote
  • 2.2.1 init.rc
  • 2.2.2 app_process
  • 2.2.3 ZygoteInit
  • 2.3 systemserver
  • 2.3.1 简介
  • 2.3.2 system ready
  • 2.3.3 boot completed
  • 2.4 App
  • 2.4.1 systemui
  • 2.4.2 home


1 概览

Android开机流程,从init进程开始到homeApp启动,如下面的流程图所示。


android开机充电模块流程 android 开机流程_Android


2 流程

2.1 init

2.1.1 简介

Android基于Linux,系统中第一个进程为init进程,一切都从init进程开始。
开机通电后,从SoC ROM的固定位置开始执行,加载BootLoaderRAM,然后初始化Linux Kernel,启动用户空间的init进程,进程ID为1,父进程ID为0。同时还启动一个kthreadd内核守护进程,进程ID为2,父进程ID也为0,这里对kthreadd不作过多介绍。
init进程fork一系列子进程,如常见的zygote进程,而zygote进程是sysemserver进程、systemuihome等App的父进程。

2.1.2 两个阶段

init相关源码目录:

system/core/init

Android.mkAndroid.bp可以看出,init包括两个阶段,init_first_stageinit_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,接着通过epollsocket启动属性服务,后面是通过ActionManagerServiceList分析init.rc、fork一系列进程,最后通过epoll进入while(true)

2.1.3 init.rc

Android中有很多的init.rc,由init进程解析。init.rc有其特有的语法格式,包括actioncommandserviceoptionimport五种类型,详细用法可参照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,同样是做一些文件系统相关的初始化工作,启动logdservicemanager等:

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完成,包括VmCreatedStartedZygoteInitExit四个阶段:

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启动后,分阶段启动一些服务,如常见的PMSAMSWMSIMS等,这些服务由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