「安卓framework基础篇1」开机流程(基于AOSP13)

作为安卓系统爱好者,想理解手机系统的运行原理,但是安卓操作系统这么复杂,从哪开始呢?跟使用手机的操作顺序一样,先从开机开始吧。

用户态的第一个进程的启动

Native层

init进程调用 system/core/init/main.cpp 的main函数, 然后再调用父类 system/core/init/init.cppSecondStageMain() 函数解析.rc启动脚本并分阶段执行 .rc 脚本:

int SecondStageMain(int argc, char** argv) {
    // 省略
    
    // 读取并加载.rc文件
    LoadBootScripts(am, sm);

     // 省略
    am.QueueEventTrigger("early-init");

     // 省略
    am.QueueEventTrigger("init");

    // 省略
    am.QueueEventTrigger("late-init");
    // 省略

}

根据 system/core/rootdir/init.zygote32.rc 这个启动脚本中的内容 (从这里开始看即可,再上面就是内核态代码了,咱们研究framework层暂时不用关心):

service zygote /system/bin/app_process -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 media.tuner
    onrestart restart netd
    onrestart restart wificond
    task_profiles ProcessCapacityHigh
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

发现要执行 /system/bin/app_process 这个二进制文件,那么这个文件对应的.cpp文件在哪里呢?使用如下命令在源码里搜索:

grep -r --include="*.bp" "name: \"app_process\"" ./

执行结果:

./frameworks/base/cmds/app_process/Android.bp:    name: "app_process",

发现在这个Android.bp文件中定义了这个二进制文件的名称。
这个bp文件包含如下内容:

cc_binary {
    name: "app_process",

    srcs: ["app_main.cpp"],

    multilib: {
        lib32: {
            suffix: "32",
        },
        lib64: {
            suffix: "64",
        },
    },

意思是将与bp文件同目录下的app_main.cpp文件编译成名称叫作app_process的二进制文件。
app_main.cpp文件main函数部分内容:

int main(int argc, char* const argv[])
{
      ...省略...
      AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
      ...省略...
      runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
      ...省略...
}

看起来是要调用"com.android.internal.os.ZygoteInit"这个java类了。我们看一下AppRuntime的父类AndroidRuntime.cpp的start函数:

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
   ...省略...
    //开启虚拟机环境
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
   ...省略...
    //调用"com.android.internal.os.ZygoteInit.java"的main方法
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
   ...省略...
}

下面我们来看 **frameworks/base/core/java/com/android/internal/os/ZygoteInit.java ** 的main方法

Framework层

ZygoteInit.java 文件的内容如下:

@UnsupportedAppUsage
    public static void main(String[] argv) {
        //定义 zygoteServer 变量
        ZygoteServer zygoteServer = null;
         //省略
            //初始化 ZygoteServer 对象,这里会创建socket监听AMS发来的进程创建请求
            zygoteServer = new ZygoteServer(isPrimaryZygote);
            
            if (startSystemServer) {
                // 这里面会fork子进程来初始化system_server
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
              // r如果不等于null则代表当前进程是用来初始化system_server的子进程,初始化完system_server直接return即可
                if (r != null) {
                    r.run();
                    return;
                }
            }
            //省略
            // r如果等于null则代标当前进程是主进程,要在runSelectLoop里循环监听socket以处理AMS的进程创建请求
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with fatal exception", ex);
            throw ex;
        } finally {
            if (zygoteServer != null) {
                zygoteServer.closeServerSocket();
            }
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }

Zygote在 frameworks/base/core/java/com/android/internal/os/ZygoteServer.java 的 runSelectLoop 方法中为新打开的app fork新进程 :

Runnable runSelectLoop(String abiList) {
                         //省略
                        try {
                            ZygoteConnection connection = peers.get(pollIndex);
                            boolean multipleForksOK = !isUsapPoolEnabled()
                                    && ZygoteHooks.isIndefiniteThreadSuspensionSafe();
                            // 最终调用 processCommand 方法为新app fork新进程
                            final Runnable command =
                                    connection.processCommand(this, multipleForksOK);
                            //省略
                        } catch (Exception e) {
                            //省略
                        } 
                         //省略
    }

我们最后看下 connection.processCommand() 方法:

Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
                //省略
                if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
                        || !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
                    // Continue using old code for now. TODO: Handle these cases in the other path.
                    // 在这里为新打开的app fork了新进程
                    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,
                            parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits,
                            parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName,
                            fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir,
                            parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList,
                            parsedArgs.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,
                            parsedArgs.mBindMountAppStorageDirs);

                  //省略  
    }

ZygoteInit.java的main方法主要就做了以下三件事:

  • fork出system_server的进程
  • 监听AMS发来的app进程创建请求
  • 收到AMS发来的app进程创建请求后为新app fork新进程

最后以一张图进行总结

zygote子进程zygote进程app_process进程init进程zygote子进程zygote进程app_process进程init进程启动app_process这个二进制可执行文件app_process启动art虚拟机环境并调用ZygoteInit.java的main方法zygote进程fork出zygote子进程zygote子进程构造出初始化system_server进程的Runnable对象zygote子进程开始执行Runnable对象的run方法初始化system_server进程zygote进程开始监听socket,等待处理AMS发来的app进程创建请求zygote进程监听到AMS发来的新app fork请求,开始为新打开的app fork新进程
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