文章目录
一、系统服务
二、系统服务主函数
三、开启 Binder
四、注册上下文
五、开启 Binder 循环
六、binder_write 方法
七、binder_ioctl 内核方法
八、binder_ioctl_write_read 内核方法
一、系统服务
System Server 是由 Zygote 进程 fork() 出来的 ;
Init 进程 启动 Zygote , Zygote 启动 System Server 进程 ;
System Server 注册服务时 , 会执行 service_manager.c 中的方法 ;
二、系统服务主函数
service_manager.c 从 int main(int argc, char** argv) 方法开始执行 , 在该 main 函数中 , 执行了 3 33 个重要操作 :
① 开启 Binder : 获取 Binder 驱动 , 并且申请了 128 KB 的内存映射地址 , bs = binder_open(driver, 128*1024); ;
② 注册上下文 : 将自己注册成 Binder 进程的上下文 , binder_become_context_manager(bs) ;
③ 开启 Binder 循环 : 不停的轮询 , 是否有消息发送 , binder_loop(bs, svcmgr_handler); ;
int main(int argc, char** argv) { // 开启 Binder , 获取 Binder 驱动 , 并且申请了 128 KB 的内存映射地址 bs = binder_open(driver, 128*1024); // 将自己注册成 Binder 进程的上下文 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; }
完整代码参考 /frameworks/native/cmds/servicemanager/service_manager.c ;
三、开启 Binder
通过调用 bs = binder_open(driver, 128*1024); 开启 Binder 的方法 struct binder_state *binder_open(const char* driver, size_t mapsize) , 定义在 /frameworks/native/cmds/servicemanager/binder.c 中 ;
首先分析下 binder_state 结构体 , 其中有 3 33 个参数 ,
int fd : Binder 驱动的文件描述
void *mapped : 内存映射首地址
size_t mapsize : 内存映射的大小 , 128 KB
方法最终返回一个 binder_state 结构体 ;
struct binder_state { int fd; // Binder 驱动的文件描述 void *mapped; // 内存映射首地址 size_t mapsize; // 内存映射的大小 , 128 KB }; // 打开 Binder , 并获取 Binder 的状态描述 struct binder_state *binder_open(const char* driver, size_t mapsize) { struct binder_state *bs; // 返回的结构体 struct binder_version vers; bs = malloc(sizeof(*bs)); // 为返回值申请内存 if (!bs) { errno = ENOMEM; return NULL; } bs->fd = open(driver, O_RDWR | O_CLOEXEC); if (bs->fd < 0) { fprintf(stderr,"binder: cannot open %s (%s)\n", driver, strerror(errno)); goto fail_open; } 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); 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; }
完整代码参考 /frameworks/native/cmds/servicemanager/binder.c#97;
四、注册上下文
通过调用 binder_become_context_manager(bs) , 将自己注册成 Binder 进程的上下文 ; 其中调用的 ioctl 方法是内核中的方法 , 这是 IO Control 的简称 ; 这个代码得去内核中查找 ;
int binder_become_context_manager(struct binder_state *bs) { return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); }
完整代码参考 /frameworks/native/cmds/servicemanager/binder.c#147
在 【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 ) 博客中分析了该 ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0) 方法对应的源码 ;
五、开启 Binder 循环
在 service_manager.c 的 main 函数中 , 调用 binder_loop(bs, svcmgr_handler) 开启 Binder 循环 ;
binder_loop 方法定义在 /frameworks/native/cmds/servicemanager/binder.c 中 ;
在 binder_loop 方法中 , 先调用了 binder_write 方法 , 然后开启了死循环 ;
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; } // 如果收到 Binder 读写消息信息 , 调用 binder_parse 方法处理 ; 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; } } }
完整代码参考 /frameworks/native/cmds/servicemanager/binder.c ;