Android系统启动

 基于android12-release

Android系统启动

可以先查看图片:4.1 系统启动 或者下图:
在这里插入图片描述在这里插入图片描述

1、Loader:Boot Rom、Boot Loader


  Boot Rom:Android设备上电后,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。(由“芯片厂商”负责设计和实现)
  Boot Loader:Bootloader 开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存。
引导程序是在Android操作系统开始运行前的一个小程序。它不是Android操作系统的一部分。引导程序是 OEM 厂商或者运营商加锁和限制的地方。(由“设备厂商”负责设计和实现)

    相关资料如下:bootloader

2、Linux Kernel


Linux 内核开始启动,初始化各种软硬件环境,加载驱动程序,挂载根文件系统,并执行init程序,由此开启Android的世界。

  严格来说,Android系统实际上是运行于Linux内核上的一系列 “服务进程”,并不算一个完整意义上的“操作系统”。Android系统以及各大Linux的发行版,他们的Linux内核部分启动过程都是差不多。Android最后都是start_kernel初始化函数(system/core/init/main.cpp)

重要进程: pid=0,linux启动的第一个进程,swapper/idle进程pid=1,init进程;pid=2,kthreadd进程
在这里插入图片描述
init/main.c (androidxref上老版本rest_init都是kernel_thread)
在这里插入图片描述

3、Native C/C++ Library :主要解析 init.rc 文件


init 进程决定了系统在启动过程中,究竟会启动哪些守护进程和服务,以及呈现出怎样的一个用户UI界面。

这里不过多介绍其他,相关代码:(基于aosp/android11-release

  • system/core/init/main.cpp

  • system/core/init/first_stage_init.cpp

  • system/core/init/init.cpp 中SecondStageMain,最终在LoadBootScripts解析rc文件
    在这里插入图片描述
    在这里插入图片描述

    rc相关语法Android Init Language: system\core\init\README.md

3.1 init

init 进程会执行 app_process 程序,创建 Zygote 进程,它是Android系统最重要的进程,所有后续的Android应用程序都是由它 fork 出来的。
在这里插入图片描述
init 触发进程和服务:
在这里插入图片描述
触发器的执行顺序为on early-init -> init -> late-init

3.2 Zygote

init.rc中import /system/etc/init/hw/init.${ro.zygote}.rc,ro.zygote属性配置。
这里查看64位的 system/core/rootdir/init.zygote64.rc

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
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    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

服务Service,以 service 开头,由 init 进程启动,一般运行在 init 的一个子进程,每一个service在启动时会通过fork方式生成子进程。这个 rc 文件其中 service 用于通知 init 进程创建名 zygote 的进程,这个 zygote 进程执行程序的路径为 /system/bin/app_process64,后面的则是要传给 app_process64 的参数。class main指的是zygote的class name为main。


init 触发启动 service:Start方法中调用 fork() 创建子进程,调用 ExpandArgsAndExecv 通过最终调用 execv 执行system/bin/app_process,这样就会进入frameworks/base/cmds/app_process/app_main.cpp的main函数。

Result<void> Service::Start() {
    // ... ... ... ...
    pid_t pid = -1;
    if (namespaces_.flags) {
        pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
    } else {
        pid = fork();
    }

    if (pid == 0) {
        umask(077);
        // ... ... ... ...
        for (const auto& [key, value] : environment_vars_) {
            setenv(key.c_str(), value.c_str(), 1);
        }

        for (const auto& descriptor : descriptors) {
            descriptor.Publish();
        }
        // ... ... ... ...
        if (!ExpandArgsAndExecv(args_, sigstop_)) {
            PLOG(ERROR) << "cannot execv('" << args_[0]
                        << "'). See the 'Debugging init' section of init's README.md for tips";
        }

        _exit(127);
    }
    // ... ... ... ...
}

在这里插入图片描述

frameworks/base/cmds/app_process/app_main.cpp
frameworks/base/core/jni/AndroidRuntime.cpp

int main(int argc, char* const argv[])
{
    // ... ... 传到的参数argv为“-Xzygote /system/bin --zygote --start-system-server” ... ...
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // ... ... ... ...
    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.");
    }
}
runtime.start 来启动 zygote

