您现在的位置是:首页 >学无止境 >一个非系统工程师所关心的——Android开机流程网站首页学无止境

一个非系统工程师所关心的——Android开机流程

闽农 2024-06-26 14:23:41
简介一个非系统工程师所关心的——Android开机流程

一、Loader层

1. Boot ROM:
        上电后,BootRom会被激活,引导芯片代码开始从预定义的地方(固化在ROM)开始执行,然后加载引导程序到RAM

2. Boot Loader引导程序

      Android是基于Linux系统的,它没有BIOS程序,取而代之的是BootLoader(系统启动引导程序)。引导程序是厂商加锁和限制的地方,它是针对特定的主板与芯片的。厂商要么使用很受欢迎的引导程序比如redbootubootARMboot等或者开发自己的引导程序,它不是Android操作系统的一部分。流程图如下:


 

 二、kernel层

      Linux内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。

1.init 进程的启动

      0号进程:
      swapper进程(pid=0):又称idle进程、空闲进程,由系统自动创建, 运行在内核态。
系统初始化过程Kernel由无到有开创的第一个进程, 也是唯一一个没有通过fork或者kernel_thread产生的进程。
swapper进程用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作。

    1号进程(就是init进程)
init进程(pid=1):由0号进程通过kernel_thread创建,在内核空间完成初始化后, 加载init程序, 并最终运行在用户空间,init进程是所有用户进程的鼻祖,他的作用是:

   (1)是挂载tmpfs, devpts, proc, sysfs文件系统

   (2)是运行init.rc脚本,init将会解析init.rc,并且执行init.rc中的命令。

   (3)当一些关键进程死亡时,重启该进程;

   (4)提供Android系统的属性服务

    2号进程
kthreadd进程(pid=2):由0号进程通过kernel_thread创建,是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。
kthreadd运行在内核空间, 负责所有内核线程的调度和管理 , kthreadd进程是所有内核进程的鼻

三、init进程启动了zygote和serviceManager

1.Zygote启动

我们关注的是:Linux内核启动后,会加载system/core/init/init.rc文件,启动init进程,init进程会fork Zygote进程,Zygote作为孵化器进程,它的main函数会创建好自己的环境准备孵化子进程,并开始等待孵化请求。

init.rc文件内容很多,我们就贴一点出来

chown system system /dev/stune/tasks

chmod 0664 /dev/stune/tasks

mkdir /dev/binderfs

mkdir /mnt/user/0/emulated/0 0755 root root

start servicemanager //重点2 servicemanager启动
start hwservicemanager
start vndservicemanager

import /system/etc/init/hw/init.${ro.zygote}.rc
trigger zygote-start
on zygote-start && property:ro.crypto.state=unencrypted
    wait_for_prop odsign.verification.done 1
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start statsd
    start netd
    start zygote
    start zygote_secondary

可见init启动了zygote、servicemanager等等。

那么我们先看zygote是怎么启动的,后面再看serviceManager。我们来看一下init.zygote64.rc文件 

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system

可见启动了app_process程序,app_process的源码在frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, const char* const argv[])
{
    // These are global variables in ProcessState.cpp
    mArgC = argc;
    mArgV = argv;
    mArgLen = 0;
    for (int i=0; i<argc; i++) {
        mArgLen += strlen(argv[i]) + 1;
    }
    mArgLen--;
    AppRuntime runtime;
    const char* argv0 = argv[0];
    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;
    // Everything up to '--' or first non '-' arg goes to the vm
    int i = runtime.addVmArguments(argc, argv);
    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    const char* parentDir = NULL;
    const char* niceName = NULL;
    const char* className = NULL;
    while (i < argc) {
        const char* arg = argv[i++];
        if (!parentDir) {
            parentDir = arg;
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;//zygote进程
            niceName = "zygote";
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;//启动系统服务
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName = arg + 12;
        } else {
            className = arg;
            break;
        }
    }
    if (niceName && *niceName) {
        setArgv0(argv0, niceName);
        set_process_name(niceName);
    }
    runtime.mParentDir = parentDir;
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "")
;//在这里通过runtime启动ZygoteInit从此由内核C层进入了我们的应用层。
    } else if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied. ");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }
}

