Server启动过程
2016-11-02 10:47:48 0 举报
AI智能生成
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析 总结
作者其他创作
大纲/内容
ProcessState::self()
创建实例gProcess
构造函数ProcessState::ProcessState()
open_driver()打开Binder设备文件/dev/binder,并将文件描述符保存在成员变量
通过open文件操作函数来打开/dev/binder设备文件
open_driver()打开Binder设备文件/dev/binder,并将文件描述符保存在成员变量
通过open文件操作函数来打开/dev/binder设备文件
调用ioctl文件控制函数与Binder驱动程序交互
BINDER_SET_MAX_THREADS
把用户传进来的参数保存在proc->max_threads中
BINDER_VERSION
将BINDER_CURRENT_PROTOCOL_VERSION写入到传入的参数arg指向的用户缓冲区中去
将BINDER_CURRENT_PROTOCOL_VERSION写入到传入的参数arg指向的用户缓冲区中去
BINDER_SET_MAX_THREADS
把用户传进来的参数保存在proc->max_threads中
mmap()把设备文件/dev/binder映射到内存中
defaultServiceManager()
返回的一个BpServiceManger类实例
返回的一个BpServiceManger类实例
MediaPlayerService::instantiate()
defaultServiceManager()::addService
BpServiceManger::addService
1、声明Parcel类数据data、reply
2、写入一个整数和一个字符串(IServiceManager::getInterfaceDescriptor()即"android.os.IServiceManager")到data中去
3、将name(即media.player)写入data中
4、将Binder对象写入data中
flatten_binder函数
初始化flat_binder_object
flatten_binder函数
初始化flat_binder_object
调用finish_flatten_binder将这个flat_binder_obj写入到Parcel中去;
并记录这个flat_binder_obj在Parcel里面的偏移位置
并记录这个flat_binder_obj在Parcel里面的偏移位置
5、进入BpBinder::transact函数
IPCThreadState::transact
调用writeTransactionData函数向Binder驱动传一个
struct binder_transaction_data结构体变量
waitForResponse(reply)
循环几次调用IPCThreadState::talkWithDriver函数与Binder驱动程序交互
通过ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)进行到Binder驱动程序的binder_ioctl函数
binder_thread_read函数
把mOut的数据清空, 并设置已经读取的内容的大小
通过ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)进行到Binder驱动程序的binder_ioctl函数
将用户传进来的参数拷贝到本地变量struct binder_write_read bwr中去
进入到binder_thread_write函数中
进入到binder_thread_write函数中
将用户传进来的transact参数拷贝在本地变量struct binder_transaction_data tr中去,接着调用binder_transaction函数进一步处理
分配了一个待处理事务t( 事务t是要交给target_proc处理的,在这个场景之下,就是Service Manager)和一个待完成工作项tcomplete,并执行初始化工作
处理传输数据中的Binder对象, 把Binder实体MediaPlayerService交给Service Manager来管理,也就是说Service Manager要引用这个MediaPlayerService
把待处理事务加入到target_list列表中,并唤醒Service Manager进程
分配了一个待处理事务t( 事务t是要交给target_proc处理的,在这个场景之下,就是Service Manager)和一个待完成工作项tcomplete,并执行初始化工作
在Service Manager的进程空间中分配一块内存来保存用户传进入的参数
处理传输数据中的Binder对象, 把Binder实体MediaPlayerService交给Service Manager来管理,也就是说Service Manager要引用这个MediaPlayerService
把待处理事务加入到target_list列表中,并唤醒Service Manager进程
binder_thread_read函数
第一次:往用户传进来的缓冲区buffer写入两个整数,分别是BR_NOOP和BR_TRANSACTION_COMPLETE
第二次: 进入睡眠状态,等待Service Manager来唤醒
唤醒后:把事务项t中的数据拷贝到本地局部变量struct binder_transaction_data tr中去,并 把tr的内容拷贝到用户传进来的缓冲区去
第二次: 进入睡眠状态,等待Service Manager来唤醒
唤醒后:把事务项t中的数据拷贝到本地局部变量struct binder_transaction_data tr中去,并 把tr的内容拷贝到用户传进来的缓冲区去
binder_loop
binder_parse
把从Binder驱动程序读出来的数据转换为一个struct binder_txn结构体,保存在txn本地变量中
调用bio_init函数来初始化reply、msg变量
真正进行处理的函数是从参数中传进来的函数指针func即
svcmgr_handler
函数
bio_get_ref
do_add_service
就是把MediaPlayerService这个Binder实体的引用写到一个struct svcinfo结构体中,主要是它的名称和句柄值,然后插入到链接svclist的头部去。这样,Client来向Service Manager查询服务接口时,只要给定服务名称,Service Manger就可以返回相应的句柄值了
将一个错误码0写到reply变量中去,表示一切正常
binder_send_reply
告诉Binder驱动程序执行BC_FREE_BUFFER和BC_REPLY命令,前者释放之前在binder_transaction分配的空间,地址为buffer_to_free,buffer_to_free这个地址是Binder驱动程序把自己在内核空间用的地址转换成用户空间地址再传给Service Manager的,所以Binder驱动程序拿到这个地址后,知道怎么样释放这个空间;后者告诉MediaPlayerService,它的addService操作已经完成了,错误码是0,保存在data.txn.data中
binder_write
直入到驱动程序的binder_ioctl函数后,执行BINDER_WRITE_READ命令
把从Binder驱动程序读出来的数据转换为一个struct binder_txn结构体,保存在txn本地变量中
调用bio_init函数来初始化reply、msg变量
真正进行处理的函数是从参数中传进来的函数指针func即
svcmgr_handler
函数
bio_get_ref
do_add_service
就是把MediaPlayerService这个Binder实体的引用写到一个struct svcinfo结构体中,主要是它的名称和句柄值,然后插入到链接svclist的头部去。这样,Client来向Service Manager查询服务接口时,只要给定服务名称,Service Manger就可以返回相应的句柄值了
将一个错误码0写到reply变量中去,表示一切正常
binder_send_reply
告诉Binder驱动程序执行BC_FREE_BUFFER和BC_REPLY命令,前者释放之前在binder_transaction分配的空间,地址为buffer_to_free,buffer_to_free这个地址是Binder驱动程序把自己在内核空间用的地址转换成用户空间地址再传给Service Manager的,所以Binder驱动程序拿到这个地址后,知道怎么样释放这个空间;后者告诉MediaPlayerService,它的addService操作已经完成了,错误码是0,保存在data.txn.data中
binder_write
直入到驱动程序的binder_ioctl函数后,执行BINDER_WRITE_READ命令
把mOut的数据清空, 并设置已经读取的内容的大小
ProcessState::self()->startThreadPool()
IPCThreadState::self()->joinThreadPool()

收藏
0 条评论
下一页