Jimmy Chen

A Programmer

(原创)servicemanager分析

servicemanager是binder部分的关键组件之一,binder client要想获取service提供的服务,可以根据service的名字向servicemanager发出获取service的请求。而binder service则需要在servicemanager中注册之后,才能够被别的client使用。显然要在其他binder client或者binder service访问servicemanager前,servicemanager就得启动了,同时servicemanager需要作为守护进程一直运行在系统中,否则当servicemanager挂掉后,binder client和binder service都无法正常工作了。

1. init启动servicemanager

servicemanager作为守护进程是由init进程来启动的,下面是代码中servicemanager.rc中的代码

servicemanager的class为core,core服务都是系统最基本的服务,只有core服务全部启动了,手机才能运行起来。servicemanager起来后的user为system,group为system和readproc(正常来说应该只有system才对,因为用的是mtk的代码,所以不清楚mtk是否有修改这里)。onrestart表示如果servicemanager重新启动的话就重新启动healthed、zygote、media等服务。所以servicemanager服务实际运行的程序就是system/bin/servicemanager了。

2. servicemanager的Android.mk

下面是servicemanager的Android.mk文件的内容,省略了一部分无关的内容

源码文件只包含两个:service_manager.c和binder.c,启动的init rc文件为servicemanager.rc

3. servicemanager源码分析

3.1 service_manager.c main函数

main函数源码如下:

main函数的内容比较简单,首先打开binder驱动,然后将自己设置为binder系统的“大管家”,然后就进入循环等待事件到来。下面看看binder_open里面做了什么设置:

3.2 binder.c binder_open函数

binder_open函数的内容放在了binder.c文件中

总结起来就是打开驱动,然后进行内存映射,然后将文件fd和映射内存的信息返回给main函数

3.3 binder.c binder_become_context_manager函数

binder_become_context_manager直接调用ioctl系统调用,之后系统会调用到binder驱动的ioctl方法,其中command为BINDER_SET_CONTEXT_MGR。

3.4 binder.c binder_ioctl函数

这里的binder.c文件和3.3中的binder.c文件不是同一个文件,这一节的binder.c文件是kernel/drivers底下的binder.c。

3.5 binder.c binder_ioctl_set_ctx_mgr函数

所以binder_become_context_manager最后回到binder驱动里面,创建binder_context_mgr_node这个binder_node,用于记录servicemanager,而且servicemanager只能注册一个,如果之前有注册,那么这里就会报错的。

3.6 binder.c binder_loop函数

这里调用binder_parse,先对接收到的数据进行解析,解析完毕后会调用svcmgr_handler对解析后的数据进行处理

3.7 binder.c binder_parse函数

上述代码的工作读取command,根据command处理数据。对于BR_TRANSACTION,需要出做的事情比较多,还要初始化reply,然后通过func即svcmgr_handler来处理客户的请求,最后将处理的结果通过binder驱动返回给发送请求的客户端。

3.8 service_manager.c svcmgr_handler函数

3.9 service_manager.c do_add_service函数

servicemanager的功能架构和代码都比较简单直接,和一个C语言小程序类似,主要就是其内部会维护一个svclist链表,记录所有注册到servicemanager中的信息,方便后续查询

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注