梳理Binder原理之ServiceManager的注册流程(启动流程)AndroidP

本文主要介绍了Android Native层的ServiceManager,它是Binder机制的大管家,用于管理系统服务。阐述了其启动过程,包括binder_open、binder_become_context_manager和binder_loop等步骤,还说明了核心工作,如do_find_service、do_add_service及注册死亡通知等,核心工作为注册和查询服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ServiceManager是什么

  • ServiceManager(SM)是Binder机制的大管家,主要用于管理系统中各种服务,无论是注册服务还是获取服务,都要通过SM。(binder通信过程中,更多的情形是BpBinder与BBinder之间的通信,例如ActivityManagerProxy与AcitivityManagerService之间的通信)
    在这里插入图片描述

    这里提到的ServiceManager是Native层的ServiceManager(C++)而不是Framework层的 ServiceManager(Java)

  • ServiceManager是Binder ipc通信中的守护进程,也是一个Binder服务

ServiceManager没有采用libbinder中的多线程模型来与Binder驱动通信,而是自行编写了binder.c直接和Binder驱动来通信,并且只有一个循环binder_loop来进行读取和处理事务,这样的好处是简单而高效

启动过程

在这里插入图片描述
源码链接http://androidxref.com/9.0.0_r3/xref/system/core/rootdir/init.rc

由rc语法

Commands: trigger < event >

触发事件event,由一个action触发到另一个action队列

late-init的时候触发事件post-fs,而late-init在init.cpp的main方法中添加到执行队列,调用am.ExecuteOneCommand();按照插入的顺序执行触发器对应的命令
在这里插入图片描述
而Android.bp中把编译出的可执行文件的名字定为servicemanager
Android.bp学习笔记
在这里插入图片描述
对应的rc文件是servicemanager.rc
在这里插入图片描述
对应的源码service_manager.c
在这里插入图片描述
bs = binder_open(128*1024) 打开binder驱动,申请128k字节大小的内存空间
binder_become_context_manager(bs) 设为守护进程,注册成为binder服务的大管家,
binder_loop(bs, svcmgr_handler) 进入无限循环,处理client端发来的请求

binder_open

在这里插入图片描述

  • binder_state结构体记录了binder的相关信息
    在这里插入图片描述

  • open 打开binder驱动,返回文件描述符
    当用户空间调用open方法,最终会调用到binder驱动的binder_open方法。
    该方法会在binder驱动层创建一个binder_proc对象,再将binder_proc对象赋值给fd->private_data,同时放入binder_procs全局链表中

  • mmap 通过系统调用,mmap内存映射,mmap必须是 page的整数倍(4kb的整数倍)
    当用户空间调用mmap方法,最终会调用到binder驱动的binder_mmap方法。
    该方法会在binder驱动层创建Binder_buffer对象,并放入当前binder_proc的proc->buffers链表中
    在这里插入图片描述

binder_become_context_manager

在这里插入图片描述
binder_become_context_manager方法中调用ioctl方法,传入binder的文件描述符,BINDER_SET_CONTEXT_MGR指令,ioctl方法对应binder驱动的binder_ioctl方法

  • binder_ioctl()
    kernel/drivers/staging/android/binder.c
    在这里插入图片描述

  • binder_ioctl_set_ctx_mgr
    kernel/drivers/staging/android/binder.c
    在这里插入图片描述

  • binder_new_node
    在这里插入图片描述
    这一步主要的工作是:

  • 在Binder驱动层创建binder_node结构体对象

  • 将当前binder_proc加入到binder_node的node->proc

  • 创建binder_node的async_todo和binder_work两个队列。

binder_loop

在这里插入图片描述
binder_write_read结构体(kernel\drivers\staging\android\binder.h)
在这里插入图片描述

binder_write()

在这里插入图片描述

binder_ioctl()

ioctl调用到binder驱动的binder_ioctl方法
在这里插入图片描述
在这里插入图片描述
此处将用户空间的binder_write_read结构体通过copy_from_user() 拷贝到内核空间(内核空间中触发的copy_from_user,注意此处只是拷贝的命令信息并不是“一次拷贝”的数据)
在这里插入图片描述
接上面代码
在这里插入图片描述

binder_write通过ioctl()将BC_ENTER_LOOPER命令发送给binder驱动,此时bwr只有write_buffer有数据,进入binder_thread_write()方法。 接下来进入for循环,执行ioctl(),此时bwr只有read_buffer有数据,那么进入binder_thread_read()方法。

在这里插入图片描述

binder_parse()

在这里插入图片描述
由于binder_loop()传入的第二个参数是svcmgr_hander,也就是func,所以当有请求到来的时候,调用svcmgr_handler
在这里插入图片描述
在这里插入图片描述
服务都是使用svcinfo结构体表示
其中的handle值事服务在注册的过程中,由服务所在进程那一端确定的。

bio_put_ref,将查询到的handle 封装到reply
在这里插入图片描述
binder_loop这一步的主要工作是
进入循环状态,等待Client端的请求,通过binder_parse处理BR_XXX命令

ServiceManager的核心工作

do_find_service

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

do_add_service

在这里插入图片描述
在这里插入图片描述
注册服务主要的工作:
* svc_can_register检查selinux权限是否满足
* find_svc 服务检索,根据服务名查询匹配的服务
* svcinfo_death 释放服务,当查询到已经存在的服务,先释放服务

binder_link_to_death 注册死亡通知

在这里插入图片描述
根据binder_loop的介绍binder_write,最终会调用到binder驱动层的binder_ioctl_write_read方法
在这里插入图片描述
write_size>0,进入binder_thread_write

binder_thread_write
(kernel\drivers\staging\android\binder.c)
在这里插入图片描述
接上面的代码
在这里插入图片描述

此方法中的proc, thread都是指当前servicemanager进程的信息. 此时TODO队列有数据,则进入binder_thread_read.
那么哪些场景会向队列增加BINDER_WORK_DEAD_BINDER事务呢? 那就是当binder所在进程死亡后,会调用binder_release方法, 然后调用binder_node_release.这个过程便会发出死亡通知的回调.

而binder_thread_read中
在这里插入图片描述
接上面的代码
在这里插入图片描述

将命令BR_DEAD_BINDER写到用户空间, 此处的cookie是前面传递的svcinfo_death. 当binder_loop下一次 执行binder_parse的过程便会处理该消息。

binder_parse
(/frameworks/native/cmds/servicemanager/binder.c)
在这里插入图片描述
由do_add_service方法中si->death.func = (void*) svcinfo_death,所以death->func是执行svcinfo_death()
在这里插入图片描述
在这里插入图片描述
在binder_release中,向binder驱动中写入BC_RELEASE命令,最终在binder驱动中执行binder_dec_ref(ref,1)来减少binder_node的以用。

总结

流程图
在这里插入图片描述

ServiceManager是所有服务的大管家,通过权限控制进程是否有权注册服务,通过比较服务名字的字符串来查找Service,也可以通过ServiceManage获取Server进程的情况。
ServiceManage进程建立了跟所有想起注册服务的死亡通知,当服务所在进程死亡后,会通知给ServiceManage

ServiceManager的核心工作:注册服务、查询服务

注册流程:

打开binder驱动,并调用mmap()方法分配128k的内存映射空间:binder_open();
通知binder驱动使其成为守护进程:binder_become_context_manager();
验证selinux权限,判断进程是否有权注册或查看指定服务;
进入循环状态,等待Client端的请求:binder_loop()。
注册服务的过程,根据服务名称,但同一个服务已注册,重新注册前会先移除之前的注册信息;
死亡通知: 当binder所在进程死亡后,会调用binder_release方法,然后调用binder_node_release.这个过程便会发出死亡通知的回调.

参考

http://gityuan.com/2015/11/07/binder-start-sm/

总结和学习中,如有错误欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值