(四)Binder分析·上篇

(四)Binder分析·上篇



一、概述

1.1 框架图

在这里插入图片描述

1.2 简介

在Android系统的Binder机制中,由一系统组件组成,分别是Client、Server、Service Manager和Binder驱动程序,其中Client、Server和Service Manager运行在用户空间,Binder驱动程序运行内核空间。Binder就是一种把这四个组件粘合在一起的粘结剂了,其中,核心组件便是Binder驱动程序,Service Manager提供了辅助管理的功能,Client和Server正是在Binder驱动和Service Manager提供的基础设施上,进行Client-Server之间的通信。Service Manager和Binder驱动已经在Android平台中实现好,开发者只要按照规范实现自己的Client和Server组件就可以了。

二、binder驱动

在这里插入图片描述

2.1 binder_init

//kernel/drivers/staging/android/binder.c
// 4290 设备驱动入口函数
device_initcall(binder_init);
// 4213
static int __init binder_init(void)
// 4220 创建名为binder的单线程的工作队列
binder_deferred_workqueue = create_singlethread_workqueue("binder");
// 4269
ret = init_binder_device(device_name);


static int __init init_binder_device(const char *name)
{
	int ret;
	struct binder_device *binder_device;
	//为binder设备分配内存
	binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL);
	if (!binder_device)
		return -ENOMEM;

	binder_device->miscdev.fops = &binder_fops;//设备文件操作结构
	binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;//设备号,动态分配
	binder_device->miscdev.name = name;//设备名binder

	binder_device->context.binder_context_mgr_uid = INVALID_UID;
	binder_device->context.name = name;
	mutex_init(&binder_device->context.context_mgr_node_lock);
	//misc驱动注册
	ret = misc_register(&binder_device->miscdev);
	if (ret < 0) {
		kfree(binder_device);
		return ret;
	}
	//将hlist节点添加到binder_devices为表头的设备链表
	hlist_add_head(&binder_device->hlist, &binder_devices);

	return ret;
}

2.2 binder_open

kernel/drivers/staging/android/binder.c
// 3454
static int binder_open(struct inode *nodp, struct file *filp)
	// 3462 为binder_proc结构体在kernel分配内存空间
	proc = kzalloc(sizeof(*proc), GFP_KERNEL);
	// 3465 将当前线程的task保存到binder进程的tsk
	get_task_struct(current);
	proc->tsk = current;
	INIT_LIST_HEAD(&proc->todo); // 初始化todo列表
	init_waitqueue_head(&proc->wait); // 初始化wait队列
	proc->default_priority = task_nice(current); // 将当前进程的nice值转换为进程优先级
	// 3474 同步锁, 因为binder支持多线程访问
	binder_lock(__func__);
	binder_stats_created(BINDER_STAT_PROC); // binder_proc对象创建数加1
	hlist_add_head(&proc->proc_node, &binder_procs); // 将proc_node节点添加到binder_procs的队列头部
	proc->pid = current->group_leader->pid; // 进程pid
	INIT_LIST_HEAD(&proc->delivered_death); // 初始化已分发的死亡通知列表
	filp->private_data = proc; // 将这个binder_proc与filp关联起来, 这样下次通过filp就能找到这个proc了
	binder_unlock(__func__); // 释放同步锁

2.3 binder_mmap

kernel/drivers/staging/android/binder.c
// 3355
static int binder_mmap(struct file *filp, struct vm_area_struct *vma){
	// 3366 保证映射内存大小不超过4M
	if ((vma->vm_end - vma->vm_start) > SZ_4M)
	vma->vm_end = vma->vm_start + SZ_4M;
	// 3382 同步锁, 保证一次只有一个进程分配内存, 保证多进程间的并发访问
	mutex_lock(&binder_mmap_lock);
	// 是否已经做过映射, 执行过则进入if, goto跳转, 释放同步锁后结束binder_mmap方法
	if (proc->buffer) {
	goto err_already_mapped;
	} // 采用 VM_IOREMAP方式, 分配一个连续的内核虚拟内存, 与进程虚拟内存大小一致
	area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP);
	// 内存分配不成功直接报错
	if (area == NULL) {
	ret = -ENOMEM;
	failure_string = "get_vm_area";
	goto err_get_vm_area_failed;
}
 // 将proc中的buffer指针指向这块内核的虚拟内存
