Linux在BootLoader后,加载完内核后,启动第一个进程init进程,源码路径位于/system/core/init:
关注入口函数main.cpp可以看见,main.cpp主要是根据参数选择某种启动模式,正常我们是走SecondStageMain
int main(int argc, char** argv) {
if (argc > 1) {
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);
}
}
}
接着我们查看/system/core/init/init.cpp
int SecondStageMain(int argc, char** argv) {
InitKernelLogging(argv);
PropertyInit();
// Mount extra filesystems required during second stage init
MountExtraFilesystems();
// Now set up SELinux for second stage.
SelinuxSetupKernelLogging();
SelabelInitialize();
SelinuxRestoreContext();
Epoll epoll;
if (auto result = epoll.Open(); !result.ok()) {
PLOG(FATAL) << result.error();
}
InstallSignalFdHandler(&epoll);
InstallInitNotifier(&epoll);
//解析init配置文件
LoadBootScripts(am, sm);
while (true) {
//省略
}
return 0;
}
可以看到init主要做了部分初始化操作,比如内核日志,文件创建挂载,se权限,epoll的创建与注册监听,配置文件解析,最后还有个while的死循环用以处理事件
我们重点关注配置解析即可:
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/system/etc/init/hw/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
// late_import is available only in Q and earlier release. As we don't
// have system_ext in those versions, skip late_import for system_ext.
parser.ParseConfig("/system_ext/etc/init");
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}
可以看到主要是从system(系统),vendor(硬件商:高通/mtk),odm(设备厂商,小米/联想/华为等)三个目录去获取配置文件,以及/system.etc/init/hw/init.rc
根据 /system/core/rootdir下的make文件,我们可以看出:
/system/core/rootdir 对应着编译后的/system/etc/init目录
主要关注:
system/core/rootdir/init.rc以及 system/core/rootdir/init.zygote64.rc
可以看到这两个配置文件分别描述了servicemanager进程以及zygote进程使得其由init进程进行解析并启动。
servicemanager源码位于:frameworks/native/cmds/servicemanager/
该进程作为servicemanager管家,主要在于向binder驱动注册自己,接着陷入循环等待(具体见路径下源码)
zygote源码位于:frameworks/base/cmds/app_process/
从路径名app_process即可看出,zygote才是我们真正意义上与应用相关的进程。
进入对应入口函数查看(app_main.cpp):
int main(int argc, char* const argv[])
{
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} 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.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
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.");
}
}
可以看到main函数中判断传入参数,走了不同的业务逻辑,要启动的是一个system-server,还是一个app,还是说就是一个zygote
最后走AppRuntime的start进行启动。因为之前在init.zygote64.rc内,指定了参数 --zygote --start-system-server,所以此处走第一个if,并且继续将-start-system-server传递进去
frameworks/base/core/jni/AndroidRuntime.cpp:
void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
static const String8 startSystemServer("start-system-server");
bool primary_zygote = false;
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
primary_zygote = true;
}
}
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//启动jvm虚拟机,传入配置参数,此时还未真正调用新进程的main
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
//虚拟机启动后的回调
onVmCreated(env);
//有了jvm环境后,注册JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
//className:com.android.internal.os.ZygoteInit
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
}
可以看到最终启动了一个jvm虚拟机,zygote为true,primary_zygote 也为true。即意味着最终我们要启动一个主zygote,并且将fork出system-server),可以看到,最终我们通过JNI调用了frameworks/base/core/java/com/android/internal/os/ZygoteInit.java的main函数
public static void main(String argv[]) {
//可以看到ZygoteInit首先创建了一个ZygoteServer:里面主要是初始化了socket
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
//关键1:fork出system server进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
//关键2: zygote陷入循环,监听处理各种需求
caller = zygoteServer.runSelectLoop(abiList);
if (caller != null) {
caller.run();
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
if (isPrimaryZygote) {
//创建了socket
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
}
}
//frameworks/base/core/java/com/android/internal/os/Zygote.java
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;//"ANDROID_SOCKET_zygote"
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
return new LocalServerSocket(fd);
}
我们先看下system server启动相关,即被fork出的system server这个进程后续逻辑frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {
//通过fork创建system server子进程
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
if (pid == 0) {
//system server子进程启动各种system server
return handleSystemServerProcess(parsedArgs);
}
}
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
//通过JNI调用native层初始化com_android_internal_os_ZygoteInit_nativeZygoteInit:
ZygoteInit.nativeZygoteInit();
//进行Java层的初始化
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
//frameworks/base/core/jni/AndroidRuntime.cpp:
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
//gCurRuntime真正实现为一开始创建的AppRuntime : AndroidRuntime
gCurRuntime->onZygoteInit();
}
//frameworks/base/cmds/app_process/app_main.cpp ->AppRuntime:
virtual void onZygoteInit()
{
//可以看到为system server进程初始化了Binder线程池,以用于处理其它程序访问系统服务
//ProcessState是每个进程唯一的,主要用于管理Binder操作,而IPCThreadState则是每个线程的Binder操作:具体可以查看Binder机制分析
sp proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java:
protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {
//其实这里就是执行SystemServer.java的main函数
Class> cl;
cl = Class.forName(className, true, classLoader);
Method m;
m = cl.getMethod("main", new Class[] { String[].class });
int modifiers = m.getModifiers();
return new MethodAndArgsCaller(m, argv);
}
//frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
//启动三大类的系统服务,然后陷入loop循环,利用之前初始化的binder环境,提供通信
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
// Loop forever.
Looper.loop();
}
可以看出整个system server由zygote fork出来之后,最终是作为独立进程启动了各类核心服务,通过Binder提供给其余应用访问
接着我们看下zygote自身的后续逻辑,即陷入循环部分,这一块涉及到普通应用是如何被zygote孵化运行并启动的
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java:
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
//所有监听描述符集合
ArrayList socketFDs = new ArrayList<>();
//所有创建的链接集合
ArrayList peers = new ArrayList<>();
//这里添加的就是在创建ZygoteServer时初始化的socket
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
//陷入死循环
while (true) {
StructPollfd[] pollFDs;
pollFDs = new StructPollfd[socketFDs.size()];
int pollIndex = 0;
//转换一下数据格式
for (FileDescriptor socketFD : socketFDs) {
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = socketFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}
//poll轮询时间
int pollTimeoutMs;
//poll监听结果
int pollReturnValue;
try {
//发起一次poll轮询
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
if (pollReturnValue == 0) {
//轮询超时前没有事件发生
} else {
//有事件发生,需要遍历描述符集合查进行处理
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
//最开始只有zygote的socket,所以会优先执行这里:与system server建立连接
if (pollIndex == 0) {
// Zygote server socket
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
}else {
//这部分是处理已建立联系的通信,system server的AMS启动新进程即在此处:
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
}
}
}
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
String[] args;
args = Zygote.readArgumentList(mSocketReader);
int pid;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
ZygoteArguments parsedArgs = new ZygoteArguments(args);
//进行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.mWhitelistedDataInfoList,
parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
if (pid == 0) {
//此时已是应用进程逻辑
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//从这里继续启动应用进程的后续逻辑
return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
}
}
//我们先看fork进程的逻辑:
//frameworks/base/core/java/com/android/internal/os/Zygote.java
static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,
boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
//创建运行环境
ZygoteHooks.preFork();
//调用native层
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
bindMountAppStorageDirs);
ZygoteHooks.postForkCommon();
return pid;
}
//frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring nice_name,
jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list,
jboolean mount_data_dirs, jboolean mount_storage_dirs) {
pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
return pid;
}
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector& fds_to_close,
const std::vector& fds_to_ignore,
bool is_priority_fork) {
//可以看到实际,最终在native层通过fork孵化了应用进程
pid_t pid = fork();
return pid;
}
//接着回到fork出的进程的后续执行逻辑中:frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs,
closeSocket();
Zygote.setAppProcessName(parsedArgs, TAG);
//可以看到最终我们再次走到了zygoteInit
// 和之前的system server进程启动一样,接下来会在native层准备binder环境,然后反射调用java层的启动类(ActivityThread)的main函数
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
简单总结一下,整个启动流程就是:
先从固定位置的固化存储中启动bootloader,然后加载linux内核,由linux内核启动第一个用户进程init。init进程启动后通过解析rc文件,依次启动了servicemanager进程,以及zygote进程。前者作为binder管家,负责所有service的通信寻址工作,后者则负责Android系统的应用孵化工作。
zygote首先是根据init解析rc传入的参数,fork出了system server进程,这里面就运行了所有的系统级服务,比如常见的AMS,PMS等等,注册进了之前的servicemanager中,接着zygote创建socket,与system server建立通信,并且陷入循环阻塞,当AMS启动应用时,就会通过socket通知zygote,zygote就会去fork出新的子进程。