其实init进程启动后,ServiceManager进程的启动,远比zygote要早,因为在启动zygote进程时需要用到ServiceManager进程的服务。ServiceManager是一个守护进程,它维护着系统服务和客户端的binder通信。
在Android系统中用到最多的通信机制就是Binder,Binder主要由Client、Server、ServiceManager和Binder驱动程序组成。其中Client、Service和ServiceManager运行在用户空间,而Binder驱动程序运行在内核空间。核心组件就是Binder驱动程序了,而ServiceManager提供辅助管理的功能,无论是Client还是Service进行通信前首先要和ServiceManager取得联系。而ServiceManager是一个守护进程,负责管理Server并向Client提供查询Server的功能。
init.rc中的声明
在init.rc中servicemanager是作为服务启动的。service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
servicemanager的main函数
源码位置在frameworks/base/cmds/servicemanager/service_manager.c,它的main函数如下:int main(int argc, char **argv)
{
struct binder_state *bs;
//宏:#define BINDER_SERVICE_MANAGER ((void*)0)。表示ServiceManager对应的句柄为0,表面自己是服务器管理者。其他的Server进程句柄值都是大于0的。
void *svcmgr = BINDER_SERVICE_MANAGER;
//打开Binder设备,映射128K的内存地址空间
bs = binder_open(128*1024);
//告诉Binder驱动程序自己是Binder上下文管理者
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
//ServiceManager对应的句柄赋值
svcmgr_handle = svcmgr;
//进入一个无线循环,充当server角色,等待Client的请求
binder_loop(bs, svcmgr_handler);
return 0;
}
binder_open函数
binder_open(unsigned mapsize)函数源码位置在frameworks/base/cmds/servicemanager/Binder.cbinder_open(unsigned mapsize)函数最终返回的类型为binder_state*,里面记录着刚刚打开的binder驱动文件句柄以及mmap()映射到的最终目标地址。
struct binder_state
{
int fd; // 文件描述符,打开的/dev/binder设备
void* mapped; // 把设备文件/dev/binder映射到进程空间的起始地址
unsigned mapsize; // 映射内存空间的大小
};
这个结构体也是在Binder.c中定义的。binder_open(unsigned mapsize)函数代码如下:
struct binder_state *binder_open(unsigned mapsize)
{
struct binder_state *bs;
bs = malloc(sizeof(*bs));
if (!bs) {
errno = ENOMEM;
return 0;
}
//打开/dev/binder驱