proc->buffer = area->addr;
// 计算出用户空间和内核空间的地址偏移量。 地址偏移量 = 用户虚拟内存地址 - 内核虚拟内存地址
proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
mutex_unlock(&binder_mmap_lock); // 释放锁
// 3407 分配物理页的指针数组, 数组大小为vma的等效page个数
proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL);
// 3418 分配物理页面, 同时映射到内核空间和进程空间, 先分配1个物理页。
if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) {


kernel/drivers/staging/android/binder.c
// 576
static int binder_update_page_range(struct binder_proc *proc, int allocate,
void *start, void *end,
struct vm_area_struct *vma)
	// 609 allocate为1, 代表分配内存过程。 如果为0则代表释放内存过程
	if (allocate == 0)
	goto free_range;
	// 624 分配一个page的物理内存
	*page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
	// 630 物理空间映射到虚拟内核空间
	ret = map_kernel_range_noflush((unsigned long)page_addr,
	PAGE_SIZE, PAGE_KERNEL, page);
	// 641 物理空间映射到虚拟进程空间
	ret = vm_insert_page(vma, user_page_addr, page[0]);


kernel/drivers/staging/android/binder.c
// 3355
static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
	// 3425
	list_add(&buffer->entry, &proc->buffers);// 将buffer连入buffers链表中
	buffer->free = 1; // 此内存可用
	binder_insert_free_buffer(proc, buffer);// 将buffer插入 proc->free_buffers 链表中
	proc->free_async_space = proc->buffer_size / 2; // 异步的可用空闲空间大小
	barrier();
	proc->files = get_files_struct(current);
	proc->vma = vma;
	proc->vma_vm_mm = vma->vm_mm;

2.4 binder_ioctl

kernel/drivers/staging/android/binder.c
// 3241
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
// 3254 进入休眠状态, 直到中断唤醒
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
// 3259 根据当前进程的pid, 从binder_proc中查找binder_thread,
// 如果当前线程已经加入到proc的线程队列则直接返回,
// 如果不存在则创建binder_thread, 并将当前线程添加到当前的proc
thread = binder_get_thread(proc);
// 3265 进行binder的读写操作
switch (cmd) {
case BINDER_WRITE_READ:
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
if (ret)

// 3136
static int binder_ioctl_write_read(struct file *filp,unsigned int cmd, unsigned long arg,struct binder_thread *thread){
// 3150 把用户空间数据ubuf拷贝到bwr
	if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
	// 3160
	if (bwr.write_size > 0) { // 当写缓存中有数据, 则执行binder写操作
	ret = binder_thread_write(proc, thread,
	bwr.write_buffer,
	bwr.write_size,
	&bwr.write_consumed);
	}
	 if (bwr.read_size > 0)  // 当读缓存中有数据, 则执行binder读操作
		ret = binder_thread_read(proc, thread, bwr.read_buffer,
		bwr.read_size,
		&bwr.read_consumed,
		filp->f_flags & O_NONBLOCK);
	// 进程todo队列不为空,则唤醒该队列中的线程
	if (!list_empty(&proc->todo))
		wake_up_interruptible(&proc->wait);
	} // 3192 把内核空间数据bwr拷贝到ubuf
	if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
	...

三、JNI注册

从上篇《系统启动过程》知道zygote是由init进程通过解析init.zygote.rc文件而创建的, zygote所对应的可执行程序appprocess, 所对应的源文件是appmain.cpp, 进程名为zygote。在app_main.cpp的main函数中,运行AndroidRuntime.cpp的start方法,调用函数startReg注册JNI方法register_android_os_Binder。

frameworks/base/core/jni/android_util_Binder.cpp
// 1282
int register_android_os_Binder(JNIEnv* env)
{
if (int_register_android_os_Binder(env) < 0)
return -1;
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
}

3.1 int_register_android_os_Binder

frameworks/base/core/jni/android_util_Binder.cpp
// 843
static const JNINativeMethod gBinderMethods[] = {
/* name, signature, funcPtr */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
// 857
const char* const kBinderPathName = "android/os/Binder";
// 859
static int int_register_android_os_Binder(JNIEnv* env)
{
	// 查找文件 kBinderPathName = "android/os/Binder", 返回对应Class对象
	jclass clazz = FindClassOrDie(env, kBinderPathName);
	// 通过gBinderOffsets结构体, 保存Java层Binder类的信息, 为JNI层访问Java层提供通道
	gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
	gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
	gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
	// 通过RegisterMethodsOrDie, 将为gBinderMethods数组完成映射关系, 从而为Java层访问JNI层提供通道
	return RegisterMethodsOrDie(
	env, kBinderPathName,
	gBinderMethods, NELEM(gBinderMethods));
}

3.2 int_register_android_os_BinderInternal

frameworks/base/core/jni/android_util_Binder.cpp
// 925
static const JNINativeMethod gBinderInternalMethods[] = {
/* name, signature, funcPtr */
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
// 933
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
// 935
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
	// 查找文件kBinderInternalPathName = "com/android/internal/os/BinderInternal", 返回Class对象
	jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
	// 通过gBinderInternalOffsets, 保存Java层BinderInternal类的信息, 为JNI层访问java层提供通道
	gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
	gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
	// 通过RegisterMethodsOrDie(), 将为gBinderInternalMethods数组完成映射关系, 从而为Java层访问JNI层提供通道
	return RegisterMethodsOrDie(
	env, kBinderInternalPathName,
	gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

3.3 int_register_android_os_BinderProxy

frameworks/base/core/jni/android_util_Binder.cpp
// 1241
static const JNINativeMethod gBinderProxyMethods[] = {
/* name, signature, funcPtr */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
// 1252
const char* const kBinderProxyPathName = "android/os/BinderProxy";
// 1254
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
	// 查找文件 kBinderProxyPathName = "android/os/BinderProxy", 返回对应Class对象
	jclass clazz = FindClassOrDie(env, "java/lang/Error");
	gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
	// 通过gBinderProxyOffsets, 保存Java层BinderProxy类的信息, 为JNI层访问Java提供通道
	clazz = FindClassOrDie(env, kBinderProxyPathName);
	gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
	gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
	gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
	"(Landroid/os/IBinder$DeathRecipient;)V");
	gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
	gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
	"Ljava/lang/ref/WeakReference;");
	gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
	clazz = FindClassOrDie(env, "java/lang/Class");
	gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
	// 通过RegisterMethodsOrDie(), 将为gBinderProxyMethods数组完成映射关系, 从而为Java层访问JNI层提供通道
	return RegisterMethodsOrDie(
	env, kBinderProxyPathName,
	gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

四、数据结构

4.1 file_operations

static const struct file_operations binder_fops = {
	.owner = THIS_MODULE,
	.poll = binder_poll,
	.unlocked_ioctl = binder_ioctl,
	.compat_ioctl = binder_ioctl,
	.mmap = binder_mmap,
	.open = binder_open,
	.flush = binder_flush,
	.release = binder_release,
};

4.2 binder_proc

//每个进程调用open()打开binder驱动都会创建该结构体, 用于管理IPC所需的各种信息。
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红黑树的根节点(以 handle为 key)
	struct rb_root refs_by_node; // binder_ref红黑树的根节点( 以 ptr为 key)
	int pid; // 相应进程 id
	struct vm_area_struct *vma; // 指向进程虚拟地址空间的指针
	struct mm_struct *vma_vm_mm; // 相应进程的内存结构体
	struct task_struct *tsk; // 相应进程的 task结构体
	struct files_struct *files; // 相应进程的文件结构体
	struct hlist_node deferred_work_node;
	int deferred_work;
	void *buffer; // 内核空间的起始地址
	ptrdiff_t user_buffer_offset; // 内核空间与用户空间的地址偏移量
	struct list_head buffers; // 所有的 buffer
	struct rb_root free_buffers; // 空闲的 buffer
	struct rb_root allocated_buffers; // 已分配的 buffer
	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; // binder统计信息
	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;
	struct binder_context *context;
};

4.3 binder_node

struct binder_node {
	int debug_id; // 节点创建时分配, 具有全局唯一性, 用于调试使用
	struct binder_work work;
	union {
		struct rb_node rb_node; // binder节点正常使用, union
		struct hlist_node dead_node; // binder节点已销毁, union
	};
	struct binder_proc *proc; // binder所在的进程, 见后面小节
	struct hlist_head refs; // 所有指向该节点的 binder引用队列
	int internal_strong_refs;
	int local_weak_refs;
	int local_strong_refs;
	binder_uintptr_t ptr; // 指向用户空间 binder_node的指针,对应于 flat_binder_object.binder
	binder_uintptr_t cookie; // 指向用户空间 binder_node的指针, 附件数据,对应于 flat_binder_object.cookie
	unsigned has_strong_ref:1; // 占位 1bit
	unsigned pending_strong_ref:1; // 占位 1bit
	unsigned has_weak_ref:1; // 占位 1bit
	unsigned pending_weak_ref:1; // 占位 1bit
	unsigned has_async_transaction:1; // 占位 1bit
	unsigned accept_fds:1; // 占位 1bit
	unsigned min_priority:8; // 占位 8bit, 最小优先级
	struct list_head async_todo; // 异步todo队列
};

4.4 binder_buffer

struct binder_buffer {
	struct list_head entry; // buffer实体的地址
	struct rb_node rb_node; // buffer实体的地址
	/* by address */
	unsigned free:1; // 标记是否是空闲buffer, 占位1bit
	unsigned allow_user_free:1; // 是否允许用户释放, 占位1bit
	unsigned async_transaction:1; // 占位1bit
	unsigned debug_id:29; // 占位29bit
	struct binder_transaction *transaction; // 该缓存区的需要处理的事务
	struct binder_node *target_node; // 该缓存区所需处理的Binder实体
	size_t data_size; // 数据大小
	size_t offsets_size; // 数据偏移量
	size_t extra_buffers_size;
	uint8_t data[0]; // 数据地址
};

五、启动server_manager

ServiceManager是由init进程通过解析init.rc文件而创建的, 其所对应的可执行程序servicemanager, 所对应的源文件是
service_manager.c, 进程名为servicemanager。在service_manager.c的main函数中,调用了binder三个重要函数,具体代码如下:

//frameworks/native/cmds/servicemanager/service_manager.c
// 354
int main(int argc, char **argv)
	// 358 打开 binder驱动, 申请 128k字节大小的内存空间---见后面小节
	bs = binder_open(128*1024);
	// 364 设为守护进程, 成为 binder大管理者---见后面小节
	if (binder_become_context_manager(bs)) {
	// 391 进入无限循环, 处理client端发来的请求---见后面小节
	binder_loop(bs, svcmgr_handler);

在这里插入图片描述

5.1 binder_open

//frameworks/native/cmds/servicemanager/binder.c
// 96
struct binder_state *binder_open(size_t mapsize)
// 98 这个结构体记录了 service_manager 中有关于 binder 的所有信息
struct binder_state *bs;
// 107 打开 binder驱动, 得到文件描述符
bs->fd = open("/dev/binder", O_RDWR);
// 123
bs->mapsize = mapsize; // service_manager自己设置的, 大小为 128kb
/*通过系统调用, mmap内存映射, mmap必须是 page的整数倍(即 4kb的整数倍)*/
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

5.2 binder_become_context_manager

//frameworks/native/cmds/servicemanager/binder.c
// 146
int binder_become_context_manager(struct binder_state *bs)
{
	return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
	case BINDER_SET_CONTEXT_MGR:
		ret = binder_ioctl_set_ctx_mgr(filp);


// 3200
static int binder_ioctl_set_ctx_mgr(struct file *filp)
	// 3208 保证只创建一次 mgr_node对象, 不为 null就直接返回
	if (context->binder_context_mgr_node) {
	// 3216
	/* uid是否有效, 当前是无效的 */
	if (uid_valid(context->binder_context_mgr_uid)) {
	} else {
	/* 设置当前线程 euid作为 service_manager的 uid */
	context->binder_context_mgr_uid = curr_euid;
	} // 创建 service_manager实体
	context->binder_context_mgr_node = binder_new_node(proc, 0, 0);
	// 3233 将 binder_context_mgr_node的强弱引用各加 1
	context->binder_context_mgr_node->local_weak_refs++;
	context->binder_context_mgr_node->local_strong_refs++;
	context->binder_context_mgr_node->has_strong_ref = 1;
	context->binder_context_mgr_node->has_weak_ref = 1;


// 923
static struct binder_node *binder_new_node(struct binder_proc *proc,
binder_uintptr_t ptr,
binder_uintptr_t cookie)
	// 931 首次进来为空
	while (*p) {
	// 943 给新创建的binder_node 分配内核空间
	node = kzalloc(sizeof(*node), GFP_KERNEL);
	// 947 将新创建的 node对象添加到 proc红黑树
	rb_link_node(&node->rb_node, parent, p);
	rb_insert_color(&node->rb_node, &proc->nodes);
	// 950 初始化 binder_node
	node->proc = proc;
	node->ptr = ptr;
	node->cookie = cookie;
	node->work.type = BINDER_WORK_NODE; // 设置 binder_work的 type
	INIT_LIST_HEAD(&node->work.entry);
	INIT_LIST_HEAD(&node->async_todo);

5.3 binder_loop

//frameworks/native/cmds/servicemanager/binder.c
// 372
void binder_loop(struct binder_state *bs, binder_handler func)
	// 378
	bwr.write_size = 0; // 初始化为 0
	bwr.write_consumed = 0;
	bwr.write_buffer = 0;
	readbuf[0] = BC_ENTER_LOOPER; // 读写要处理的命令
	binder_write(bs, readbuf, sizeof(uint32_t)); // 设置线程的 looper状态为循环状态
	for (;;) {
		bwr.read_size = sizeof(readbuf); // 不为 0, 进入 binder_thread_read
		bwr.read_consumed = 0;
		bwr.read_buffer = (uintptr_t) readbuf;
		/* 不断地 binder读数据, 没有数据会进入休眠状态 */
		res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);


// 151
int binder_write(struct binder_state *bs, void *data, size_t len)
	// 156
	bwr.write_size = len; // 大于 0, 进入 binder_thread_write
	bwr.write_consumed = 0;
	bwr.write_buffer = (uintptr_t) data; // 此处 data为 BC_ENTER_LOOPER
	bwr.read_size = 0; // read 不会进去
	bwr.read_consumed = 0;
	bwr.read_buffer = 0;
	/* 设置线程的 looper状态为循环状态 */
	res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);


// 2250
static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed)
	// 2262 获取命令, 即 BC_ENTER_LOOPER
	if (get_user(cmd, (uint32_t __user *)ptr))
	// 2472
	case BC_ENTER_LOOPER:
	// 2481 设置该线程的 looper状态
	thread->looper |= BINDER_LOOPER_STATE_ENTERED;



static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block)
	// 2664 设置命令为 BR_NOOP
	if (*consumed == 0) {
	if (put_user(BR_NOOP, (uint32_t __user *)ptr))
	// 2671 wait_for_proc_work 为 true
	wait_for_proc_work = thread->transaction_stack == NULL &&
	list_empty(&thread->todo);
	// 2694 准备就绪的线程个数加 1
	if (wait_for_proc_work)
	proc->ready_threads++;
	// 2702
	if (wait_for_proc_work) {
	if (non_block) { // 非阻塞操作, service_manager是阻塞的, 所以 if不命中
	} else // 进入 else, 开始等待
	ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
}

六、获取server_manager

获取Service Manager是通过defaultServiceManager()方法来完成,总的来说:

sp<IServiceManager> sm = defaultServiceManager();  

相当于:

sp<IServiceManager> sm = new BpServiceManager(new BpBinder(0));   

详细调用流程:

//frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        /* 创建或者获取 SM时, SM可能未准备就绪, 这时通过 sleep 1秒后, 循环尝试获取直到成功 */
        while (gDefaultServiceManager == NULL) {
            /* 分为三块分析 */
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

6.1 ProcessState::self

frameworks/native/libs/binder/ProcessState.cpp
// 70
sp<ProcessState> ProcessState::self()
{
	/* 单例模式 */
	if (gProcess != NULL) {
		return gProcess;
	} 
	gProcess = new ProcessState; // 实例化 ProcessState
	return gProcess;
}
//frameworks/native/libs/binder/ProcessState.cpp
// 339
ProcessState::ProcessState(): mDriverFD(open_driver())
// 358 采用内存映射函数 mmap, 给 binder分配一块大小为 (1M-8K)的虚拟地址空间,用来接收事务
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
// 311
static int open_driver()
// 313 打开 /dev/binder设备, 建立与内核的 Binder驱动的交互通道
int fd = open("/dev/binder", O_RDWR);
// 328 通过 ioctl设置 binder驱动, 能支持的最大线程数
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);

6.2 getContextObject

//frameworks/native/libs/binder/ProcessState.cpp
// 85
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
	// 参数为0, 获取service_manager服务
	return getStrongProxyForHandle(0);
}


// 179
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
	// 查找 handle对应的资源项
	handle_entry* e = lookupHandleLocked(handle);
	// 192 当handle值所对应的IBinder不存在或弱引用无效时
	if (b == NULL || !e->refs->attemptIncWeak(this)) {
	// 214 通过ping操作测试binder是否准备就绪
	status_t status = IPCThreadState::self()->transact(
	0, IBinder::PING_TRANSACTION, data, NULL, 0);
	// 220 创建BpBinder对象
	b = new BpBinder(handle);


//frameworks/native/libs/binder/BpBinder.cpp
// 89
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)
{
	/* 支持强弱引用计数, OBJECT_LIFETIME_WEAK表示目标对象的生命周期受弱指针控制 */
	extendObjectLifetime(OBJECT_LIFETIME_WEAK);
	/* handle所对应的 bindle弱引用 + 1 */
	IPCThreadState::self()->incWeakHandle(handle);
}

6.3 interface_cast

//frameworks/native/include/binder/IInterface.h
// 41
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
// 等价于: IServiceManager::asInterface
return INTERFACE::asInterface(obj);
}

asInterface是一个模板函数,最终调用:

android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
{
	android::sp<IServiceManager> intr;
	if(obj != NULL) {
		intr = static_cast<IServiceManager *>(
		obj->queryLocalInterface(IServiceManager::descriptor).get());
		if (intr == NULL) {
		// 等价于 new BpServiceManager(BpBinder)
		intr = new BpServiceManager(obj);
		}
	}
	return intr;
}

6.4 BpServiceManager

//frameworks/native/libs/binder/IServiceManager.cpp
// 126
class BpServiceManager : public BpInterface<IServiceManager>
// 129
BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl)


//frameworks/native/include/binder/IInterface.h
// 134
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote): BpRefBase(remote)



//frameworks/native/libs/binder/Binder.cpp
// 241 mRemote指向 new BpBinder(0), 从而 BpServiceManager能够利用 Binder进行通过通信
BpRefBase::BpRefBase(const sp<IBinder>& o): mRemote(o.get()), mRefs(NULL), mState(0)

七、addService流程(下一篇单独分析)


总结

以上就是今天学习binder的内容,Binder是一种进程间通信机制, 做 Android 开发肯定离不开跟 Binder 打交道。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值