4、Java API Framework


4.1 启动 SystemServer

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/Zygote.java

    public static void main(String argv[]) {
        // ... ... ... ...
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }
        // ... ... ... ...
    }
// ... ... ... ...
   /**
     * Prepare the arguments and forks for the system server process.
     *
     * @return A {@code Runnable} that provides an entrypoint into system_server code in the child
     * process; {@code null} in the parent.
     */
    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        // ... ... ... ...
                /* Hardcoded command line to start the system server */
        String args[] = {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
        };
            // ... ... ... ...
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

forkSystemServer 开启线程,执行 Zygote.forkSystemServer fork子进程,用于运行system_server;handleSystemServerProcess 完成system_server进程剩余的工作

反射调用到com.android.server.SystemServer

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
frameworks/base/core/services/java/com/android/server/SystemServer.java
Zygote最终调用 RuntimeInit.applicationInitfindStaticMain 方法反射调用调用到cl.getMethod("main", new Class[] { String[].class });

    public static void main(String[] args) {
        new SystemServer().run();
    }
    private void run() {
        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        try {
            t.traceBegin("InitBeforeStartServices");
            // ... ... ... ...
            // Initialize native services.
            System.loadLibrary("android_servers");
            // ... ... ... ...
            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            mDumper.addDumpable(mSystemServiceManager);

            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
            // ... ... ... ...
            // Start services.
        try {
            t.traceBegin("StartServices");
            startBootstrapServices(t);
            startCoreServices(t);
            startOtherServices(t);
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }
        // ... ... ... ...
    }
启动服务
  • startBootstrapServices 启动引导服务
  • startCoreServices 启动核心服务
  • startOtherServices 启动其他服务
    在这里插入图片描述

4.2 系统启动时序图

在这里插入图片描述

5、Launcher


frameworks/base/core/services/java/com/android/server/SystemServer.java

// 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(() -> {
    Slog.i(TAG, "Making services ready");
    t.traceBegin("StartActivityManagerReadyPhase");
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
    t.traceEnd();
    t.traceBegin("StartObservingNativeCrashes");
    try {
        mActivityManagerService.startObservingNativeCrashes();
    } catch (Throwable e) {
        reportWtf("observing native crashes", e);
    }
    t.traceEnd();

    t.traceBegin("RegisterAppOpsPolicy");
    try {
        mActivityManagerService.setAppOpsPolicy(new AppOpsPolicy(mSystemContext));
    } catch (Throwable e) {
        reportWtf("registering app ops policy", e);
    }
    t.traceEnd();

    // No dependency on Webview preparation in system server. But this should
    // be completed before allowing 3rd party
    final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";
    Future<?> webviewPrep = null;
    if (!mOnlyCore && mWebViewUpdateService != null) {
        webviewPrep = SystemServerInitThreadPool.submit(() -> {
            Slog.i(TAG, WEBVIEW_PREPARATION);
            TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
            traceLog.traceBegin(WEBVIEW_PREPARATION);
            ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");
            mZygotePreload = null;
            mWebViewUpdateService.prepareWebViewInSystemServer();
            traceLog.traceEnd();
        }, WEBVIEW_PREPARATION);
    }

    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
        t.traceBegin("StartCarServiceHelperService");
        final SystemService cshs = mSystemServiceManager
                .startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
        if (cshs instanceof Dumpable) {
            mDumper.addDumpable((Dumpable) cshs);
        }
        if (cshs instanceof DevicePolicySafetyChecker) {
            dpms.setDevicePolicySafetyChecker((DevicePolicySafetyChecker) cshs);
        }
        t.traceEnd();
    }

    // Enable airplane mode in safe mode. setAirplaneMode() cannot be called
    // earlier as it sends broadcasts to other services.
    // TODO: This may actually be too late if radio firmware already started leaking
    // RF before the respective services start. However, fixing this requires changes
    // to radio firmware and interfaces.
    if (safeMode) {
        t.traceBegin("EnableAirplaneModeInSafeMode");
        try {
            connectivityF.setAirplaneMode(true);
        } catch (Throwable e) {
            reportWtf("enabling Airplane Mode during Safe Mode bootup", e);
        }
        t.traceEnd();
    }
    t.traceBegin("MakeNetworkManagementServiceReady");
    try {
        if (networkManagementF != null) {
            networkManagementF.systemReady();
        }
    } catch (Throwable e) {
        reportWtf("making Network Managment Service ready", e);
    }
    CountDownLatch networkPolicyInitReadySignal = null;
    if (networkPolicyF != null) {
        networkPolicyInitReadySignal = networkPolicyF
                .networkScoreAndNetworkManagementServiceReady();
    }
    t.traceEnd();
    t.traceBegin("MakeIpSecServiceReady");
    try {
        if (ipSecServiceF != null) {
            ipSecServiceF.systemReady();
        }
    } catch (Throwable e) {
        reportWtf("making IpSec Service ready", e);
    }
    t.traceEnd();
    t.traceBegin("MakeNetworkStatsServiceReady");
    try {
        if (networkStatsF != null) {
            networkStatsF.systemReady();
        }
    } catch (Throwable e) {
        reportWtf("making Network Stats Service ready", e);
    }
    t.traceEnd();
    t.traceBegin("MakeConnectivityServiceReady");
    try {
        if (connectivityF != null) {
            connectivityF.systemReady();
        }
    } catch (Throwable e) {
        reportWtf("making Connectivity Service ready", e);
    }
    t.traceEnd();
    t.traceBegin("MakeVpnManagerServiceReady");
    try {
        if (vpnManagerF != null) {
            vpnManagerF.systemReady();
        }
    } catch (Throwable e) {
        reportWtf("making VpnManagerService ready", e);
    }
    t.traceEnd();
    t.traceBegin("MakeVcnManagementServiceReady");
    try {
        if (vcnManagementF != null) {
            vcnManagementF.systemReady();
        }
    } catch (Throwable e) {
        reportWtf("making VcnManagementService ready", e);
    }
    t.traceEnd();
    t.traceBegin("MakeNetworkPolicyServiceReady");
    try {
        if (networkPolicyF != null) {
            networkPolicyF.systemReady(networkPolicyInitReadySignal);
        }
    } catch (Throwable e) {
        reportWtf("making Network Policy Service ready", e);
    }
    t.traceEnd();

    // Wait for all packages to be prepared
    mPackageManagerService.waitForAppDataPrepared();

    // It is now okay to let the various system services start their
    // third party code...
    t.traceBegin("PhaseThirdPartyAppsCanStart");
    // confirm webview completion before starting 3rd party
    if (webviewPrep != null) {
        ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
    }
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
    t.traceEnd();

    t.traceBegin("StartNetworkStack");
    try {
        // Note : the network stack is creating on-demand objects that need to send
        // broadcasts, which means it currently depends on being started after
        // ActivityManagerService.mSystemReady and ActivityManagerService.mProcessesReady
        // are set to true. Be careful if moving this to a different place in the
        // startup sequence.
        NetworkStackClient.getInstance().start();
    } catch (Throwable e) {
        reportWtf("starting Network Stack", e);
    }
    t.traceEnd();

    t.traceBegin("StartTethering");
    try {
        // TODO: hide implementation details, b/146312721.
        ConnectivityModuleConnector.getInstance().startModuleService(
                TETHERING_CONNECTOR_CLASS,
                PERMISSION_MAINLINE_NETWORK_STACK, service -> {
                    ServiceManager.addService(Context.TETHERING_SERVICE, service,
                            false /* allowIsolated */,
                            DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
                });
    } catch (Throwable e) {
        reportWtf("starting Tethering", e);
    }
    t.traceEnd();

    t.traceBegin("MakeCountryDetectionServiceReady");
    try {
        if (countryDetectorF != null) {
            countryDetectorF.systemRunning();
        }
    } catch (Throwable e) {
        reportWtf("Notifying CountryDetectorService running", e);
    }
    t.traceEnd();
    t.traceBegin("MakeNetworkTimeUpdateReady");
    try {
        if (networkTimeUpdaterF != null) {
            networkTimeUpdaterF.systemRunning();
        }
    } catch (Throwable e) {
        reportWtf("Notifying NetworkTimeService running", e);
    }
    t.traceEnd();
    t.traceBegin("MakeInputManagerServiceReady");
    try {
        // TODO(BT) Pass parameter to input manager
        if (inputManagerF != null) {
            inputManagerF.systemRunning();
        }
    } catch (Throwable e) {
        reportWtf("Notifying InputManagerService running", e);
    }
    t.traceEnd();
    t.traceBegin("MakeTelephonyRegistryReady");
    try {
        if (telephonyRegistryF != null) {
            telephonyRegistryF.systemRunning();
        }
    } catch (Throwable e) {
        reportWtf("Notifying TelephonyRegistry running", e);
    }
    t.traceEnd();
    t.traceBegin("MakeMediaRouterServiceReady");
    try {
        if (mediaRouterF != null) {
            mediaRouterF.systemRunning();
        }
    } catch (Throwable e) {
        reportWtf("Notifying MediaRouterService running", e);
    }
    t.traceEnd();
    t.traceBegin("MakeMmsServiceReady");
    try {
        if (mmsServiceF != null) {
            mmsServiceF.systemRunning();
        }
    } catch (Throwable e) {
        reportWtf("Notifying MmsService running", e);
    }
    t.traceEnd();

    t.traceBegin("IncidentDaemonReady");
    try {
        // TODO: Switch from checkService to getService once it's always
        // in the build and should reliably be there.
        final IIncidentManager incident = IIncidentManager.Stub.asInterface(
                ServiceManager.getService(Context.INCIDENT_SERVICE));
        if (incident != null) {
            incident.systemRunning();
        }
    } catch (Throwable e) {
        reportWtf("Notifying incident daemon running", e);
    }
    t.traceEnd();

    if (mIncrementalServiceHandle != 0) {
        t.traceBegin("MakeIncrementalServiceReady");
        setIncrementalServiceSystemReady(mIncrementalServiceHandle);
        t.traceEnd();
    }
}, t);

