Android Framework-Binder的启动

181 阅读3分钟

Binder的启动

在基础启动流程的时候,我们知道是zygote.rc 会调用app_process 传入参数启动

//base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
   // 继承 AndroidRuntime
   AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    }

AndroidRuntime 在构建后会调用start()方法onVmCreated()会注册JNI方法

//frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
    //省略。。
    onVmCreated(env);
  
  if (startReg(env) < 0) {
      //该方法内注册了JNI方法
        ALOGE("Unable to register all android natives\n");
        return;
    }
}
​
int AndroidRuntime::startReg(JNIEnv* env)
{
    
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
​
    
    env->PushLocalFrame(200);
​
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);
​
   
​
    return 0;
}
​
static const RegJNIRec gRegJNI[] = {
   //省略。。。
    REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
    REG_JNI(register_com_android_internal_os_ZygoteInit),
  
}
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}
​
//注册的nativeZygoteInit 方法
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}
​

到现在位置我们起码知道我们注册了一个JNI 方法 nativeZygoteInit

ZygoteInit 在执行main 方法过程中

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
// handleSystemServerProcess 之前判断了pid=0 才调用的 
main()
-->forkSystemServer()
--handleSystemServerProcess()
-->zygoteInit()
-->ZygoteInit.nativeZygoteInit();
​
  调用到JNI层的nativeZygoteInit() -->
//frameworks/base/core/jni/AndroidRuntime.cpp
  
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}
 // - frameworks/base/cmds/app_process/app_main.cpp
// -->调用onZygoteInit()
​
    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        proc->startThreadPool();
    }
​
}
​
//base/cmds/app_process/app_main.cpp
​
 virtual void onZygoteInit()
    {
   
      //构建ProcessState
        sp<ProcessState> proc = ProcessState::self();
        proc->startThreadPool();//在这里面启动binder
        ///startThreadPool()经过几次调用后 调用 makeBinderThreadName()
    }
​

ProcessState 构造

// self()调用了init方法 在该方法里 const char* kDefaultDriver = "/dev/binder";
#define DEFAULT_MAX_BINDER_THREADS 15
#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
sp<ProcessState> ProcessState::self()
{
    return init(kDefaultDriver, false /*requireDefault*/);
}
​
​
​
​
//核心在于open_driver 开启了binder 驱动 路径是/dev/binder 
//也据说说在构造函数里就启动了 binder 然后开启了mmap 
//默认设置是  一页大小 一般是4k 默认就是1m-8k
//设置了很多参数 ,比如最大线程数是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)
    , mWaitingForThreads(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)//最大线程数15
    , mStarvationStartTimeMs(0)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{
    if (mDriverFD >= 0) {
     
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
           
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }
​
#ifdef __ANDROID__
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened.  Terminating.", driver);
#endif
}
​
//这里对/dev/binder  进行了监听处理 返回句柄
static int open_driver(const char *driver)
{
    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) {
           
            close(fd);
            fd = -1;
        }
        //省略
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
         //省略
        uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
        result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
         //省略
    } 
    return fd;
}

startThreadPool()

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}
//这个和looper 那个主线程么啥关系
//开启了一个线程 并启动起来了 这里进入PoolThread
//拼接了名称 为Binder pid s
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
       
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        //构建了PoolThread 当run 的时候会调用到PoolThread的 threadLoop
        sp<Thread> t = sp<PoolThread>::make(isMain);
        t->run(name.string());
    }
}
​
String8 ProcessState::makeBinderThreadName() {
    int32_t s = android_atomic_add(1, &mThreadPoolSeq);
    pid_t pid = getpid();
    String8 name;
    name.appendFormat("Binder:%d_%X", pid, s);
    return name;
}

PoolThread

virtual bool threadLoop()
    {
  
        //self 函数相当于一个单例
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
​
    const bool mIsMain;
};
​
​
//死循环等待 一般不会退出
void IPCThreadState::joinThreadPool(bool isMain)
{
  
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
​
    mIsLooper = true;
    status_t result;
    do {
        processPendingDerefs();
         //核心方向 获取和执行一些命令 和binder 进行交互
        result = getAndExecuteCommand();
         //省略。。
​
 
        if(result == TIMED_OUT && !isMain) {
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);
​
       //省略。。
    mOut.writeInt32(BC_EXIT_LOOPER);
    mIsLooper = false;
    talkWithDriver(false);
}

IPCThreadState

//native/libs/binder/IPCThreadState.cpp
  // 每个binder 线程都有一个IPCThreadState 对象  有点像ThreadLocal

总结:

启动ProcessState ,在构造函数 打开了binder,映射了对应内存,

设置了一些基本函数,线程数之类,构建出来mmap ,大小为1m-8k,

然后启动了一个死循环线程,构建了一个IPCTThread对象,调用joinThreadPool(),在里面等待和binder驱动的一些交互。

到这里 应用端启动就完成了。