ServiceManager在init进程启动以后启动,用来管理系统中的service,那么首先理解一下在init进程启动以后启动这句话类:node
通常开机过程分为三个阶段:linux
在ServiceManager中有两个比较重要的方法:add_service和check_service,系统的service须要经过add_service把本身的信息注册到servicemanager中,当须要使用时,经过check_service检查该service是否存在。看它的main函数的源码:缓存
三件事:app
首先看一下struct binder_state这个结构体函数
struct binder_state{ int fd; //文件描述符,打开/dev/binder设备 void* mapped; //把设备文件/dev/binder映射到进程空间的起始地址 unsigned mapsize; //映射内存空间的大小 }
告诉Binder驱动程序,本身是Binder上下文管理者oop
进入循环,不停去读Binder设备,看是否有对service的请求,若是有的话就去调用svcmgr_handller函数回调处理请求。ui
下面就来看一下servicemanager是怎么循环等待客户端的请求,并进行注册服务、服务获取这一系列活动的。spa
ServiceManager进程经过binder_loop方法进入循环等待客户端的请求中,当有客户端请求时,进程ServiceManager被唤醒并调用svcmgr_handler来处理客户端的请求。线程
首先设置binder_write_read结构体变量的值,而后经过ioctl传递到Binder驱动程序中,此时控制命令为BINDER_WRITE_READ,binder_ioctl函数中对BINDER_WRITE_READ命令的处理过程为:code
在binder_thread_write方法中,对BC_ENTER_LOOPER Binder协议的处理以下:
此处仅仅设置了binder_thread结构体变量中的线程运行状态looper为BINDER_LOOPER_STATE_ENTERED,表示当前的binder线程进入循环状态。
2. 睡眠等待客户端请求
在没有客户端请求时,当前进程就进入休眠状态,等待请求到来再唤醒。
总结一哈?
ServiceManager进程的启动首先打开binder驱动并开辟内核缓存区,同时将缓存区的物理页面同时映射到内核虚拟地址空间及进程虚拟地址空间中,而后在内核中建立属于servicemanager进程的binder_node实体节点,接着设置处理客户端请求的binder线程运行状态,因为此时没有客户端的请求,servicemanager进程进入睡眠等待中,直到客户端请求的到来时,唤醒servicemanager进程,再继续往下执行。
直接来看,当有service请求时,调用的回到函数svcmgr_handler函数。
若是请求注册,就执行红色框中的代码,咱们再来看一下具体实现do_add_service()方法是怎么实现的:
看代码中的三个红框,首先会检查是否有权限注册service,若是没有权限就直接返回不能注册;而后去检查该service是否已经注册过了,若是已经注册过,那就不能再注册;再判断内存是否够用。若是都没有问题,就会注册该service,加入到svcList中来,(在servicemanager中维护service信息的地方就是svcList,里面存了service的name和handler)。经过以上几步,service就算注册成功了。
若是是服务获取,就会执行代码中的黄色框,并将返回的数据写入reply,返回给客户端,do_find_service函数中主要执行service的查找,看源码: