您的位置:首页 > 其它

binder源码分析(一)

2020-04-01 18:51 316 查看

前言

接触Android的时候就对binder有所耳闻,作为进程间通信的工具,binder驱动,拷贝数据的次数少,也不是太复杂,前段时间看来了些源码,自己尝试分析了之后还是受益匪浅,写下来,日后也可以看看回顾一下。

这里也是servicemanager开始,串一遍注册和获取服务的过程,分析一下binder的源码。

servicemanager

  1. 首先是servicemanager的注册,值得注意的是,servicemanager不是java程序,是用C跑的。
servicemanager.c
int main(int argc, char** argv)
{
struct binder_state *bs;
union selinux_callback cb;
char *driver;

if (argc > 1) {
driver = argv[1];
} else {
driver = "/dev/binder";
}

bs = binder_open(driver, 128*1024);
//建立起内存映射等
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}

...(selinux相关)

binder_loop(bs, svcmgr_handler);

return 0;
}
  1. binder_become_context_manager()中进行ioctl(),cmd为BINDER_SET_CONTEXT_MGR,ioctl调用binder_ioctl_set_ctx_mgr(),新建binder_node并赋值给context->binder_context_mgr_node(service_manager的节点)
  2. binder_loop()先调用ioctl(),cmd为BC_ENTER_LOOPER,将当前线程(service_manager)thread->looper设置为BINDER_LOOPER_STATE_ENTERED。接着开始调用binder_ioctl读取binder中的消息,注意这里write_size为0,read_size非0,进入binder_thread_read后因为当前没有任务会阻塞。
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);

... // log

res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
if (res == 0) {
ALOGE("binder_loop: unexpected reply?!\n");
break;
}
...
}
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
ljt326053002 发布了6 篇原创文章 · 获赞 0 · 访问量 113 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: