Binder Q&A

binder mmap 的内存是每个进程独立的吗?会存在拷贝?

是独立的(1MB - 8KB),用于接收数据。发送 BC_TRANSACTION/BC_REPLY (请求/回包)的时候拷贝buffer(参数)和 offsets(参数中binder对象的偏移)到目标进程的 mmap 内存区,只拷贝这一次。

如果所有进程共享这部分内存,要 mmap 更大的用户内存空间满足同等吞吐量,而且非常不安全,因为任意进程都能读并猜测其他进程传输的数据

说是说一次拷贝,但是读数据时(talkWithDriver)是用 Parcel 承载数据的啊,不用再拷贝一下吗?

那是包头,固定大小的。buffer 和 offsets 是跨进程一次拷贝,这个长度可变的才是最闹心的。

BINDER_SET_MAX_THREADS 限制的是谁的线程数?

ProcessState.cpp : open_driver 将这个值设置为 15

限制的是当前进程的 loop 线程(循环取 binder 请求并执行的线程)个数
这个线程数不包含用户主动启动的loop线程(spawnPooledThread(true)),MediaPlayerService 就主动启动了两个,所以它最多将会有17个 loop 线程。

当 binder_thread_read 发现当前进程的所有的 loop 线程都在干活(没活干的时候会在 binder_thread_read 中 wait,有统计这些"闲人"的个数),会将回包中第一条BR_NOOP(自动插的,上层自动忽略这条命令)换成 BR_SPAWN_LOOPER 命令,调用者读到该指令会启动一个新 loop 线程(spawnPooledThread(false))

service_manager.c

负责注册查询所有命名 binder,是单线程的纯C程序,没有使用 ProcessState IPCThreadState 等 C++ 封装对象,如果要写可执行程序可以 copy 这里的实现。

addService 同名怎么办?

  • root 用户随便加
  • 其他要判断 allowed 列表(只是系统的一些uid可以重复 add 同名service)

fork 出来的子进程不能进行 binder 通信的原因

  1. binder_proc 被绑定在 open(/dev/binder) 打开的 struct file 上(private_data成员),fork 后子进程共享父进程的 file 对象,所以子进程调用 ioctl 最终是用父进程的 binder_proc 发包的,回包也会把数据填到父进程 mmap 内存区(这种情况下内核没有崩溃也是奇迹了o(╯□╰)o)。
  2. binder_mmap 中分配内存时加了 VM_DONTCOPY 标志,fork 时这部分内存页不会拷贝,所以子进程中就没有这块内存了(尝试读取回包数据时会发生缺页异常,因为 data 和 offsets 就在这片地址空间中):
vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;

总之就是一旦已经打开过 /dev/binder,那 fork 出来的子进程就不能继续用 binder 了,除非用 exec 系列函数重新投胎。

一次 read/write 可以处理几个 binder_transaction_data?

binder_thread_read 读到一个 binder_transaction_data 就会返回。

binder_thread_write 理论上可以写多个 binder_transaction_data,因为不是由它来执行,只管发到目标进程就行,它接下来会 wait 等回包,不知道哪个先到,所以实际上是不可行的。

BC BR 怎么转换的?

BC_XXX 是发送(ioctl)
BR_XXX 是接收(waitForResponse)

在驱动中转换了:
BC_TRANSACTION ->
目标进程 BINDER_WORK_TRANSACTION(binder_work.type) ->
目标进程读 BR_TRANSACTION

BINDER_WORK_TRANSACTION_COMPLETE ->
本线程 BR_TRANSACTION_COMPLETE

文件形式的binder 是什么鬼?

共享 struct file,读写位置也是共享的。

bwr.read_consumed 是驱动读了多少数据到 mIn 吧?

是的。

binder 推荐教程

Android深入浅出之Binder机制 —— 讲的是用户态 binder 的实现,没讲驱动,但是用户态的逻辑更绕,先要理解用户态的需求,才能明白驱动为什么要那么实现,所以应该先看这个。

Android Binder设计与实现 - 设计篇 —— 讲的是 binder 驱动,没有按源码分析,是作者根据源码总结的,把"怎么实现的"和"为什么这么实现"都讲明白了,写得太好了。

Android Binder设计与实现 - 实现篇 —— 对设计篇的补充,关键源码分析,设计篇中一些看后有点模糊的点,这里都讲清楚了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值