Binder(七)系统服务注册流程总结

本文基于Android_9.0、kernel_3.18源码

通过Binder(三)到Binder(六)的相关文章,我们详细介绍了Binder服务启动、服务注册的流程;其中服务注册相当于servicemanager提供的一个方法,AMS在system_server进程中,AMS完成注册即通过binder完成了一次跨进程通信,我们再梳理一下整体流程。

Binder(七)系统服务注册流程总结

流程梳理

一、初始化

1、service_manager进程创建之后,会进行binder的初始化:
(1)通过binder_open打开dev/binder,创建binder_proc来记录进程信息,并通过mmap进行内存映射
(2)通过binder_become_context_manager注册为binder的管理者,即将自己赋值给全局变量全局变量binder_context_mgr_node
(3)通过binder_loop循环,等待消息,由于刚刚创建,没有进行中待处理任务,阻塞进程,等待唤醒

2、system_server进程创建后,也会进行binder初始化:
(1)通过ProcessState打开dev/binder,创建binder_proc来记录进程信息,并通过mmap进行内存映射
(2)通过开启新的线程,并调用IPCThreadState的joinThreadPool开启循环,等待接收消息,由于没有待处理的任务,该线程阻塞,等待唤醒。

二、进程通信

1、BpBinder的获取
binder通信,需要知道通信的目标是谁,在binder中定义binder_context_mgr_node的handle = 0,因此就通过handle = 0找到servicemanager,在BpBinder创建时持有了handle。

2、以AMS注册为例,数据发送
(1)通过Parcel将AMS数据包装,在此设置type为BINDER_TYPE_BINDER,并将AMS数据写入对应结构,再通过BpBinder的transact调用IPCThreadState的transact进行通信;
(2)在IPCThreadState的waitForResponse中,会调用binder驱动进行如下操作:
在第5步创建事务时,事物的数据地址直接通过地址偏移量计算出来,省去一次拷贝。

<1>查找/创建binder_thread
<2>找到servicemanager的binder_node
<3>查找/创建AMS的binder_node
<4>查找/创建AMS的binder_ref
<5>新建任务加入servicemanager队列中
<6>唤醒servicemanager进程
<7>创建任务告诉自己已经发送成功

(3)如上操作会唤醒servicemanager进程,servicemanager进程会对任务进行处理,同时发送回执

<1>找到AMS的binder_thread
<2>新建任务加入AMS队列中
<3>唤醒ssystem_server进程
<4>创建任务告诉自己已经发送成功

(4)第(3)步操作会唤醒system_server线程,system_server处理回执消息,退出waitForResponse,数据交互流程完毕。

数据结构

binder_proc

在binder驱动中,用来描述进程的上下文信息;每当进程打开文件节点/dev/binder时,binder驱动都会为这个进程创建一个binder_proc。

struct binder_proc {
	struct hlist_node proc_node;
	struct rb_root threads; // binder_thread红黑树
	struct rb_root nodes; // binder_node组成的红黑树
	struct rb_root refs_by_desc; // binder_ref组成的红黑树,根据句柄排序
	struct rb_root refs_by_node; // binder_ref组成的红黑树,根据binder_node排序
	int pid;
	struct vm_area_struct *vma;
	struct mm_struct *vma_vm_mm;
	struct task_struct *tsk;
	struct files_struct *files;
	struct hlist_node deferred_work_node;
	int deferred_work;

	// 通过buffer + user_buffer_offset便能计算出用户空间的地址
	void *buffer; // 物理内存在内核空间的起始位置
	ptrdiff_t user_buffer_offset; // 内核空间和用户空间的偏移量

	struct list_head buffers;
	struct rb_root free_buffers;
	struct rb_root allocated_buffers;
	size_t free_async_space;

	struct page **pages; // 映射的内存页数
	size_t buffer_size; // 映射的内存大小
	uint32_t buffer_free;
	struct list_head todo; // 进程待处理队列
	wait_queue_head_t wait;
	struct binder_stats stats;
	struct list_head delivered_death;
	int max_threads;
	int requested_threads;
	int requested_threads_started;
	int ready_threads;
	long default_priority;
	struct dentry *debugfs_entry;
};

binder_thread

描述线程相关的数据。

struct binder_thread {
	struct binder_proc *proc; // 进程信息
	struct rb_node rb_node;
	int pid;
	int looper; // 进程状态BINDER_LOOPER_STATE_ENTERED
	struct binder_transaction *transaction_stack; // 正在处理的事务
	struct list_head todo; // 待处理的链表
	uint32_t return_error; /* Write failed, return error code in read buf */
	uint32_t return_error2; /* Write failed, return error code in read */
		/* buffer. Used when sending a reply to a dead process that */
		/* we are also waiting on */
	wait_queue_head_t wait;
	struct binder_stats stats;
};

binder_node

在binder驱动中,会为每一个服务创建一个binder_node,通过它可以找到真正提供服务的对象。

struct binder_node {
	int debug_id;
	struct binder_work work;
	union {
		struct rb_node rb_node;
		struct hlist_node dead_node;
	};
	struct binder_proc *proc; // 所属的进程信息
	struct hlist_head refs; // binder_ref组成的链表
	int internal_strong_refs;
	int local_weak_refs;
	int local_strong_refs;
	binder_uintptr_t ptr; // 真正提供服务的对象地址,如AMS
	binder_uintptr_t cookie; // 真正提供服务的对象数据,如AMS数据
	unsigned has_strong_ref:1;
	unsigned pending_strong_ref:1;
	unsigned has_weak_ref:1;
	unsigned pending_weak_ref:1;
	unsigned has_async_transaction:1;
	unsigned accept_fds:1;
	unsigned min_priority:8;
	struct list_head async_todo;
};

binder_ref

binder驱动中,需要通过binder_ref找到binder_node(服务对应的实体),每个与binder_node对应的客户端都会创建一个binder_ref;
Binder(七)binder_ref和binder_node关系

struct binder_ref {
	/* Lookups needed: */
	/*   node + proc => ref (transaction) */
	/*   desc + proc => ref (transaction, inc/dec ref) */
	/*   node => refs + procs (proc exit) */
	int debug_id;
	struct rb_node rb_node_desc;
	struct rb_node rb_node_node;
	struct hlist_node node_entry;
	struct binder_proc *proc; // 进程
	struct binder_node *node; // binder_node
	uint32_t desc; // handle
	int strong;
	int weak;
	struct binder_ref_death *death;
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值