i.mx6 Android5.1.1 servicemanager本地服务
接在之前的
i.mx6 Android5.1.1 初始化流程之init进程
i.mx6 Android5.1.1 初始化流程之init.rc解析
servicemanager是由init创建的本地服务,是binder的守护进程。
主要用来管理开发者创建的各种Server,并且向Client提供查询Server远程接口的功能。
#名字为servicemanager的服务,可执行文件的路径在/system/bin/servicemanager #属于core类,用户为:system,用户组为:system #critical:如果在几分钟内一直没响应则重启服务 #重启servicemanager需要冲入如下的服务healthd,zygote,media,surfaceflinger,drm service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart healthd onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm
可以得知其路径在/system/bin/servicemanager
查看android.mk
include $(CLEAR_VARS) LOCAL_SHARED_LIBRARIES := liblog libselinux LOCAL_SRC_FILES := service_manager.c binder.c LOCAL_CFLAGS += $(svc_c_flags) LOCAL_MODULE := servicemanager include $(BUILD_EXECUTABLE)
可以得知,就是在service_manager.c
int main(int argc, char **argv) { struct binder_state *bs; //打开binder设备驱动文件,并将Binder设备文件映射到servicemanger进程的地址空间中 bs = binder_open(128*1024); if (!bs) { ALOGE("failed to open binder driver\n"); return -1; } //在binder驱动层设置服务管理者角色 if (binder_become_context_manager(bs)) { ALOGE("cannot become context manager (%s)\n", strerror(errno)); return -1; } selinux_enabled = is_selinux_enabled(); sehandle = selinux_android_service_context_handle(); if (selinux_enabled > 0) { 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(); } } union selinux_callback cb; 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); //接收到请求后的需要执行的回调函数 svcmgr_handle = BINDER_SERVICE_MANAGER; //进入binder.c循环,等待客户请求 binder_loop(bs, svcmgr_handler); return 0; }
struct binder_state *binder_open(size_t mapsize) { 。。。 //打开设备节点 bs->fd = open("/dev/binder", O_RDWR); 。。。
//映射 bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); 。。。 }
再看看直接的那个回调函数
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
。。。
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
//查找相关的服务,如果有,则返回其句柄
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0;
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
//想servicemanager添加服务
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break;
case SVC_MGR_LIST_SERVICES: {
uint32_t n = bio_get_uint32(msg);
if (!svc_can_list(txn->sender_pid)) {
ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
txn->sender_euid);
return -1;
}
si = svclist;
while ((n-- > 0) && si)
si = si->next;
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
void binder_loop(struct binder_state *bs, binder_handler func) { int res; struct binder_write_read bwr; uint32_t readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0; readbuf[0] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof(uint32_t)); for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (uintptr_t) readbuf; //读取binder节点数据 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0) { ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno)); break; } //解析 res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); if (res == 0) { ALOGE("binder_loop: unexpected reply?!\n"); break; } if (res < 0) { ALOGE("binder_loop: io error %d %s\n", res, strerror(errno)); break; } } }
int binder_parse(struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func) { 。。。 switch(cmd) { 。。。 binder_dump_txn(txn); if (func) { unsigned rdata[256/4]; struct binder_io msg; struct binder_io reply; int res; bio_init(&reply, rdata, sizeof(rdata), 4); bio_init_from_txn(&msg, txn);
//注意:这个是之前我们传进来的回调函数 res = func(bs, txn, &msg, &reply); binder_send_reply(bs, &reply, txn->data.ptr.buffer, res); } ptr += sizeof(*txn); break; } 。。。default: ALOGE("parse: OOPS %d\n", cmd); return -1; } } return r; }
小结:
1.申请一段内存,打开设备节点/dev/binder,同时将内存映射到内核中用来给binder使用
2.将自己设置为服务管理者
3.通过binder接口循环读取查看是否有数据,当有数据传来时,调用回调函数添加服务,或者查询服务