Binder(四)system_server中binder的初始化

本文基于Android_9.0、kernel_3.18源码

引言

由Zygote进程简介,我们知道android进程之间的关系;system_server是由zygote进程fork出来的,那它中间是怎样操作的呢?

Binder(四)system_server中binder的初始化

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& 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()方法中。


args

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.

* * Current recognized args: *

    *
  • [--] <start class name> <args> *
* * @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 proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool();
}

首先,通过ProcessState::self()获取ProcessState实例;
然后,调用startThreadPool方法。

5.1、ProcessState::self()

// 获取单例
sp 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 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()读取操作处理任务,在初始状态没有任务,便会阻塞等待任务唤醒。

你可能感兴趣的:(Binder(四)system_server中binder的初始化)