「安卓framework基础篇1」开机流程(基于AOSP13)
「安卓framework基础篇1」开机流程(基于AOSP13)
作为安卓系统爱好者,想理解手机系统的运行原理,但是安卓操作系统这么复杂,从哪开始呢?跟使用手机的操作顺序一样,先从开机开始吧。
用户态的第一个进程的启动
Native层
init进程调用 system/core/init/main.cpp 的main函数, 然后再调用父类 system/core/init/init.cpp 的 SecondStageMain() 函数解析.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新进程
最后以一张图进行总结
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)