1.6 Binder机制
1 minute read
1.6.1 Binder驱动
- 流程
init()
, 创建/dev/binder设备节点, 调用binder_init()
, 注册misc设备, 即调用misc_register()
open()
获取Binder Driver的文件描述符, binder_open()
, 打开binder驱动设备, 创建binder_proc
对象, 保存当前进程信息
- 通过
mmap()
, 在内核分配内存, binder_mmap()
在内核虚拟地址空间申请一块与用户虚拟内存相同大小的内存, 再申请一个page大小的物理内存, 将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间
- 通过
ioctl
, 将IPC数据传给Binder Driver, binder_ioctl()
负责在两个进程收发IPC数据和IPC reply数据; binder_ioctl_write_read()
, (一)先把用户空间数据copy到内核空间bwr, (二)当bwr写缓存有数据, 则执行binder_thread_write()
, (三)当bwr读缓存有数据, 则执行binder_thread_read()
, (四)把内核数据bwr copy到用户空间
- BWR核心数据结构, 即
binder_write_read
, 包含了写缓存write_buffer
和读缓存read_buffer
, 包含了BR Protocol, 和binder_transaction_data
[target, code, data]
copy_from_user()
将用户空间IPC数据copy到内核态binder_write_read
结构体
copy_to_user()
将内核态binder_write_read
结构体copy到用户空间
binder_node
即binder实体
- Binder通信
binder_thread_write()
请求码为BC_TRANSACTION
或BC_REPLY
-> binder_transaction()
binder_thread_read()
- Binder内存机制
虚拟用户地址空间和虚拟内核地址空间都映射到同一物理内存, 当Client与Server发送数据时, Client把数据通过IPC通信
copy_from_user
copy到内核空间, Server端和内核共享内存
BpBinder
即客户端, BBinder
即服务端
1.6.2 ServiceManager
- 启动流程:
- 打开binder驱动:
binder_open()
, 系统调用open("/dev/binder", O_RDWR)
打开, Binder驱动层会创建binder_proc
, 通过系统调用mmap()
映射binder内存
- 注册成为服务管家:
binder_become_context_manager()
-> binder_ioctl()
-> binder_ioctl_set_ctx_mgr()
, 创建ServiceManager实体, 即binder_node
- 进入循环, 等待客户端请求:
binder_loop()
-> binder_write()
发送命令给binder
驱动 -> binder_ioctl()
进行binder
读写操作 -> binder_ioctl_write_read()
copy用户数据到bwr -> binder_thread_write()
设置当前线程的looper状态为BINDER_LOOPER_STATE_ENTERED
; binder_parse()
- 备注: ServiceManager最核心功能为查询和注册服务, 注册服务即记录服务名和handle信息, 保存到svclist列表; 查询服务即根据服务名查询相应的handle信息
- 获取ServiceManager
IServiceManager#defaultServiceManager()
-> interface_cast<IServiceManager>(ProcessState::self()->getContexObject(NULL));
ProcessState::self() -> getContextObject()
, 用于获取BpBinder对象
defaultServiceManager()
等价于new BpServiceManager(new BpBinder(0))
1.6.3 注册服务(addService)
- 流程
ProcessState::self()
, 打开Binder驱动, 调用mmap()
, 给binder分配一块虚拟地址空间
defaultServiceManager()
-> defaultServiceManager() -> addService(String16("media.player"), new MediaPlayerService())
-> BpServiceManager#addService()
即调用BpBinder
对象的transact()
-> IPCThreadState::self() ->transact()
, IPCThreadState
包含mIn
和mOut
用于接收和存储Binder设备的数据, 默认256字节, IPCThreadState::self() ->transact()
包含以下操作
- ->
errorCheck()
数据错误检查
- ->
writeTransactionData()
传输数据, 把Binder请求码BC_TRANSACTION
和binder_transaction_data
写入mOut
- ->
waitForResponse()
等待响应 -> IPCThreadState#talkWithDriver()
-> ioctl()
-> binder_ioctl()
-> binder_ioctl_write_read()
, binder_ioctl_write_read()
包含以下操作
copy_from_user()
, 将用户空间数据copy到内核空间
binder_thread_write()
将数据放入目标进程 -> binder_transaction()
binder_thread_read()
读取自己队列的数据
ProcessState::self() -> startThreadPool()
启动Binder线程池
IPCThreadState::self()->joinThreadPool()
当前线程加入线程池
1.6.4 查询服务(getService)
- 流程
defaultServiceManager
, 获取ServiceManager
sm->getService(String16("media.player"));
获取”media.player”服务
BpServiceManager#checkService()
, 检查服务是否存在
BpBinder#transact()
-> IPCThreadState::self()->transact()
IPCThreadState:transact()
包含如下操作
writeTransactionData()
传输数据
IPCThreadState#waitForResponse()
-> IPCThreadState#talkWithDriver()
- 最终
readStrongBinder()
, 返回BBinder
对象
1.6.5 如何使用Binder In Native
sp<IServiceManager> sm = defaultServiceManager();
sm->addService("service.myservice", new BnMyService());
ProcessState::self()->startThreadPol();//启动线程池
IPCThreadState::self()->joinThreadPool();//把主线程加入线程池
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("service.myservie"));
sp<IMyService> cs = interface_cast<IMyService>(binder);
cs->sayHello();
- 创建MyService, 定义接口, 定义BnMyService(Binder服务器)和BpMyService(Binder客户端)
- IMyService.cpp, 实现相关接口
1.6.6 AIDL
public class RemoteService extends Service {
public IBinder onBinder(Intent intent) {
returen mBinder;
}
// 实现IRemoteService定义的方法
xxx = new IRemoteService.Stub() {
xxx
}
}
Intent intent = new Intent(xxx, RemoteService.class);
intent.setPackage(IRemoteService.class.getName());
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
}
}
服务器Client 服务Server
业务层 IRmoteService IRemoteService[实现]
---------------------------------------------
服务Proxy 服务Stub
RPC层 IRemoteService.Stub.Proxy IRemoteService.Stub
--------------------------------------------------
IPC层 BinderProxy Binder
-----------------------------------------