本文基于Android_9.0、kernel_3.18源码
引言
由Zygote进程简介,我们知道android进程之间的关系;system_server是由zygote进程fork出来的,那它中间是怎样操作的呢?
frameworks/base/cmds/app_process/app_main.cpp
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/Zygote.java
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
frameworks/base/core/jni/AndroidRuntime.cpp
frameworks/native/libs/binder/ProcessState.cpp
frameworks/native/libs/binder/IPCThreadState.cpp
frameworks/native/include/binder/IPCThreadState.h
system_server进程创建过程
1、app_main.cpp->main()
int main(int argc, char* const argv[]){
........
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
........
if (zygote) {
// 拉起com.android.internal.os.ZygoteInit.java
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {} else {}
}
在app_main.cpp->main()方法中,通过runtime.start()拉起ZygoteInit.java;AppRuntime是AndroidRuntime的子类,start方法会开启虚拟机,并且调用className的main方法。
// 开启Android虚拟机, 并调用className的main方法
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){}
2、ZygoteInit.java->main()
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
........
// 注册socket
zygoteServer.registerServerSocketFromEnv(socketName);
........
// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
// 预加载资源
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
........
if (startSystemServer) {
// 启动system_server
Runnable r = forkSystemServer(abiList, socketName, 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;
}
}
........
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
// 启动消息循环
caller = zygoteServer.runSelectLoop(abiList);
}
ZygoteInit.java->main()方法主要做四件事:
1、注册socket
2、预加载资源
3、启动system_server
4、启动消息循环
3、ZygoteInit.java->forkSystemServer()
/**
* Prepare the arguments and forks for the system server process.
*
* Returns an {@code Runnable} that provides an entrypoint into system_server code in the
* child process, and {@code null} in the parent.
*/
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
........
int pid;
try {
// 封装参数
parsedArgs = new ZygoteConnection.Arguments(args);
........
// 创建system_server进程
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} 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;
}
首先,通过Zygote.forkSystemServer()fork出子进程;
然后,通过handleSystemServerProcess(parsedArgs)进行下一步处理。
3.1、Zygote.java->forkSystemServer()
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
VM_HOOKS.postForkCommon();
return pid;
}
native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
首先,通过Zygote.java->forkSystemServer()调用到native方法nativeForkSystemServer(),该方法定义在com_android_internal_os_Zygote.cpp中
然后,在com_android_internal_os_Zygote_nativeForkSystemServer()方法内部调用ForkAndSpecializeCommom();
最后,在ForkAndSpecializeCommom()中,通过系统调用fork()创建进程,并进行参数设置。
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, false, NULL, NULL);
........
return pid;
}
// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint runtime_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jintArray fdsToIgnore, bool is_child_zygote,
jstring instructionSet, jstring dataDir) {
pid_t pid = fork();
if (pid == 0) {
// 设置进程参数
}
}
3.2、ZygoteInit.java->handleSystemServerProcess()
static class Arguments {
........
/** from --invoke-with */
String invokeWith;
}
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
........
if (parsedArgs.invokeWith != null) {
........
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
通过invokeWith的注释可以知道,它是通过--invoke-with参数携带进来的。通过查看启动system_server的参数可知,此处并未设置,因此走到 ZygoteInit.zygoteInit()方法中。
4、ZygoteInit.java->zygoteInit()
/**
* The main function called when started through the zygote process. This
* could be unified with main(), if the native code in nativeFinishInit()
* were rationalized with Zygote startup.<p>
*
* Current recognized args:
* <ul>
* <li> <code> [--] <start class name> <args>
* </ul>
*
* @param targetSdkVersion target SDK version
* @param argv arg strings
*/
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
ZygoteInit.java->zygoteInit()最终会调用native方法nativeZygoteInit()。
5、app_main.cpp AppRuntime->onZygoteInit()
nativeZygoteInit()方法定义在AndroidRuntime.cpp中:
int main(int argc, char* const argv[]){
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
}
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength){
SkGraphics::Init();
// Pre-allocate enough space to hold a fair number of options.
mOptions.setCapacity(20);
assert(gCurRuntime == NULL); // one per process
gCurRuntime = this;
}
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz){
gCurRuntime->onZygoteInit();
}
nativeZygoteInit()中使用了gCurRuntime,而它是在AndroidRuntime构造函数中赋值的。我们还记得在app_main.cpp的main方法中实例化了AndroidRuntime的子类AppRuntime。
因此, gCurRuntime->onZygoteInit()也就调用到了AppRuntime->onZygoteInit()。
virtual void onZygoteInit(){
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
首先,通过ProcessState::self()获取ProcessState实例;
然后,调用startThreadPool方法。
5.1、ProcessState::self()
// 获取单例
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState("/dev/binder");
return gProcess;
}
ProcessState::self()比较简单,获取ProcessState单例。接着我们看看ProcessState的构造方法:
#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
#define DEFAULT_MAX_BINDER_THREADS 15
// 构造函数
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
, mDriverFD(open_driver(driver))
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
// mmap进行内存映射
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
close(mDriverFD);
mDriverFD = -1;
mDriverName.clear();
}
}
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
在ProcessState构造函数中:
1、通过open_driver()打开binder驱动;
2、通过mmap()函数进行内存映射,仔细看BINDER_VM_SIZE参数,它定义的大小是1M-_SC_PAGE_SIZE*2;这是binder对内存的限制。
5.1.1、再仔细分析一下open_driver()
static int open_driver(const char *driver)
{
// 打开binder驱动
int fd = open(driver, O_RDWR | O_CLOEXEC);
if (fd >= 0) {
int vers = 0;
// 获取版本号
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result == -1) {
ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
close(fd);
fd = -1;
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
close(fd);
fd = -1;
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
// 设置最大线程数
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
} else {
ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
}
return fd;
}
open_driver做了三个操作:
1、系统调用open()打开binder驱动
2、系统调用ioctl()获取版本号
3、系统调用ioctl()设置最大线程数
5.2、ProcessState::startThreadPool()
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
通过ProcessState::startThreadPool()调用到spawnPooledThread(),在spawnPooledThread()中创建PoolThread,并执行run方法。
5.2.1、PoolThread
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
通过PoolThread ->run()会调用到threadLoop()方法,相关内容可参考:
system/core/include/utils/Thread.h
system/core/libutils/Threads.cpp
6、IPCThreadState::joinThreadPool()
Parcel mIn;
Parcel mOut;
void IPCThreadState::joinThreadPool(bool isMain){
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
// 开启循环
do {
processPendingDerefs();
// now get the next command to be processed, waiting if necessary
// 等待请求
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
mProcess->mDriverFD, result);
abort();
}
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if(result == TIMED_OUT && !isMain) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
(void*)pthread_self(), getpid(), result);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
status_t IPCThreadState::getAndExecuteCommand(){
status_t result;
int32_t cmd;
result = talkWithDriver();
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) return result;
cmd = mIn.readInt32();
........
result = executeCommand(cmd);
........
}
return result;
}
首先,由上下文知道,此时isMain为true,因此mOut的指令是BC_ENTER_LOOPER;
然后,joinThreadPool()通过do while开启循环,getAndExecuteCommand()会调用talkWithDriver()。
7、talkWithDriver()
status_t IPCThreadState::talkWithDriver(bool doReceive){
........
binder_write_read bwr;
// 判断要读还是要写
// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
// This is what we'll read.
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
........
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {
........
#if defined(__ANDROID__)
// 通过ioctl与binder驱动交互,如果read,并且没有任务,触发阻塞
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
if (mProcess->mDriverFD <= 0) {
err = -EBADF;
}
IF_LOG_COMMANDS() {
alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
}
} while (err == -EINTR);
........
return err;
}
joinThreadPool()+getAndExecuteCommand()+talkWithDriver()中的逻辑与上一篇文章中binder_loop()中的内容很像;
1、都会向binder驱动发送BC_ENTER_LOOPER指令,告诉驱动,当前线程进入循环;
2、再调用ioctl()读取操作处理任务,在初始状态没有任务,便会阻塞等待任务唤醒。