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接口循环读取查看是否有数据,当有数据传来时,调用回调函数添加服务,或者查询服务

posted on 2017-10-13 16:03  maogefff  阅读(336)  评论(0编辑  收藏  举报

导航