<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://www.mywiki.cn/Hovercool/index.php?action=history&amp;feed=atom&amp;title=ServiceManager</id>
	<title>ServiceManager - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://www.mywiki.cn/Hovercool/index.php?action=history&amp;feed=atom&amp;title=ServiceManager"/>
	<link rel="alternate" type="text/html" href="https://www.mywiki.cn/Hovercool/index.php?title=ServiceManager&amp;action=history"/>
	<updated>2026-09-01T03:58:52Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://www.mywiki.cn/Hovercool/index.php?title=ServiceManager&amp;diff=833&amp;oldid=prev</id>
		<title>2015年5月6日 (三) 12:00 Hovercool</title>
		<link rel="alternate" type="text/html" href="https://www.mywiki.cn/Hovercool/index.php?title=ServiceManager&amp;diff=833&amp;oldid=prev"/>
		<updated>2015-05-06T12:00:07Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;这里单纯说一下ServiceManager的Bn端，与其他服务的native不同，ServiceManager的native单纯由c实现，并没有使用binder c++中的框架结构。&lt;br /&gt;
&lt;br /&gt;
代码位于：&lt;br /&gt;
:&lt;br /&gt;
 frameworks/base/cmds/servicemanager/&lt;br /&gt;
&lt;br /&gt;
文件也很少：&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Android.mk&lt;br /&gt;
bctest.c&lt;br /&gt;
binder.c&lt;br /&gt;
binder.h&lt;br /&gt;
service_manager.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
编译时将生成  /system/bin/servicemanager，并通过init.rc启动&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
service servicemanager /system/bin/servicemanager&lt;br /&gt;
    class core&lt;br /&gt;
    user system&lt;br /&gt;
    group system&lt;br /&gt;
    critical&lt;br /&gt;
    onrestart restart healthd&lt;br /&gt;
    onrestart restart zygote&lt;br /&gt;
    onrestart restart media&lt;br /&gt;
    onrestart restart surfaceflinger&lt;br /&gt;
    onrestart restart drm&lt;br /&gt;
    onrestart restart iss_daemon&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
main函数位于 service_manager.c中：&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    struct binder_state *bs;&lt;br /&gt;
    void *svcmgr = BINDER_SERVICE_MANAGER;&lt;br /&gt;
&lt;br /&gt;
    bs = binder_open(128*1024);&lt;br /&gt;
