1.启动ServiceManager

ServiceManager是BinderIPC通信过程的守护进程。之前讨论的四大组件的启动过程中AMS,就是由ServiceManager来管理。
ServiceManager启动,顾名思义是系统启动的一部分。
系统启动1
系统启动2
Zygote启动
Zygote启动2
以上过程就是系统启动和zygote启动的过程。
接下来就是androidFramework的启动,而framework启动最重要的就是
ServiceManager的启动。

2.启动过程分析

以下分析都是基于android8的源码

2.1 init过程注册

service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    ...

这是service_manager.rc文件

2.2 main

framework/native/cmds/servicemanager/service_manager.c

int main(int argc, char** argv)
{
    ...
    bs = binder_open(driver, 128*1024);
    ...
    if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    ...
    binder_loop(bs, svcmgr_handler);
    return 0;
}

启动过程3大阶段

  • 启动Binder驱动程序binder_open
  • 注册binder服务管家:binder_become_context_manager
  • loop,处理client端发送来的请求:binder_loop

2.2 binder_open

framework/native/cmds/servicemanager/binder.c

struct binder_state *binder_open(const char* driver, size_t mapsize)
{
    ...
    bs->fd = open(driver, O_RDWR | O_CLOEXEC);
    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;
    }
    ...
    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    ...
    return bs;

fail_map:
    close(bs->fd);
fail_open:
    free(bs);
    return NULL;
}

整个binder驱动开启就2部分

  • 打开虚拟驱动文件,该方法回创建一个binder_proc对象
  • ioctl是驱动的读写方法。这里检验binder的版本和binder驱动版本是否一致。
  • mmap是内存映射,该方法回创建binder_buffer对象,并给予binder_proc对象的proc_buffers链表。

    2.3 binder_state

    framework/native/cmds/servicemanager/binder.c

    struct binder_state
    {
    int fd; //dev/binder的文件描述符
    void *mapped;   //指向mmap的内存地址
    size_t mapsize;     //分配的内存大小,默认为128KB
    };

2.4 binder_become_context_manager

framework/native/cmds/servicemanager/binder.c

int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

成为上下文的管理者,整个系统中只有一个这样的管理者。 通过ioctl()方法经过系统调用,对应于Binder驱动层的binder_ioctl()方法.

2.5 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;
    binder_write(bs, readbuf, sizeof(uint32_t));

    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;

        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;
        }
    }
}

进入循环读写操作,参数func指向svcmgr_handler.
首先通知kernel,进入BC_ENTER_LOOPER状态,也就是消息循环状态。然后就是等待client端的消息输入。
可以参照handler机制,这个时候进入中断等待状态,直到消息来临,read消息。
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
然后解析消息,最后call func。

2.6 svcmgr_handler

让我们回故下serviceManager主要是干什么的。
从binder机制来说,这个ServiceManager主要干的就是注册和获取server端。或者说是binder机制的server端。

int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    ...
    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;
}

从上面的switch语句,看到了handler的内容就是注册和获取service。

到这里ServiceManager启动过程完成了。

参考

发表评论

电子邮件地址不会被公开。 必填项已用*标注