Android Binder 应用程序Binder 启动源码分析

Posted we1less

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder 应用程序Binder 启动源码分析相关的知识,希望对你有一定的参考价值。

android8.1启动过程(七) SystemServer_we1less的博客-CSDN博客

这篇文章说道SystemServer进程主要用于创建系统服务,同时初始化Zygote

调用gCurRuntime->onZygoteInit();本文从这继续解析binder的启动过程。


onZygoteInit   AOSP/frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\\n");
        proc->startThreadPool();
    }

ProcessState::self();  frameworks/native/libs/binder/ProcessState.cpp

        #define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)

sysconf(_SC_PAGE_SIZE)这个代表一页内存大小一般是 4096

这样        BINDER_VM_SIZE = 1M - 8k

#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
#define DEFAULT_MAX_BINDER_THREADS 15

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");
    return gProcess;
}


ProcessState::ProcessState(const char *driver)
    //驱动文件的名字 /dev/binder
    : mDriverName(String8(driver))
    //这里有打开驱动的代码open_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.
        //内存映射  1M - 8k
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\\n");
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }

    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

open_driver  打开驱动节点 

static int open_driver(const char *driver)
{
    //open节点返回文件句柄
    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;
        }
        //DEFAULT_MAX_BINDER_THREADS  最大binder线程大小 = 15
        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;
}

接下来分析startThreadPool  frameworks/native/libs/binder/ProcessState.cpp

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        //创建binder线程名字  binder-xxx
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\\n", name.string());
        //启动主线程循环
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

//循环线程
class PoolThread : public Thread
{
...
protected:
    virtual bool threadLoop()
    {
        //循环体
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
    
    const bool mIsMain;
};

接下来看  IPCThreadState  frameworks/native/libs/binder/IPCThreadState.cpp

        从这里就能说明每一个binder线程就对应一个IPCThreadState对象

IPCThreadState* IPCThreadState::self()
{
    //初始gHaveTLS == false
    if (gHaveTLS) {
restart:
        const pthread_key_t k = gTLS;
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        return new IPCThreadState;
    }
    ...

    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {
        int key_create_value = pthread_key_create(&gTLS, threadDestructor);
        if (key_create_value != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\\n",
                    strerror(key_create_value));
            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    //执行完毕后回到restart
    goto restart;
}

joinThreadPool

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
        //与binder驱动进行相互通信
        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);
}

总结:

1.打开binder驱动 open_driver

2.映射内存  mmap

3.启动binder线程

4.获取binder线程IPCThreadState对象

5.通知binder驱动已经进入循环

以上是关于Android Binder 应用程序Binder 启动源码分析的主要内容,如果未能解决你的问题,请参考以下文章

Android : 跟我学Binder --- C程序示例

Android面试Android跨进程通信之Binder

Android : 跟我学Binder --- 驱动情景分析

android Binder机制

Android——Binder机制

Android笔记 - Binder之数据结构