Android5.1.1

Android5.1.1 Binder机制

Binder是Android系统提供的一种IPC机制,由于基于Linux内核所以除了Binder意外还有其它IPC机制如:管道,Socket等。
在这里插入图片描述

Binder驱动程序中,binder_work表示在Binder驱动中进程索要处理的工作项:

struct binder_work {
	struct list_head entry;
	enum {
		BINDER_WORK_TRANSACTION = 1,
		BINDER_WORK_TRANSACTION_COMPLETE,
		BINDER_WORK_NODE,
		BINDER_WORK_DEAD_BINDER,
		BINDER_WORK_DEAD_BINDER_AND_CLEAR,
		BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
	} type;
};

entry被定义为list_head类型,用于实现一个双向链表,存储所有binder_work队列;还包含一个enum类型的type:binder_work。

结构体binder_node用来定义Binder实体对象:

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;
	int internal_strong_refs;
	int local_weak_refs;
	int local_strong_refs;
	void __user *ptr;
	void __user *cookie;
	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实体隶属于提供实体的进程。binder_node说明:

在这里插入图片描述

binder_ref_death同志结构体。只要某一进程对某一binder引用订阅了其实体的死亡通知,那么binder都启动将会成为此binder引用建立一个binder_ref_death通知结构体,将其保存在当前进程的对应binder引用结构体的death域中:

struct binder_ref_death {
	struct binder_work work;
	void __user *cookie;
};

结构体binder_ref描述一个Binder引用对象:


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;
	uint32_t desc;
	int strong;
	int weak;
	struct binder_ref_death *death;
};

在这里插入图片描述

结构体binder_buffer描述一个内核缓冲区,能在进程间传输数据:

struct binder_buffer {
	struct list_head entry; /* free and allocated entries by address */ //构建一个双向链表
	struct rb_node rb_node; /* free entry by size or allocated entry */ //表示一个红黑树节点
				/* by address */
	unsigned free:1;
	unsigned allow_user_free:1;
	unsigned async_transaction:1;
	unsigned debug_id:29;

	struct binder_transaction *transaction; //中转请求和返回结果

	struct binder_node *target_node;	//一个目标节点
	size_t data_size;					//数据大小
	size_t offsets_size;				//偏移量
	uint8_t data[0];					//存储实际数据
};

结构体binder_proc表示症状使用Binder进程通信机制的进程,能够保存调用Binder的各个进程或线程的信息:

struct binder_proc {
	struct hlist_node proc_node; 	//实现双向链表
	struct rb_root threads;			//储存所有进程信息
	struct rb_root nodes;			
	struct rb_root refs_by_desc;
	struct rb_root refs_by_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;
	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;			//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;
};

结构体binder_thread存储每一个单独的线程的信息,表示Binder线程池中的一个线程:

struct binder_thread {
	struct binder_proc *proc;				//当前线程属于哪一个Binder进程(binder_porc指针)	
	struct rb_node rb_node;					//红黑树节点
	int pid;								//线程pid
	int looper;								//线程状态信息
	struct binder_transaction *transaction_stack;//定义要接收发送的进/线程信息binder_transaction
	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;					//等待队列头结构binder_stats
	struct binder_stats stats;
};
enum {
	BINDER_LOOPER_STATE_REGISTERED  = 0x01,
	BINDER_LOOPER_STATE_ENTERED     = 0x02,
	BINDER_LOOPER_STATE_EXITED      = 0x04,
	BINDER_LOOPER_STATE_INVALID     = 0x08,
	BINDER_LOOPER_STATE_WAITING     = 0x10,
	BINDER_LOOPER_STATE_NEED_RETURN = 0x20
};

looper表示的线程状态信息枚举定义:0x01,0x02,0x04,0x08,0x10,0x20(注册、进入、退出、销毁、等待、需要返回)

结构体binder_transaction中转请求和返回结果,并保存接受和要发送的进程信息:

struct binder_transaction {
	int debug_id;					//调试相关
	struct binder_work work;		//binder_work
	struct binder_thread *from;		//binder_thread对象
	struct binder_transaction *from_parent;	//接收进程信息的父节点
	struct binder_proc *to_proc;		//binder_proc类型结构体
	struct binder_thread *to_thread;	//发送进程信息的父节点
	struct binder_transaction *to_parent;
	unsigned need_reply:1;
	/* unsigned is_dead:1; */	/* not used at the moment */

	struct binder_buffer *buffer;
	unsigned int	code;
	unsigned int	flags;
	long	priority;
	long	saved_priority;
	uid_t	sender_euid;		/*ender_euid表示要发送进程对文件和资源的操作权限(euid表示进程对文件和资源的访问权限)*/
};

binder_transaction中还包含了类型类inder_buffer的一个buffer,用来表示Binder的缓冲区信息

在.h文件中

结构体binder_write_read表示在进程之间的通信过程中传输的数据,数据包中有一个cmd域用于区分不同的请求:

struct binder_write_read {
	signed long	write_size;	/* bytes to write */	//写入数据大小
	signed long	write_consumed;	/* bytes consumed by driver */	//被消耗的写数据大小
	unsigned long	write_buffer;
	signed long	read_size;	/* bytes to read */		//读入数据大小
	signed long	read_consumed;	/* bytes consumed by driver */	//被消耗的读数据大小
	unsigned long	read_buffer;
};

当Binder驱动找到处理此事件的进程后,Binder驱动就会把需要处理的事件的任务放在读缓冲(binder_write_read)里,返回给这个服务线程,改服务线程则会执行指定命令的操作;处理请求的线程把数据交给合适的对象来执行预定操作,然后返回结果同样结构binder_transaction_data进行封装,以写命令的方式传回给Binder驱动,并将此数据放在一个读缓冲(binder_write_read)里,返回正在等待结果的原进程(线程),这样就完成一次通信

结构体binder_write_read包含的命令在BinderDriverCommandProtocol中定义:

enum BinderDriverCommandProtocol {
	BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),	/*用于翻译和解析将要被处理的事件数据*/
	BC_REPLY = _IOW('c', 1, struct binder_transaction_data),/*事件处理完成之后对返回“结果数据”的操作指令*/
	/*
	 * binder_transaction_data: the sent command.
	 */

	BC_ACQUIRE_RESULT = _IOW('c', 2, int),
	/*
	 * not currently supported
	 * int:  0 if the last BR_ATTEMPT_ACQUIRE was not successful.
	 * Else you have acquired a primary reference on the object.
	 */

	BC_FREE_BUFFER = _IOW('c', 3, int),
	/*
	 * void *: ptr to transaction data received on a read
	 */

	BC_INCREFS = _IOW('c', 4, int),
	BC_ACQUIRE = _IOW('c', 5, int),
	BC_RELEASE = _IOW('c', 6, int),
	BC_DECREFS = _IOW('c', 7, int),
	/*
	 * int:	descriptor
	 */

	BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie),
	BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie),
	/*
	 * void *: ptr to binder
	 * void *: cookie for binder
	 */

	BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc),
	/*
	 * not currently supported
	 * int: priority
	 * int: descriptor
	 */

	BC_REGISTER_LOOPER = _IO('c', 11),
	/*
	 * No parameters.
	 * Register a spawned looper thread with the device.
	 */

	BC_ENTER_LOOPER = _IO('c', 12),
	BC_EXIT_LOOPER = _IO('c', 13),
	/*
	 * No parameters.
	 * These two commands are sent as an application-level thread
	 * enters and exits the binder loop, respectively.  They are
	 * used so the binder can have an accurate count of the number
	 * of looping threads it has available.
	 */

	BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie),
	/*
	 * void *: ptr to binder
	 * void *: cookie
	 */

	BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie),
	/*
	 * void *: ptr to binder
	 * void *: cookie
	 */

	BC_DEAD_BINDER_DONE = _IOW('c', 16, void *),
	/*
	 * void *: cookie
	 */
};

在枚举BinderDriverReturnProtocol中定义了读操作命令协议:

enum BinderDriverReturnProtocol {
	BR_ERROR = _IOR('r', 0, int),
	/*
	 * int: error code
	 */

	BR_OK = _IO('r', 1),
	/* No parameters! */

	BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
	BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
	/*
	 * binder_transaction_data: the received command.
	 */

	BR_ACQUIRE_RESULT = _IOR('r', 4, int),
	/*
	 * not currently supported
	 * int: 0 if the last bcATTEMPT_ACQUIRE was not successful.
	 * Else the remote object has acquired a primary reference.
	 */

	BR_DEAD_REPLY = _IO('r', 5),
	/*
	 * The target of the last transaction (either a bcTRANSACTION or
	 * a bcATTEMPT_ACQUIRE) is no longer with us.  No parameters.
	 */

	BR_TRANSACTION_COMPLETE = _IO('r', 6),
	/*
	 * No parameters... always refers to the last transaction requested
	 * (including replies).  Note that this will be sent even for
	 * asynchronous transactions.
	 */

	BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie),
	BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie),
	BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie),
	BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie),
	/*
	 * void *:	ptr to binder
	 * void *: cookie for binder
	 */

	BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie),
	/*
	 * not currently supported
	 * int:	priority
	 * void *: ptr to binder
	 * void *: cookie for binder
	 */

	BR_NOOP = _IO('r', 12),
	/*
	 * No parameters.  Do nothing and examine the next command.  It exists
	 * primarily so that we can replace it with a BR_SPAWN_LOOPER command.
	 */

	BR_SPAWN_LOOPER = _IO('r', 13),
	/*
	 * No parameters.  The driver has determined that a process has no
	 * threads waiting to service incomming transactions.  When a process
	 * receives this command, it must spawn a new service thread and
	 * register it via bcENTER_LOOPER.
	 */

	BR_FINISHED = _IO('r', 14),
	/*
	 * not currently supported
	 * stop threadpool thread
	 */

	BR_DEAD_BINDER = _IOR('r', 15, void *),
	/*
	 * void *: cookie
	 */
	BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *),
	/*
	 * void *: cookie
	 */

	BR_FAILED_REPLY = _IO('r', 17),
	/*
	 * The the last transaction (either a bcTRANSACTION or
	 * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory).  No parameters.
	 */
};

binder_ptr_cookie和binder_transaction_data

binder_ptr_cookie表示一个Binder实体对象或者Service组件的死亡接受通知:

struct binder_ptr_cookie {
	void *ptr;
	void *cookie;
};

binder_transaction_data表示在通信过程中传递的数据:

struct binder_transaction_data {
	/* The first two are only used for bcTRANSACTION and brTRANSACTION,
	 * identifying the target and contents of the transaction.
	 */
	union {
		size_t	handle;	/* target descriptor of command transaction */
		void	*ptr;	/* target descriptor of return transaction */
	} target;
	void		*cookie;	/* target object cookie */
	unsigned int	code;		/* transaction command */

	/* General information about the transaction. */
	unsigned int	flags;
	pid_t		sender_pid;
	uid_t		sender_euid;
	size_t		data_size;	/* number of bytes of data */
	size_t		offsets_size;	/* number of bytes of offsets */

	/* If this transaction is inline, the data immediately
	 * follows here; otherwise, it ends with a pointer to
	 * the data buffer.
	 */
	union {
		struct {
			/* transaction data */
			const void	*buffer;
			/* offsets from buffer to flat_binder_object structs */
			const void	*offsets;
		} ptr;
		uint8_t	buf[8];
	} data;
};

系统中,把在进程之间传递的数据成为Binder对象,在对应源代码中使用结构体flat_binder_object表示:

struct flat_binder_object {
	/* 8 bytes for large_flat_header. */
	unsigned long		type;	/*描述Binder类型,传输的数据是一个复用数据联合体。对Binder类型来说,数据是一个Binder本地对象*/
	unsigned long		flags;	//传输方式,其值使用一个enum表示

	/* 8 bytes of data. */
	union {
		void		*binder;	/* local object */
		signed long	handle;		/* remote object */	//一个远程的handle句柄
	};

	/* extra data associated with local object */
	void			*cookie;	//如果是本地对象,Binder还可以带有额外的数据,保存到cookie字段中
};



enum transaction_flags {
	TF_ONE_WAY	= 0x01,	/* this is a one-way call: async, no return */
	TF_ROOT_OBJECT	= 0x04,	/* contents are the component's root object */
	TF_STATUS_CODE	= 0x08,	/* contents are a 32-bit status code */
	TF_ACCEPT_FDS	= 0x10,	/* allow replies with file descriptors */
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值