Android考虑到移动设备耗电以及跨进程通信效率等因素,基于OpenBinder专门为进程通信开发了一套框架:binder。例如,客户端程序需要获取WindowManager,TelephonyManager等系统服务时,就需要通过binder这个中介来负责数据与指令的传输。那么,Android提供了如此多的系统服务(可达上百个,可通过 adb shell service list查看),又是谁在负责管理这些服务了?Android为此专门提供了一个系统管家servicemanagerservicemanager主要负责添加服务,获取服务,查找服务以及当某个服务意外终止时,对该服务的资源进行回收。ServiceManager跨越了两个框架层:Java层、C++层。这篇文章先看一看native(C)层的具体实现原理。

源码路径:

  • C++: /android/frameworks/native/cmds/servicemanager/
  • Java: /android/frameworks/base/core/java/android/os/

servicemanager的启动

Android在init进程启动以后,通过脚本init.rc,启动ServiceManager:

    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 keystore

service_manager.c中找到对应的main()函数,这是servicemanager启动的入口:

    int main()    {        struct binder_state *bs;        // 打开binder        bs = binder_open(128*1024);        if (!bs) {            ALOGE("failed to open binder driver\n");            return -1;        }        // 成为系统服务的管家        if (binder_become_context_manager(bs)) {            ALOGE("cannot become context manager (%s)\n", strerror(errno));            return -1;        }        ....        // 进入binder循环        binder_loop(bs, svcmgr_handler);        return 0;    }

main函数里主要做了三件事:一是打开binder文件节点,并分配IPC所需的内存;二让ServiceManager成为系统服务的管家(context manager);三开启相应的工作线程,并循环处理IPC请求。

binder_open

函数binder_open()主要作用:(1)打开binder设备文件,获取到对应的文件描述符,(2)从Binder驱动获取binder版本号,(3)接着创建一个binder内存区域,用于跨进程数据的交换(这里大小为128K)。

    struct binder_state *binder_open(size_t mapsize)    {        struct binder_state *bs;        struct binder_version vers;        // 为binder_state分配内存空间        bs = malloc(sizeof(*bs));        if (!bs) {            errno = ENOMEM;            return NULL;        }        // 打开Binder驱动对应的文件节点,最终调用驱动函数binder_open        bs->fd = open("/dev/binder", O_RDWR | O_CLOEXEC);        // 获取当前Binder版本号        if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||            (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {            fprintf(stderr,                    "binder: kernel driver version (%d) differs from user space version (%d)\n",                    vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);            goto fail_open;        }        //分配一块只读内存区域,用于IPC交换数据,最终调用binder驱动接口binder_mmap        bs->mapsize = mapsize;        bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);        if (bs->mapped == MAP_FAILED) {            fprintf(stderr,"binder: cannot map device (%s)\n",                    strerror(errno));            goto fail_map;        }        return bs;        fail_map:            close(bs->fd);        fail_open:            free(bs);            return NULL;    }

binder相关的ioctl指令定义在 /android/kernel/drivers/staging/android/uapi/binder.h

    #define BINDER_WRITE_READ       _IOWR('b', 1, struct binder_write_read)    #define BINDER_SET_IDLE_TIMEOUT     _IOW('b', 3, __s64)    #define BINDER_SET_MAX_THREADS      _IOW('b', 5, __u32)    #define BINDER_SET_IDLE_PRIORITY    _IOW('b', 6, __s32)    #define BINDER_SET_CONTEXT_MGR      _IOW('b', 7, __s32)    #define BINDER_THREAD_EXIT      _IOW('b', 8, __s32)    #define BINDER_VERSION          _IOWR('b', 9, struct binder_version)

binder驱动提供了诸如ioctl,mmap,open,flush等操作,在驱动初始化时会将其注册到系统中

    static const struct file_operations binder_fops = {    .owner = THIS_MODULE,    .poll = binder_poll,    .unlocked_ioctl = binder_ioctl,    .compat_ioctl = binder_ioctl,    .mmap = binder_mmap,    .open = binder_open,    .flush = binder_flush,    .release = binder_release,    };    static struct miscdevice binder_miscdev = {        .minor = MISC_DYNAMIC_MINOR,        .name = "binder",        .fops = &binder_fops    };

binder_become_context_manager

    int binder_become_context_manager(struct binder_state *bs)    {        // 系统调用,告知binder驱动,ServiceManager将成为系统服务管家,对应的handle为0        return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);    }

系统调用ioctl最终会调用binder驱动对应的操作函数。查看binder驱动的代码,在/android/kernel/drivers/staging/android/binder.c中有一个函数binder_ioctl,这就是用于处理kernel系统调用ioctl对应的指令,找到请求BINDER_SET_CONTEXT_MGR对应的代码,在设置系统服务管家完成后,返回对应的结果。

    static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)    {        int ret;        struct binder_proc *proc = filp->private_data;        struct binder_thread *thread;        unsigned int size = _IOC_SIZE(cmd);        void __user *ubuf = (void __user *)arg;        ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);        // 加锁        binder_lock(__func__);        thread = binder_get_thread(proc);        switch (cmd) {            ....            // 设置服务管家            case BINDER_SET_CONTEXT_MGR:                ret = binder_ioctl_set_ctx_mgr(filp);                if (ret)                    goto err;                break;            ....            // 查询Binder版本            case BINDER_VERSION: {                struct binder_version __user *ver = ubuf;                if (put_user_preempt_disabled(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) {                    ret = -EINVAL;                    goto err;                }                break;            }            default:                ret = -EINVAL;                goto err;        }        ret = 0;        ....    }

binder_loop

    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;        // 让ServiceManager线程进入循环        binder_write(bs, readbuf, sizeof(uint32_t));        for (;;) {            bwr.read_size = sizeof(readbuf);            bwr.read_consumed = 0;            bwr.read_buffer = (uintptr_t) readbuf;            // 读取 driver中的数据            res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);            // 解析读取到的数据,并通过svcmgr_handler进行处理            res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);            ....        }    }

读取到binder驱动缓冲区域里的数据后,解析之:

    int binder_parse(struct binder_state *bs, struct binder_io *bio,                     uintptr_t ptr, size_t size, binder_handler func)    {        int r = 1;        uintptr_t end = ptr + (uintptr_t) size;        while (ptr < end) {            uint32_t cmd = *(uint32_t *) ptr;            ptr += sizeof(uint32_t);            switch(cmd) {            case BR_NOOP:                break;            case BR_TRANSACTION_COMPLETE:                break;            case BR_INCREFS:            case BR_ACQUIRE:            case BR_RELEASE:            case BR_DECREFS:                ptr += sizeof(struct binder_ptr_cookie);                break;            case BR_TRANSACTION: {                struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;                ....                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);                    // 处理客户端请求,func就是函数svcmgr_handler                    res = func(bs, txn, &msg, &reply);                    if (txn->flags & TF_ONE_WAY) {                        binder_free_buffer(bs, txn->data.ptr.buffer);                    } else {                        // 发送回复给客户端                        binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);                    }                }                ptr += sizeof(*txn);                break;            }            case BR_REPLY: {                struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;                if ((end - ptr) < sizeof(*txn)) {                    ALOGE("parse: reply too small!\n");                    return -1;                }                binder_dump_txn(txn);                if (bio) {                    bio_init_from_txn(bio, txn);                    bio = 0;                } else {                    /* todo FREE BUFFER */                }                ptr += sizeof(*txn);                r = 0;                break;            }            case BR_DEAD_BINDER: {                struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;                ptr += sizeof(binder_uintptr_t);                death->func(bs, death->ptr);                break;            }            case BR_FAILED_REPLY:                r = -1;                break;            ....            default:                ALOGE("parse: OOPS %d\n", cmd);                return -1;            }        }        return r;    }

svcmgr_handler处理客户端的请求,如添加服务,查找服务以及获取服务等。

    int svcmgr_handler(struct binder_state *bs,                       struct binder_transaction_data *txn,                       struct binder_io *msg,                       struct binder_io *reply)    {        struct svcinfo *si;        uint16_t *s;        size_t len;        uint32_t handle;        uint32_t strict_policy;        int allow_isolated;        if (txn->target.ptr != BINDER_SERVICE_MANAGER)            return -1;        if (txn->code == PING_TRANSACTION)            return 0;           ....        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(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;            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, txn->sender_euid)) {                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;    }

这里总结下ServiceManager进程启动的过程,其流程简图如下:

  • binder_open(): 打开驱动设备节点,并为进程分配一个128K大小的内存区域用于IPC数据交换;
  • binder_become_context_manager(): 使servicemanager称为系统服务的管家;
  • binder_loop(): 进入线程执行状态,等待客户端程序的请求

参考文献

  • http://gityuan.com/android/

更多相关文章

  1. Android启动脚本init.rc
  2. 对Android体系结构的理解--后续会补充
  3. android L 启动流程
  4. Service深入分析
  5. android窗口管理机
  6. Android之——AIDL深入
  7. Android(安卓)AIDL示例
  8. 对Android体系结构的理解--后续会补充
  9. Android系统服务-WindowManager

随机推荐

  1. Matlab基本语法5
  2. NPOI 导入XLS文件报错
  3. Matlab基本语法7
  4. scrapy-redis爬虫如何发送POST请求
  5. 9.0 Ansible 图形界面-Tower
  6. JS获取指定字符串中出现次数最多的字符及
  7. vivo 应用商店中的断点续传技术剖析
  8. Konga面板安装
  9. 戴尔服务器安装centos,以及esxi虚拟化,给pe
  10. 如何处理Linux服务器内存过高?