Launcher启动:Launcher启动过程
frameworks\base\services\java\com\android\server\SystemServer.java
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java
frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java
frameworks\base\services\core\java\com\android\server\wm\ActivityStartController.java
frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java
SystemServer 执行 startOtherServices 启动服务时,最后会调用 mActivityManagerService.systemReady。AMS.systemReady -> ActivityTaskManagerService.java 中 startHomeOnAllDisplays -> mRootWindowContainer.startHomeOnAllDisplays -> startHomeOnDisplay -> startHomeOnTaskDisplayArea -> ATMS中getHomeIntent获取intent,mService.getActivityStartController().startHomeActivity

   public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
        // ... ... ... ...
        Slog.i(TAG, "System now ready");
        // ... ... ... ...
        synchronized (this) {
            // ... ... ... ...
            // Start up initial activity.
            mBooting = true;
            // ... ... ... ...
            if (bootingSystemUser) {
                t.traceBegin("startHomeOnAllDisplays");
                mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
                t.traceEnd();
            }
            // ... ... ... ...
        }
    }

在这里插入图片描述
在这里插入图片描述

* 小结回顾

在这里插入图片描述
在这里插入图片描述

感谢并推荐:Android内核开发


Android内核开发:开发板选购
Android内核开发:理解和掌握repo工具
Android内核开发:源码的版本与分支详解
Android内核开发:系统编译输出的镜像文件
Android内核开发:系统分区与镜像文件的烧写
Android内核开发:图解Android系统的启动过程
Android内核开发:如何统计系统的启动时间
Android内核开发:学会分析系统的启动log
Android内核开发:系统启动速度优化

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xhBruce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值