0、总体流程四部
开机由init进程解析init.rc文件启动servicemanager.rc。启动会调用main.cpp的main函数
main函数里面主要做了以下几件事 :
1.1 打开/dev/binder设备;
1.2 通过mmap映射设备的内存空间到ServiceManager进程中。
1.3 设置ServiceManager为context manager。
1.4 ServiceManager服务进入循环,等待接收数据来进行处理
int main(int argc, char** argv) {if (argc > 2) {LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";}const char* driver = argc == 2 ? argv[1] : "/dev/binder";//1.打开/dev/binder设备;2.并且通过mmap映射设备的内存空间到SM进程中sp<ProcessState> ps = ProcessState::initWithDriver(driver);ps->setThreadPoolMaxThreadCount(0);ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {LOG(ERROR) << "Could not self register servicemanager";}//3. 设置SM为context managerIPCThreadState::self()->setTheContextObject(manager);ps->becomeContextManager();//4. 进入循环,等待接收数据来进行处理sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);BinderCallback::setupTo(looper);ClientCallbackCallback::setupTo(looper, manager);while(true) {looper->pollAll(-1);}return EXIT_FAILURE;}
1、打开设备
相关构造ProcessState()-------->open_driver(driver)、 mmap()
ProcessState::ProcessState(const char *driver): mDriverName(String8(driver)), mDriverFD(open_driver(driver)) //***open_driver(driver)......, mCallRestriction(CallRestriction::NONE){if (mDriverFD >= 0) {//***mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);if (mVMStart == MAP_FAILED) {ALOGE("Using %s failed: unable to mmap transaction memory.\n", close(mDriverFD);......}}}
open_driver()打开设备文件,主要是通过ioctl()向binder驱动查询并设置了一些信息,比如:
版本:BINDER_VERSION, 设置最大线程 BINDER_SET_MAX_THREADS 等等。
static int open_driver(const char *driver)
380 {
381 int fd = open(driver, O_RDWR | O_CLOEXEC);
382 if (fd >= 0) {
383 int vers = 0;
384 status_t result = ioctl(fd, BINDER_VERSION, &vers);
385 //...
396 size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
397 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
398 //...
401 uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
402 result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
403
406 } else {
407 ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
408 }
409 return fd;
410 }
2、从binder设备的内存空间映射到SM进程里
//kernel/drivers/android/binder.c
static int binder_mmap(struct file *filp, struct vm_area_struct *vma){int ret;struct binder_proc *proc = filp->private_data;if(proc->tsk != current->group_leader)return -EINVAL;if((vma->vm_end - vma->vm_start) > SZ_4M)vma->vm_end = vma->vm_start +SZ_4M;...if(vma->vm_flags & FORBIDDEN_MMAP_FLAGS){ret = -EPERM;failure_string = "bad vm_flags"goto err_bad_arg;}vma->vm_flags |= VM_DONTCOPY | VM_MIXEDMAP;vma->vm_flags &= ~VM_MAYWRITE;vma->vm_ops = &binder_vm_ops;vma->vm_private_data = proc;ret = binder_alloc_mmap_handler(&proc->alloc, vma);if(ret)return ret;return 0;
}
3、设置为context manager
创建manager,并且把自己设置到SM中
sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {LOG(ERROR) << "Could not self register servicemanager";}
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder) {
mNameToService[name] = Service {.binder = binder,.allowIsolated = allowIsolated,.dumpPriority = dumpPriority,.debugPid = ctx.debugPid,};
ioctl()通过BINDER_SET_CONTEXT_MGR命令,将SM设置到binder驱动中
//frameworks/native/libs/binder/ProcessState.cpp
bool ProcessState::becomeContextManager()
{AutoMutex _l(mLock);flat_binder_object obj {.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,};......int unused = 0;result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &unused);return result == 0;
}
4、 设置SM循环
//frameworks/native/cmds/servicemanager/main.cppint main(int argc, char** argv) {......sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);BinderCallback::setupTo(looper);ClientCallbackCallback::setupTo(looper, manager);while(true) {looper->pollAll(-1);}// should not be reachedreturn EXIT_FAILURE;}