我们看看/java/com/android/internal/os/ZygoteInit.java 类都做了些什么

   static void preload(TimingsTraceLog bootTimingsTraceLog) {
        Log.d(TAG, "begin preload");
      
       
beginPreload();
        preloadClasses();//预加载类,其中就包括我们熟悉的系统API
       
cacheNonBootClasspathClassLoaders();加载无法放入Boot classpath的文件
        preloadResources();加载drawables、colors
       
nativePreloadAppProcessHALs();加载hal 硬件
       
maybePreloadGraphicsDriver();调用OpenGL/Vulkan加载图形驱动程序
       
preloadSharedLibraries();//加载共享库
       
preloadTextResources();初始化TextView ,对,你没看错
        WebViewFactory.prepareWebViewInZygote();//初始化webview
        endPreload();// 取消软引用保护
        warmUpJcaProviders(); 初始化JCA安全相关的参数,比如AndroidKeyStoreProvider安装
        sPreloadComplete = true;
    }

for系统服务:

 private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
       
        StructCapUserHeader header = new StructCapUserHeader(
                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
        StructCapUserData[] data;
        try {
            data = Os.capget(header);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to capget()", ex);
        }
        capabilities &= Integer.toUnsignedLong(data[0].effective) |
                (Integer.toUnsignedLong(data[1].effective) << 32);
        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,3005,3006,3007,3009,3010,3011,3012",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
        };
        ZygoteArguments parsedArgs;
        int pid;
        try {
            ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
            try {
                parsedArgs = ZygoteArguments.getInstance(commandBuffer);
            } catch (EOFException e) {
                throw new AssertionError("Unexpected argument error for forking system server", e);
            }
            commandBuffer.close();
            Zygote.applyDebuggerSystemProperty(parsedArgs);
            Zygote.applyInvokeWithSystemProperty(parsedArgs);
            if (Zygote.nativeSupportsMemoryTagging()) {
                String mode = SystemProperties.get("arm64.memtag.process.system_server", "");
                if (mode.isEmpty()) {
                  /* The system server has ASYNC MTE by default, in order to allow
                   * system services to specify their own MTE level later, as you
                   * can't re-enable MTE once it's disabled. */
                  mode = SystemProperties.get("persist.arm64.memtag.default", "async");
                }
                if (mode.equals("async")) {
                    parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
                } else if (mode.equals("sync")) {
                    parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_SYNC;
                } else if (!mode.equals("off")) {
                    /* When we have an invalid memory tag level, keep the current level. */
                    parsedArgs.mRuntimeFlags |= Zygote.nativeCurrentTaggingLevel();
                    Slog.e(TAG, "Unknown memory tag level for the system server: "" + mode + """);
                }
            } else if (Zygote.nativeSupportsTaggedPointers()) {
                /* Enable pointer tagging in the system server. Hardware support for this is present
                 * in all ARMv8 CPUs. */
                parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
            }
            /* Enable gwp-asan on the system server with a small probability. This is the same
             * policy as applied to native processes and system apps. */
            parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;
            if (shouldProfileSystemServer()) {
                parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer( //调用zygote fork 系统服务
                    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;
    }

所以最终调用  java/com/android/internal/os/Zygote.java 的 forkSystemServer,我们看一下源码

static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        ZygoteHooks.preFork();
        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits,
                permittedCapabilities, effectiveCapabilities);
        // Set the Java Language thread priority to the default value for new apps.
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
        ZygoteHooks.postForkCommon();
        return pid;
    }

所以systemServer就这么启动了。

好了,具体的细节我们就跟踪到这里,有兴趣的可以看源码,源码有详细的过程。
 

2.servicemanager启动

我们看到 init 也启动了/system/bin/servicemanager程序,servicemanager程序的源码在android/frameworks/native/cmds/servicemanager/main.cpp

int main(int argc, char** argv) {
    android::base::InitLogging(argv, android::base::KernelLogger);
    if (argc > 2) {
        LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
    }
    const char* driver = argc == 2 ? argv[1] : "/dev/binder";
    LOG(INFO) << "Starting sm instance on " << driver;
    sp<ProcessState> ps = ProcessState::initWithDriver(driver);//驱动层创建binder_proc
    ps->setThreadPoolMaxThreadCount(0);
    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);

//创建ServiceManager
    sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
   //添加服务

if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
        LOG(ERROR) << "Could not self register servicemanager";
    }
    IPCThreadState::self()->setTheContextObject(manager);
    if (!ps->becomeContextManager()) {//注册成为binder服务的大管家
        LOG(FATAL) << "Could not become context manager";
    }

//开启looper 消息循环 监听 BinderCallback
    sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
    BinderCallback::setupTo(looper); //处理Binder请求
    ClientCallbackCallback::setupTo(looper, manager);//定时通知client变化
#ifndef VENDORSERVICEMANAGER
    if (!SetProperty("servicemanager.ready", "true")) {
        LOG(ERROR) << "Failed to set servicemanager ready property";
    }
#endif
    while(true) {
        looper->pollAll(-1);
    }
    // should not be reached
    return EXIT_FAILURE;
}

。。。等待继续

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。