Linux鼻祖LinusTorvalds曾说过的一句话:Read The Fucking Source Code。
注:以下记录需对照着源码看
目录
一、Binder核心方法:
java
binder_init()驱动设备的初始化
misc_register()注册misc设备
binder_open()打开binder驱动设备
binder_proc对象 管理IPC所需的各种信息,并拥有其他结构体的根结构体
filp->private_data = proc; 把binder_proc对象保存到文件指针filp
binder_mmap() 用户空间的Buffer和内核空间的Buffer映射
area=get_vm_area() 分配一个连续的内核虚拟空间,与用户虚拟空间大小一致
binder_update_page_range() 分配物理页面,同时映射到内核空间和用户空间
alloc_page() 分配一个page的物理内存
ret=map_kernel_range_noflush() 物理空间映射到虚拟内核空间
ret=vm_insert_page() 物理空间映射到虚拟用户空间
//binder_alloc_buf() 用于分配内存
binder_ioctl() 数据操作( ioctl(文件描述符,ioctl命令,数据类型))
binder_get_thread() 获取binder_thread
//根据当前进程的pid,从binder_proc中查找相应的binder_thread
//如果不存在则创建binderthread,并将当前线程添加到当前的proc
binder_ioctl_write_read() 进行binder读写操作
copy_from_user() 把用户空间的数据ubuf拷贝到内核空间bwr
if(bwr.write_size>0即bwr写缓存有数据)
ret=binder_thread_write() 执行binder写操作
if(ret<0写失败)
copy_to_user将bwr数据写回用户空间
if(bwr.read_size>0读缓存中有数据)
ret=binder_thread_read() 执行binder读操作
if(ret<0读失败)
copy_to_user将bwr数据写回用户空间
if(copy_to_user()) 将内核数据bwr拷贝到用户空间ubuf
二、Binder通信协议:
java
binder_thread_write() 处理Binder协议中的请求码。
请求码为BC_TRANSACTION或BC_REPLY
copy_from_user()//拷贝用户空间tr到内核
binder_transaction()
分配两个结构体内存
从target_proc分配一块buffer
向目标进程的target_list添加BINDER_WORK_TRANSACTION事务
向当前线程的todo队列添加BINDER_WORK_TRANSACTION_COMPLETE事务
binder_thread_read() 根据不同的binder_work->type以及不同状态,生成相应的响应码。
根据wait_for_proc_work来决定wait在当前线程还是进程的等待队列
三、Binder启动ServiceManager:
java
1.打开bndier驱动,binder_open
2.注册成为binder服务的大管家:binder_beome_context_manager
3.启动无限循环,处理client端发来的binder
service_manager.c中的main() service_manager 的入口函数
binder_open() 打开binder驱动,申请内存
open() 通过系统调用陷入内核,打开Binder设备驱动
通过系统调用,ioctl获取binder版本信息
mmap()通过系统调用,mmap内存映射,mmap必须是page的整数倍
成为上下文管理者
if(selinux_enabled>0)
if(sehandle==null)
abort()无法获取
if(getcon(&service_manager_context)!=0)
abort()无法获取service_manager上下文
binder_loop() 进入无限循环,处理client端发来的请求
binder_write() 将BC_ENTER_LOOPER命令发送给binder驱动,让service manager进入循环
根据传进来的参数,初始化bwr
return ioctl() 通过ioctl将bwr数据发送给binder驱动
ioctl()进入循环,不断地binder读写过程
binder.get_thread() 获取binder_thread
binder_ioctl_write_read()
copy_from_user()把用户空间数据拷贝到bwr
binder_thread_write() 主要是设置当前线程的looper状态为BINDER_LOOPER_STATE_ENTERED
copy_to_user()将内核数据bwr拷贝到用户空间
binder_parse()解析binder信息
bio_init()
bio_init_from_txn()
func(bs,txn,&msg,&reply);//svcmgr_handler()
bio_get_string16()服务名
do_find_service() 根据名称查找相应的服务
find_svc() 查询相应的服务
服务存在,返回相应服务名,否则返回null
检查服务是否允许孤立于进程而单独存在
服务是否满足查询条件
bio_put_ref()
if(handle) bio_alloc_obj()
bio_alloc()
else bio_alloc()
bio_get_string16()服务名
bio_get_ref()
do_add_service()注册指定服务
svc_can_register()权限检查
check_mac_perms_form_lookup()检查selinux权限是否满足
find_svc()服务检索
svcinfo_death()服务已注册时,释放相应的服务
binder_acquire()
binder_link_to death()
binder_write()
binder_send_reply()
binder_write() 这个
binder_become_context_manager() 通 知 binder 驱 动 使 其 成 为 守 护 进 程
return ioctl(bs->fd,BINDER_SET_CONTEXT_MGR,0)通过ioctl,传递BINDER_SET_CONTEXT_MGR指令
binder_ioctl_set_ctx_mgr()里面调用的这个方法
binder_new_node()创建service实体
kzallor给新建的binder_node分配内核空间
rb_linko_node() 将新建的node对象添加到proc红黑树
四、获取ServiceManager
java
defaultServiceManager()
gDefaultServiceManager的创建过程:
1.ProcessState::self() 获取ProcessState对象(单例),一个进程一个,存在则返回,否则创建
new ProcessState 实例化ProcessState
初始化ProcessState
open_driver()
open("/dev/binder",o_RDWR);打开/dev/binder设备,建立与内核的Binder驱动的交互通道
2.getContextObject() 获取BpBinder对象
getStrongProxyForHandle(0) 获取handle=0的IBinder
lookupHandleLocked(handle) 查找handle对应的资源项
根据handle查找对应的handle_entry
当handle大于mHandleToObject的Vector长度时
mHandleToObject.insertAt() 则向该Vector添加(handle+1-N)个结构体,
然后再返回handle向对应位置的handle_entry结构体指针
new BpBinder(handle) 当handle值对应的IBinder不存在或弱引用无效,则创建BpBinder对象()
针对handle=0特殊情况,通过PING_TRANSACTION来判断是否准备就绪
3.interface_cast<IServiceManager>() 获取BpServiceManager对象
INTERFACE::asInterface()
DECLARE_META_INTERFACE(ServiceManager)
声明asInterface(),getInterfaceDesciptor()
IMPLEMENT_META_INTERDACE(ServiceManager,"android.os.IServiceManager")
BpServiceManager实例化<-BpInterface<-BpRefBase //BpRefBase的mRemote指向new BpBinder(0)
五、注册服务addService
java
media服务注册
main_mediaserver.cpp的main() 入口函数
sp<ProcessState> proc(ProcessState::self())获得ProcessState实例
new ProcessState 单例,保证一个进程一个ProcessState对象
open_driver() 打开Binder驱动
open("/dev/binder",O_RDWR) 打开/dev/binder设备,建立与内核的Binder驱动的交互通道
ioctl() 设置binder驱动,能支持的最大线程数
mmap() 采用内存映射函数,给binder分配一块虚拟地址空间
close() 没有足够空间分配,关闭驱动
defaultServiceManager() 获取BpServiceManager对象
注册多媒体服务
startThreadPool() 启动Binder线程池
joinThreadPool() 当前线程加入到线程池
服务注册MediaPlayerService::instantiate()
addService()注册服务
Parcelle data ,reply; Parcel数据通道
data.writeInterfaveToken(IServiceManager::getInterfaceDescriptor()) 写入头信息
data.writeString16(name)
data.writeStrongBinder(service) MediaPlayerService对象
flatten_binder()
localBinder()
finish_flatten_binder()
remote()->transact() //remote()指向BpBinder对象
BpBinder::transact
IPCThreadState::self()->transact() Binder代理类调用transact(),真正工作还是交给IPCThreadSate进行transact工作
new IPCThreadState; 初始IPCThreadState
pthread_key_creat() 创建线程的TLS
IPC::transact
errorCheck() 数据检查错误
writeTransactionData() 传输数据
waitForResponse() 等待相应
talkWithDriver()
ioctl() 通过ioctl不停读写,跟Binder Driver进行通信
executeCommand()
Binder Driver
binder_ioctl_write_read()
copy_from_user() 将用户空间bwr结构体拷贝到内核空间
binder_thread_write() 将数据放入目标进程
binder_thread_read() 读取自己队列的数据
copy_to_user() 将内核空间bwr结构体拷贝到用户空间
binder_thread_write()
getUser() 拷贝用户空间的cmd命令
copy_from_user() 拷贝用户空间的binder_transaction_data
binder_transaction()
binder_get_node() //从binder_proc来根据binder指针ptr指,查询相应的binder_node
binder_new_node() 服务所在进程 创建binder_node实体
kzaalloc() 给新创建的binder_node分配内核空间
rb_link_node() 将新创建的node添加到proc红黑树
binder_get_ref_for_node() servicemanager进程binder_ref
ServiceManager:
启动ServiceManager,循环在binder_loop()过程,会调用binder_parse()
binder_parse()
bio_init_from_txn() 从txn解析出binder_io信息
func() 收到binder事务
binder_send_reply() 发送reply事件
svcmgr_handler()
do_add_service() 注册指定服务
权限检查
服务检索
binder_rend_reply()
binder_write() 向Binder驱动通信
六、获取服务getService()
java
getMediaPlayService()
defaultServiceManager() 获取驱动Service
getService("media.player") 获取名为"media.player"的服务
checkService() 检索服务,存在即返回,否则sleep(1)再检索,循环5次
data.writeInterfaceToken()写入RPC头
data.writeString16()写入服务名
remote()->transact() remote()为BpBinder
IPCThreadState::self()->transact() 真正工作交给IPCThreadState来进行transact
errorCheck() 数据错误检查
writeTransactionData() 数据传输
waitForResponse() 等待响应
talkWithDriver()
ioctl() 通过ioctl不停的读写操作,跟Binder Driver进行通信
binder_transaction()
binder_thread_read()
readStrongBinder() 功能:flat_binder_object解析并创建BpBinder对象
unflatten_binder()
reinterpret_cast() 当请求服务的进程和服务属于同一进程
getStrongProxyForHandle() 请求服务的进程与服务属于不同进程
lookupHandleLocked() 查找handle对应的资源项
linkToDeath() 将死亡通知连接到binder
七、Framework层分析
java
1.初始化
AndroidRuntime::startReg() //完成jni方法的注册
register_jni_procs(gRegJNI, NELEM(gRegJNI),env) //注册jni(), gRegJNI是数组,记录所有需要注册的jni(),比如REG_JNI(register_android_os_Binder)
register_android_os_Binder()
int_register_android_os_Binder() //注册Binder类的jni()
gBinderOffsets //是全局静态结构体,保存了类本身及成员方法,execTransat(),mObject属性。
gBinderMethodsOrDie //将gBinderMethods数组完成映射关系,从而为Java层访问JNI层提供通道
int_register_android_os_BinderInternal() //注册BinderInternal类的jni()
gBinderInternalOffsetd() //保存了BinderInternal的forceBinderIGc()
int_register_android_os_BinderProxy() //注册BinderProxy类的jni()
gBinderProxyOffsets //保存了BinderProxy的构造方法,sendDeayhNotice(),mObject,mySelf,mOrgue
2.注册服务(有点乱)
ServiceManager.addService()
getIServiceManager() //先获取SMP对象,则执行注册服务操作
getContextObject() //等价于new BinderProxy()
getContextObject() //等价于new BpBinder(0)
javaObjectForIBinder() //创建BinderProxy对象,并存到BinderProxy.mObject成员变量
ServiceManagerNative.asInterface()
new ServiceManagerProxy() //SMP初始化
ServiceManagerProxy.addService()
writeStrongBinder()
nativewriteStrongBinder()//此处为native调用
android_os_Parcel_writeStrongBinder()
reinterpret_cast() //将Java层Parcel转换为native
ibinderForJavaObject() //创建JavaBBinderHolder对象,并把地址保存到Binder.mObject成员变量
JavaBBinderHolder.get()
new JavaBinder() //首次进来,创建JavaBBinder对象
mRemote.transact()
BinderProxy.transact
checkParcel() //用于检测Parcel大小
transactNative()
//最终交由Native层的BpBinder::transact()完成
3.获取服务
ServiceManager.getService()
sCache.get() //先从缓存中查看
getIServiceManager().getService() //getIServiceManager()等价于ServiceManagerProxy(new BinderProxy())
ServiceManagerProxy.getService()
mRemote.transact() //mRemote为BinderProxy:
android_os_BinderProxy_transact()
parcelForJavaObject() //Java Parcel转为native parcel
gBinderProxyOffsets.mObject()// 保存的是new BpBinder(0)对象
transact() //此处便是BpBinder::transact(),经过native层
IPCThreadState::transact()
errorCheck() //数据错误检查
writeTransactionData() //传输数据
waitForResponse() //等待回应事件
//当reply对象回收时,则会调用freeBuffer来回收内存。
//reply来源:binder_send_reply
reply.readStrongBinder() //从reply里面解析出获取的IBinder对象,基本是writeStrongBinder逆过程
readStrongBinder()
unflatten_binder()
getStrongProxyForHandle()
lookupHandleLocked()//查找handle对应的资源项
new BpBinder() //当handle值所对应的IBinder不存在或弱引用无效,则创建BpBinder对象