1.servicemanager与binder之间的关系
-
ServiceManager的角色
- ServiceManager是Android系统中的核心服务管理器,负责管理系统级的服务,如ActivityManager、PackageManager、WindowManager等。
- 它是一个Binder服务,handle固定为0。
- ServiceManager提供注册服务和查询服务的功能。应用程序相要通过Binder向一个service发送数据,必须先通过ServiceManager获取该service的handle,然后才能通过Binder驱动与service通信。
- ServiceManager运行在一个独立进程当中,由init进程负责启动,属于系统关键服务,一旦异常退出,系统会尝试重启它。
-
Binder的角色:
- Binder是Android系统中的一个进程间通信(IPC)机制,它允许不同进程之间相互调用方法和传递数据。
- Binder的核心是Binder驱动程序,它负责管理不同进程之间的通信。
- 每个进程都可以创建自己的Binder对象作为服务提供者,也可以获取其他进程提供的Binder对象作为客户端使用。
- 在Android开发中,可以通过AIDL(Android Interface Definition Language)来定义自己的Binder接口,并实现相应的服务提供者和客户端。
-
ServiceManager与Binder的协作:
- ServiceManager是Binder通信机制的核心,扮演了Binder通信机制上下文管理者的角色。
- 客户端可以从ServiceManager获取Binder服务,服务端可以注册Binder服务。
- 当一个服务通过Binder注册到ServiceManager时,ServiceManager会保存该服务的引用,并允许其他进程通过Binder机制与之通信。
- 应用程序通过Binder与服务通信时,首先需要通过ServiceManager获取服务的handle,然后使用这个handle与服务进行通信。
2.servicemanager启动,通过init.rc启动servicemanager.rc
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
writepid /dev/cpuset/system-background/tasks
shutdown critical
//rc文件解析
service servicemanager /system/bin/servicemanager
这定义了一个名为servicemanager的服务。
该服务的可执行文件位于/system/bin/servicemanager。
class core animation
这将servicemanager服务分类为core和animation类别。这通常用于系统内部,以决定服务的启动顺序和依赖关系。
user system group system readproc
这指定了servicemanager服务的运行用户和组。在这里,它以system用户身份运行,并属于system和readproc组。
readproc组通常允许服务读取其他进程的信息。
critical
这表示servicemanager是一个关键服务。如果它崩溃或停止,系统可能会变得不稳定或不可操作。
onrestart ... restart ...
这些指令指定了当servicemanager服务重启时,哪些其他服务也应该被重启。
例如,当servicemanager重启时,healthd、zygote、audioserver等也会重启。
writepid /dev/cpuset/system-background/tasks
这将servicemanager的PID(进程ID)写入/dev/cpuset/system-background/tasks文件。这通常与CPU集(cpuset)有关,用于限制或分配进程到特定的CPU或CPU集。
shutdown critical
这表示在系统关闭时,servicemanager被视为一个关键服务。这可能意味着在关闭过程中,系统会特别关注此服务的状态或行为。
接下来看下servicemanager里面作了什么
源码路径:frameworks/native/cmds/servicemanager/service_manager.c,看看他的main方法里面做了什么
int main(int argc, char** argv)
{
struct binder_state *bs;
union selinux_callback cb;
char *driver;
if (argc > 1) {
driver = argv[1];
} else {
driver = "/dev/binder";
}
bs = binder_open(driver, 128*1024);//打开binder驱动,分配内存
if (!bs) {
#ifdef VENDORSERVICEMANAGER
ALOGW("failed to open binder driver %s\n", driver);
while (true) {
sleep(UINT_MAX);
}
#else
ALOGE("failed to open binder driver %s\n", driver);
#endif
return -1;
}
if (binder_become_context_manager(bs)) {
//告诉binder驱动,自己是servicemanager(注册dns服务器)
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
cb.func_log = selinux_log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
#ifdef VENDORSERVICEMANAGER
sehandle = selinux_android_vendor_service_context_handle();
#else
sehandle = selinux_android_service_context_handle();
#endif
selinux_status_open(true);
if (sehandle == NULL) {
ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
abort();
}
if (getcon(&service_manager_context) != 0) {
ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
abort();
}
可以看见在service_manager.c的main方法里面主要做了三件事,一、首先就是打开binder驱动,并分配内存空间 二、告诉binder驱动自己是servicemanager 三、启动binder循环接下来逐一分析下这三步的具体实现
(1)binder_open
struct binder_state *binder_open(const char* driver, size_t mapsize)
{
struct binder_state *bs;
struct binder_version vers;
bs = malloc(sizeof(*bs));
if (!bs) {
errno = ENOMEM;
return NULL;
}
bs->fd = open(driver, O_RDWR | O_CLOEXEC);//打开驱动
if (bs->fd < 0) {
fprintf(stderr,"binder: cannot open %s (%s)\n",
driver, strerror(errno));
goto fail_open;
}
if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -