[–>service_manager.c, main()]
int main(int argc, char **argv) {
// 打开设备文件 driver = "/dev/binder",并映射设备文件到本进程地址空间
bs = binder_open(driver, 128*1024);
// 注册成为 Binder 进程间通信机制的上下文管理者
binder_become_context_manager(bs);
// 循环等待和处理 Client 进程的通信请求
binder_loop(bs, svcmgr_handler);
}
// binder.c
struct binder_state
{
int fd; // 打开设备文件 “/dev/binder” 后得到的文件描述符(用于和 Binder 驱动程序交互)
void *mapped; // 映射设备文件后得到的地址空间的起始地址
size_t mapsize; // 映射设备文件后得到的地址空间的地址空间大小(默认为 128KB)
};
[–>binder.c, binder_open()]
// driver = "/dev/binder"
// mapsize = 128*1024
struct binder_state *binder_open(const char* driver, size_t mapsize) {
struct binder_state *bs;
// open():通过系统调用陷入内核,打开 Binder 设备驱动(会调用驱动的 binder_open 函数)
// O_RDWR:读写模式
// O_CLOEXEC:当调用 exec 成功后,文件描述符会自动关闭,在 open 中是原子操作
bs->fd = open(driver, O_RDWR | O_CLOEXEC);
if (bs->fd < 0) {
goto fail_open; // 无法打开 Binder 设备
}
// 映射设备文件后得到的地址空间的地址空间大小,传入的是 128*1024(128KB)
bs->mapsize = mapsize;
// 映射设备文件后得到的地址空间的起始地址,mmap():通过系统调用,进行内存映射(必须是 page 的整数倍)
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
if (bs->mapped == MAP_FAILED) {
goto fail_map; // Binder 设备内存无法映射
}
return bs;
fail_map:
close(bs->fd);
fail_open:
free(bs);
return NULL;
}
open 经过系统调用,进入 Binder 驱动,调用 binder_open(),该方法会在 Binder 驱动层创建一个 binder_proc 对象(用于描述当前进程的 Binder 进程间通信状态),再将 binder_proc 对象赋值给 fd->private_data,同时放入全局链表 binder_procs
mmap 经过系统调用,进入 Binder 驱动,调用 binder_mmap(),该方法会在 Binder 驱动层创建一个 binder_buffer 对象,并放入当前 binder_proc 的 proc->buffers 内核缓冲区链表
[–>binder.c, binder_become_context_manager()]
static struct binder_node *binder_context_mgr_node;
static uid_t binder_context_mgr_uid = -1;
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
int ret;
// 取出 binder_open 中给 ServiceManager 创建的 binder_proc
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
// 获取当前线程,首次创建并保存,之后直接返回
thread = binder_get_thread(proc);
// cmd = BINDER_SET_CONTEXT_MGR
switch (cmd) {
case BINDER_SET_CONTEXT_MGR:
// binder_context_mgr_node 默认为空,不为空说明当前已注册为 Binder 进程间通信机制的上下文管理者
if (binder_context_mgr_node != NULL) {
ret = -EBUSY;
goto err;
}
// binder_context_mgr_uid 默认为 -1,不为 -1 说明其它进程已注册 Binder 进程间通信机制的上下文管理者
if (binder_context_mgr_uid != -1) {
// binder_context_mgr_uid 不是当前进程的有效用户 id
if (binder_context_mgr_uid != current->cred->euid) {
ret = -EPERM;
goto err; // 出错
}
} else // binder_context_mgr_uid 默认为 -1
// binder_context_mgr_uid 赋值为当前进程的有效用户 id
binder_context_mgr_uid = current->cred->euid;
// 为 ServiceManager 创建一个 Binder 实体对象
binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
if (binder_context_mgr_node == NULL) {
ret = -ENOMEM;
goto err;
}
binder_context_mgr_node->local_weak_refs++;
binder_context_mgr_node->local_strong_refs++;
binder_context_mgr_node->has_strong_ref = 1;
binder_context_mgr_node->has_weak_ref = 1;
break;
}
}
[–>kernel/drivers/android/binder.c, binder_new_node()]
// ptr = NULL
// cookie = NULL
static struct binder_node *binder_new_node(struct binder_proc *proc, binder_uintptr_t ptr, binder_uintptr_t cookie)
{
struct rb_node **p = &proc->nodes.rb_node;
struct rb_node *parent = NULL;
struct binder_node *node;
// 首次进入,红黑树中没有节点,跳过 while 循环
while (*p) {
parent = *p;
node = rb_entry(parent, struct binder_node, rb_node);
if (ptr < node->ptr)
p = &(*p)->rb_left;
else if (ptr > node->ptr)
p = &(*p)->rb_right;
else
return NULL;
}
// 创建一个 Binder 实体对象,并且对它进行初始化,最后将它加入到宿主进程的成员变量 nodes 红黑树中
node = kzalloc(sizeof(*node), GFP_KERNEL); // 分配内核空间
if (node == NULL)
return NULL;
binder_stats_created(BINDER_STAT_NODE);
// 将新创建的 node 对象添加到 proc 红黑树
rb_link_node(&node->rb_node, parent, p);
rb_insert_color(&node->rb_node, &proc->nodes);
node->debug_id = ++binder_last_id;
// 将传入的 proc:binder_proc* 加入到 node:binder_node* 的 proc
node->proc = proc;
node->ptr = ptr;
node->cookie = cookie;
// 设置 binder_work 的 type
node->work.type = BINDER_WORK_NODE;
INIT_LIST_HEAD(&node->work.entry);
INIT_LIST_HEAD(&node->async_todo);
return node;
}
&(*p)->rb_left
&(*p)->rb_left = &((*p)->rb_left)
-> 的优先级比 & 高
首次进入 binder_new_node:
[–>binder.c, binder_loop()]
void binder_loop(struct binder_state *bs, binder_handler func) {
int res;
struct binder_write_read bwr;
uint32_t readbuf[32];
readbuf[0] = BC_ENTER_LOOPER;
// 发送命令协议 BC_ENTER_LOOPER 给 Binder 驱动,将 Service Manager 进程主线程注册为 Binder 线程
binder_write(bs, readbuf, sizeof(uint32_t));
bwr.write_size = 0; // 进程用户态地址空间传递到内核数据的大小
bwr.write_consumed = 0; // 进程用户态地址空间传递到内核数据中已经被内核态处理的大小
bwr.write_buffer = 0; // 进程用户态地址空间传递到内核数据的起始地址
for (;;) { // 进入循环,不断地 binder 读写过程
// 每次循环前,重置 read 相关的参数
bwr.read_size = sizeof(readbuf); // 总共可供给驱动写入的字节数,read_buffer 可供内核使用的大小
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t)readbuf; // 内核驱动发送给进程数据 buffer 的起始地址
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
break;
}
// 解析 binder 信息
res = binder_parse(bs, 0, (uintptr_t)readbuf, bwr.read_consumed, func); // func 传入的是 svcmgr_handler
if (res == 0) {
break;
}
if (res < 0) {
break;
}
}
}
[–>binder.c, binder_write()]
// data = BC_ENTER_LOOPER
int binder_write(struct binder_state *bs, void *data, size_t len)
{
struct binder_write_read bwr;
int res;
bwr.write_size = len; // len 传入的是 sizeof(uint32_t),大小为 4
bwr.write_consumed = 0;
// write_buffer 指向缓冲区的起始地址,其内容为 BC_ENTER_LOOPER 请求协议号
bwr.write_buffer = (uintptr_t) data;
bwr.read_size = 0;
bwr.read_consumed = 0;
bwr.read_buffer = 0;
// 调用驱动 binder_ioctl
// write_size 大于 0,read_size 等于 0,只写不读,写完立马返回用户空间
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
return res;
}
通过 ioctl() 将 binder_write_read 数据发给 Binder 驱动,调用 binder_ioctl() 方法
[–>kernel/drivers/android/binder.c, binder_ioctl()]
// cmd = BINDER_WRITE_READ
// arg = &binder_write_read
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
// 取出 binder_open 中给 ServiceManager 创建的 binder_proc
struct binder_roc *proc = filp->private_ata;
struct binder_thread *thread;
void __user *ubuf = (void __user *)arg;
// 获取当前线程对应的 binder_thread,在 binder_become_context_manager 中已创建,这里直接返回
thread = binder_get_thread(proc);
// cmd = BINDER_WRITE_READ
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
// 拷贝从用户空间传来的 binder_write_read,保存到 bwr 变量
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
// 拷贝的 bwr 中,只有 write_size 大于 0,write_buffer 只包含 BC_ENTER_LOOPER
if (bwr.write_size > 0) {
ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
if (ret < 0) {
bwr.read_consumed = 0;
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
if (bwr.read_size > 0) {
ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
if (!list_empty(&proc->todo))
wake_up_interruptible(&proc->wait);
if (ret < 0) {
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
break;
}
default:
ret = -EINVAL;
goto err;
}
// 没有出错,则最终返回 0
ret = 0;
err:
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
return ret;
}
[–>kernel/drivers/android/binder.c, binder_thread_write()]
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)
{
uint32_t cmd;
void __user *ptr = buffer + *consumed;
void __user *end = buffer + size;
while (ptr < end && thread->return_error == BR_OK) {
// ptr 实际为 write_buffer,因此 cmd = BC_ENTER_LOOPER
if (get_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
// cmd = BC_ENTER_LOOPER
switch (cmd) {
case BC_ENTER_LOOPER:
// 设置线程的 looper 状态为 BINDER_LOOPER_STATE_ENTERED
thread->looper |= BINDER_LOOPER_STATE_ENTERED;
break;
}
*consumed = ptr - buffer;
}
return 0;
}
binder_thread_write 处理完命令协议 BC_ENTER_LOOPER 后,返回 binder_ioctl 中,然后返回到用户空间的 binder_write 中,最后返回到 binder_loop,开始执行 for 循环中的内容
[–>binder.c, binder_loop()]
void binder_loop(struct binder_state *bs, binder_handler func) {
...
for (;;) { // 进入循环,不断地 binder 读写过程
// 每次循环前,重置 read 相关的参数
bwr.read_size = sizeof(readbuf); // 总共可供给驱动写入的字节数,read_buffer 可供内核使用的大小
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t)readbuf; // 内核驱动发送给进程数据 buffer 的起始地址
// 调用驱动 binder_ioctl
// read_size 大于 0,write_size 等于 0,只读不写
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
break;
}
// 解析 binder 信息
res = binder_parse(bs, 0, (uintptr_t)readbuf, bwr.read_consumed, func); // func 传入的是 svcmgr_handler
if (res == 0) {
break;
}
if (res < 0) {
break;
}
}
}
[–>kernel/drivers/android/binder.c, binder_ioctl()]
// cmd = BINDER_WRITE_READ
// arg = &binder_write_read
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
// 取出 binder_open 中给 ServiceManager 创建的 binder_proc
struct binder_roc *proc = filp->private_ata;
struct binder_thread *thread;
void __user *ubuf = (void __user *)arg;
// 获取当前线程对应的 binder_thread,在 binder_become_context_manager 中已创建,这里直接返回
thread = binder_get_thread(proc);
// cmd = BINDER_WRITE_READ
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
// 拷贝从用户空间传来的 binder_write_read,保存到 bwr 变量
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
if (bwr.write_size > 0) {
ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
if (ret < 0) {
bwr.read_consumed = 0;
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
// 拷贝的 bwr 中,只有 read_size 大于 0,read_buffer 用于接收内核驱动发送给进程 ServiceManager 的数据
if (bwr.read_size > 0) {
ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
if (!list_empty(&proc->todo))
wake_up_interruptible(&proc->wait);
if (ret < 0) {
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
break;
}
default:
ret = -EINVAL;
goto err;
}
// 没有出错,则最终返回 0
ret = 0;
err:
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
return ret;
}
[–>kernel/drivers/android/binder.c, binder_thread_read()]
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)
{
void __user *ptr = buffer + *consumed;
void __user *end = buffer + size;
int ret = 0;
int wait_for_proc_work;
if (*consumed == 0) {
// 将 BR_NOOP 写回到用户传进来的缓冲区
// ptr = buffer + *consumed = bwr.read_buffer + bwr.consumed = bwr.read_buffer + 0 = bwr.read_buffer
if (put_user(BR_NOOP, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
}
retry:
// 线程事务堆栈为空(没有等待其他线程完成事务) && 线程 todo 队列为空,此时可以去等待处理进程 todo 队列中的待处理项
wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
// 设置线程处于空闲状态
thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
if (wait_for_proc_work)
proc->ready_threads++;
// 线程等待处理进程 todo 队列中可能存在的未处理工作项
if (wait_for_proc_work) {
if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED))) {
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
}
binder_set_nice(proc->default_priority);
// non_block 表示不阻塞,没有可处理工作项时,不休眠立即返回
if (non_block) {
if (!binder_has_proc_work(proc, thread))
ret = -EAGAIN;
} else
// 线程睡眠等待进程有待处理工作项
ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
} else { // 线程处理自己 todo 队列中可能存在的未处理工作项
if (non_block) {
if (!binder_has_thread_work(thread))
ret = -EAGAIN;
} else
// 线程睡眠等待自己有待处理工作项
ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
}
if (wait_for_proc_work)
proc->ready_threads--;
// 取消线程处于空闲状态
thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
if (ret)
return ret;
// while 循环用于处理进程或线程 todo 队列中存在的未处理工作项
while (1) {
... // 暂不分析处理工作项(假定暂无需要处理的工作项)
}
done:
*consumed = ptr - buffer;
if (proc->requested_threads + proc->ready_threads == 0 && // 正在请求的次数 + 空闲线程数 = 0,即两个都为 0
proc->requested_threads_started < proc->max_threads && // 通过请求增加的线程数 < 最大线程数(该值在 ProcessState.cpp 的 open_driver 中设置为 15)
(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED))) { // 当前线程是一个 Binder 线程(已注册成为 Binder 线程)
proc->requested_threads++; // requested_threads + 1,则 if 条件不满足,一次只能增加一个线程,当线程增加成功后,驱动程序会将 requested_threads 会减一
// 将返回协议 BR_SPAWN_LOOPER 写入到用户空间缓冲区 buffer,请求进程 proc 创建一个新的线程加入到 Binder 线程池中
if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
return -EFAULT;
}
return 0;
}
至此, ServiceManager 进程启动过程分析完毕。若 ServiceManager 进程的主线程没有待处理的工作项,则此时就会睡眠在 Binder 驱动程序的 binder_thread_read 中,等待 Client 进程(向 Server 进程 ServiceManager 发送请求)的 Service 组件(向 Client 进程提供服务)或 Client 组件(Service 代理对象,向 Server 进程请求服务)
这里的 Service 组件和 Client 组件是 Binder 进程间通信机制中的概念