&lt;br /&gt;
    if (binder_become_context_manager(bs)) {&lt;br /&gt;
        LOGE(&amp;quot;cannot become context manager (%s)\n&amp;quot;, strerror(errno));&lt;br /&gt;
        return -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    svcmgr_handle = svcmgr;&lt;br /&gt;
    binder_loop(bs, svcmgr_handler);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
可以看到，启动时此进程将首先通过 binder_open与binder driver通信，把所有信息（binder驱动句柄、mmap信息）都保存在 binder_state这个结构体中：&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
struct binder_state&lt;br /&gt;
{&lt;br /&gt;
    int fd;&lt;br /&gt;
    void *mapped;&lt;br /&gt;
    unsigned mapsize;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct binder_state *binder_open(unsigned mapsize)&lt;br /&gt;
{&lt;br /&gt;
    struct binder_state *bs;&lt;br /&gt;
    bs = malloc(sizeof(*bs));&lt;br /&gt;
    bs-&amp;gt;fd = open(&amp;quot;/dev/binder&amp;quot;, O_RDWR);&lt;br /&gt;
    bs-&amp;gt;mapsize = mapsize;&lt;br /&gt;
    bs-&amp;gt;mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs-&amp;gt;fd, 0);&lt;br /&gt;
    return bs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
接下来，是将自己注册成service manager:&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
int binder_become_context_manager(struct binder_state *bs)&lt;br /&gt;
{&lt;br /&gt;
    return ioctl(bs-&amp;gt;fd, BINDER_SET_CONTEXT_MGR, 0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
然后是进入 binder_loop这个循环中，开始提供服务注册/获取等相关服务。&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
void binder_loop(struct binder_state *bs, binder_handler func)&lt;br /&gt;
{&lt;br /&gt;
    int res;&lt;br /&gt;
    struct binder_write_read bwr;&lt;br /&gt;
    unsigned readbuf[32];&lt;br /&gt;
&lt;br /&gt;
    bwr.write_size = 0;&lt;br /&gt;
    bwr.write_consumed = 0;&lt;br /&gt;
    bwr.write_buffer = 0;&lt;br /&gt;
    &lt;br /&gt;
    readbuf[0] = BC_ENTER_LOOPER;&lt;br /&gt;
    binder_write(bs, readbuf, sizeof(unsigned));&lt;br /&gt;
&lt;br /&gt;
    for (;;) {&lt;br /&gt;
        bwr.read_size = sizeof(readbuf);&lt;br /&gt;
        bwr.read_consumed = 0;&lt;br /&gt;
        bwr.read_buffer = (unsigned) readbuf;&lt;br /&gt;
&lt;br /&gt;
        res = ioctl(bs-&amp;gt;fd, BINDER_WRITE_READ, &amp;amp;bwr);&lt;br /&gt;
&lt;br /&gt;
        if (res &amp;lt; 0) {&lt;br /&gt;
            LOGE(&amp;quot;binder_loop: ioctl failed (%s)\n&amp;quot;, strerror(errno));&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);&lt;br /&gt;
        if (res == 0) {&lt;br /&gt;
            LOGE(&amp;quot;binder_loop: unexpected reply?!\n&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        if (res &amp;lt; 0) {&lt;br /&gt;
            LOGE(&amp;quot;binder_loop: io error %d %s\n&amp;quot;, res, strerror(errno));&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
可以看到，在进入for循环后，这里只是不停地从 binder driver中读取其他程序给自己的数据，然后通过 binder_parse进行处理。&lt;br /&gt;
&lt;br /&gt;
我们知道，所有的binder数据传输都是从客户端由 BC_TRANSACTION发起，到本地端对应的接收到 BR_TRANSACTION，这里我们就只看　BR_TRANSACTION这个最重要的case：&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
int binder_parse(struct binder_state *bs, struct binder_io *bio,&lt;br /&gt;
                 uint32_t *ptr, uint32_t size, binder_handler func)&lt;br /&gt;
{&lt;br /&gt;
    int r = 1;&lt;br /&gt;
    uint32_t *end = ptr + (size / 4);&lt;br /&gt;
&lt;br /&gt;
    while (ptr &amp;lt; end) {&lt;br /&gt;
        uint32_t cmd = *ptr++;&lt;br /&gt;
&lt;br /&gt;
        switch(cmd) {&lt;br /&gt;
        case BR_TRANSACTION: {&lt;br /&gt;
            struct binder_txn *txn = (void *) ptr;&lt;br /&gt;
            if (func) {&lt;br /&gt;
                unsigned rdata[256/4];&lt;br /&gt;
                struct binder_io msg;&lt;br /&gt;
                struct binder_io reply;&lt;br /&gt;
                int res;&lt;br /&gt;
&lt;br /&gt;
                bio_init(&amp;amp;reply, rdata, sizeof(rdata), 4);&lt;br /&gt;
                bio_init_from_txn(&amp;amp;msg, txn);&lt;br /&gt;
                res = func(bs, txn, &amp;amp;msg, &amp;amp;reply);&lt;br /&gt;
                binder_send_reply(bs, &amp;amp;reply, txn-&amp;gt;data, res);&lt;br /&gt;
            }&lt;br /&gt;
            ptr += sizeof(*txn) / sizeof(uint32_t);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return r;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
这里首先从 ptr中取出 cmd（比如这里就是 BR_TRANSACTION）,然后将剩余的数据转化为 binder_txn；&lt;br /&gt;
&lt;br /&gt;
而通过学习 binder driver可以知道，binder数据的传输结构为 binder_write_read，其中 write_buffer和 read_buffer成员指向的数据正是 cmd + binder_transaction_data，那这里 binder_transaction_data可以直接转换成 binder_txn吗？&lt;br /&gt;
&lt;br /&gt;
我们来对比一下这两者的定义：&lt;br /&gt;
:&lt;br /&gt;
&amp;lt;pre class=&amp;quot;prettyprint&amp;quot;&amp;gt;&lt;br /&gt;
struct binder_transaction_data {&lt;br /&gt;
	union {&lt;br /&gt;
		__u32	handle;	/* target descriptor of command transaction */&lt;br /&gt;
		binder_uintptr_t ptr;	/* target descriptor of return transaction */&lt;br /&gt;
	} target;&lt;br /&gt;
	binder_uintptr_t	cookie;	/* target object cookie */&lt;br /&gt;
	__u32		code;		/* transaction command */&lt;br /&gt;
&lt;br /&gt;
	__u32	        flags;&lt;br /&gt;
	pid_t		sender_pid;&lt;br /&gt;
	uid_t		sender_euid;&lt;br /&gt;
	binder_size_t	data_size;	/* number of bytes of data */&lt;br /&gt;
	binder_size_t	offsets_size;	/* number of bytes of offsets */&lt;br /&gt;
	union {&lt;br /&gt;
		struct {&lt;br /&gt;
			binder_uintptr_t	buffer;&lt;br /&gt;
			binder_uintptr_t	offsets;&lt;br /&gt;
		} ptr;&lt;br /&gt;
		__u8	buf[8];&lt;br /&gt;
	} data;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct binder_txn&lt;br /&gt;
{&lt;br /&gt;
    void *target;&lt;br /&gt;
    void *cookie;&lt;br /&gt;
    uint32_t code;&lt;br /&gt;
    uint32_t flags;&lt;br /&gt;
&lt;br /&gt;
    uint32_t sender_pid;&lt;br /&gt;
    uint32_t sender_euid;&lt;br /&gt;
&lt;br /&gt;
    uint32_t data_size;&lt;br /&gt;
    uint32_t offs_size;&lt;br /&gt;
    void *data;&lt;br /&gt;
    void *offs;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hovercool</name></author>
	</entry>
</feed>