接在之前的

i.mx6 Android5.1.1 初始化流程之init进程

i.mx6 Android5.1.1 初始化流程之init.rc解析

servicemanager是由init创建的本地服务,是binder的守护进程。

主要用来管理开发者创建的各种Server,并且向Client提供查询Server远程接口的功能。

#名字为servicemanager的服务,可执行文件的路径在/system/bin/servicemanager
#属于core类,用户为:system,用户组为:system
#critical:如果在几分钟内一直没响应则重启服务
#重启servicemanager需要冲入如下的服务healthd,zygote,media,surfaceflinger,drm
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm

可以得知其路径在/system/bin/servicemanager

查看android.mk

include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := liblog libselinux
LOCAL_SRC_FILES := service_manager.c binder.c
LOCAL_CFLAGS += $(svc_c_flags)
LOCAL_MODULE := servicemanager
include $(BUILD_EXECUTABLE)

可以得知,就是在service_manager.c

int main(int argc, char **argv)
{
struct binder_state *bs; //打开binder设备驱动文件,并将Binder设备文件映射到servicemanger进程的地址空间中
bs = binder_open(*);
if (!bs) {
ALOGE("failed to open binder driver\n");
return -;
} //在binder驱动层设置服务管理者角色
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -;
} selinux_enabled = is_selinux_enabled();
sehandle = selinux_android_service_context_handle(); if (selinux_enabled > ) {
if (sehandle == NULL) {
ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
abort();
} if (getcon(&service_manager_context) != ) {
ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
abort();
}
} union selinux_callback cb;
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
cb.func_log = selinux_log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
  //接收到请求后的需要执行的回调函数
svcmgr_handle = BINDER_SERVICE_MANAGER;
//进入binder.c循环,等待客户请求
binder_loop(bs, svcmgr_handler); return ;
}
struct binder_state *binder_open(size_t mapsize)
{
。。。
  //打开设备节点
bs->fd = open("/dev/binder", O_RDWR);
。。。
//映射
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, );
。。。
}

再看看直接的那个回调函数

int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
。。。
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
     //查找相关的服务,如果有,则返回其句柄
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0; case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
     //想servicemanager添加服务
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break; case SVC_MGR_LIST_SERVICES: {
uint32_t n = bio_get_uint32(msg); if (!svc_can_list(txn->sender_pid)) {
ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
txn->sender_euid);
return -1;
}
si = svclist;
while ((n-- > 0) && si)
si = si->next;
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
} bio_put_uint32(reply, 0);
return 0;
}
void binder_loop(struct binder_state *bs, binder_handler func)
{
int res;
struct binder_write_read bwr;
uint32_t readbuf[]; bwr.write_size = ;
bwr.write_consumed = ;
bwr.write_buffer = ; readbuf[] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(uint32_t)); for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = ;
bwr.read_buffer = (uintptr_t) readbuf;
     //读取binder节点数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    
if (res < ) {
ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
break;
}
     //解析
res = binder_parse(bs, , (uintptr_t) readbuf, bwr.read_consumed, func);
if (res == ) {
ALOGE("binder_loop: unexpected reply?!\n");
break;
}
if (res < ) {
ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
break;
}
}
}
int binder_parse(struct binder_state *bs, struct binder_io *bio,
uintptr_t ptr, size_t size, binder_handler func)
{
  。。。
switch(cmd) {
    。。。
binder_dump_txn(txn);
if (func) {
unsigned rdata[/];
struct binder_io msg;
struct binder_io reply;
int res; bio_init(&reply, rdata, sizeof(rdata), );
bio_init_from_txn(&msg, txn);
          //注意:这个是之前我们传进来的回调函数
res = func(bs, txn, &msg, &reply);
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
}
ptr += sizeof(*txn);
break;
}
。。。default:
ALOGE("parse: OOPS %d\n", cmd);
return -;
}
} return r;
}

小结:

1.申请一段内存,打开设备节点/dev/binder,同时将内存映射到内核中用来给binder使用

2.将自己设置为服务管理者

3.通过binder接口循环读取查看是否有数据,当有数据传来时,调用回调函数添加服务,或者查询服务

i.mx6 Android5.1.1 servicemanager本地服务的更多相关文章

  1. i.mx6 Android5.1.1 初始化流程之init.rc解析(未完成)

    接上一篇:i.mx6 Android5.1.1 初始化流程之init进程 参考资料:http://blog.csdn.net/mr_raptor/article/category/799879 这个博 ...

  2. i.mx6 Android5.1.1 初始化流程之框架

    Android启动过程分为以下几个步骤: 1.  Boot ROM:  上电后启动芯片固话代码. 2.  BootLoader:固话代码会根据启动模式启动bootloader,(一般为启动引脚的电平的 ...

  3. i.mx6 Android5.1.1 System server

    1. 概述: 1. Zygote进程是Android Java世界的开创者,所有的Java应用程序进程都由Zygote进程创建: 2. Zygote创建应用程序进程过程其实就是复制自身进程地址空间作为 ...

  4. i.mx6 Android5.1.1 初始化流程之init进程(未完成)

    概述: 接在i.mx6 Android5.1.1 初始化流程之框架之后 参考资料:http://blog.csdn.net/mr_raptor/article/category/799879 相关源码 ...

  5. Python 启动本地服务

    在 Linux 服务器上或安装了 Python 的机器上,Python自带了一个WEB服务器 SimpleHTTPServer,我们可以很简单的使用  python -m SimpleHTTPServ ...

  6. 利用node构建本地服务

    利用node构建本地服务 首先安装下node.js,地址为https://nodejs.org/en/,然后安装npm. node.js的中文api地址http://nodeapi.ucdok.com ...

  7. Android Service学习之本地服务

    Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过来声明.可以通过contect.startservice和contect.bindse ...

  8. Anroid四大组件service之本地服务

    服务是Android四大组件之一,与Activity一样,代表可执行程序.但Service不像Activity有可操作的用户界面,它是一直在后台运行.用通俗易懂点的话来说: 如果某个应用要在运行时向用 ...

  9. webpack-dev-server 搭建本地服务以及浏览器实时刷新

    一.概述开发项目中为了保证上线,开发项目是都需要使用localhost进行开发,以前的做法就是本地搭建Apache或者Tomcat服务器.有的前端开发人员 对服务器的搭建和配置并不熟悉,这个时候需要后 ...

随机推荐

  1. 将引用了第三方jar包的Java项目打包成jar文件的两种方法

    方案一:用Eclipse自带的Export功能 步骤1:准备主清单文件 “MANIFEST.MF”, 由于是打包引用了第三方jar包的Java项目,故需要自定义配置文件MANIFEST.MF,在该项目 ...

  2. Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)

    row_number() over()   1.2.3.4.5.6.7 rank() over()  1.2.2.4.5.5.7 dense_rank() over() 1.2.2.3.3.4.5 n ...

  3. 其他信息: 实体类型 xxxxx 不是当前上下文的模型的一部分。

    我是手动添加的EF类的,   解决方法: 没有在DbContext 添加  public virtual DbSet<xxx> xxxx{ get; set; } 导致不在上下文中

  4. c# BindingSource 类

      1.引言     BindingSource组件是数据源和控件间的一座桥,同时提供了大量的API和Event供我们使用.使用这些API我们可以将Code与各种具体类型数据源进行解耦:使用这些Eve ...

  5. HBase – 存储文件HFile结构解析

    本文由  网易云发布. 作者:范欣欣 本篇文章仅限内部分享,如需转载,请联系网易获取授权. HFile是HBase存储数据的文件组织形式,参考BigTable的SSTable和Hadoop的TFile ...

  6. leecode刷题(17)-- 实现StrStr

    leecode刷题(17)-- 实现StrStr 实现StrStr 描述: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串 ...

  7. PHP 函数功能参考

    basename() 返回路径中的文件名部分 chgrp() 改变文件组 chmod() 改变文件模式 chown() 改变文件所有者 clearstatcache() 清除文件状态缓存 copy() ...

  8. day00 -----博客作业1

    问题1.使用while循环输入 1 2 3 4 5 6     8 9 10 i = 0 while i<10: i+=1 if i ==7: continue print(i) 问题2 求1- ...

  9. Java文件字节流和字符流

    输入流:只能从中读取数据,不能向其写入数据. InputStream,Reader 输出流:只能向其中写入数据,不能从中读取数据. OutputStream, Writer 输入流是相对于程序而言,外 ...

  10. jquery插件制作,下拉菜单

    要求输入框点击出现下拉菜单,并实现以下功能: 1.首先点击地点标签页,选择好地点: 2.自动显示相应节点标签页显示节点信息,选择好节点 3.自动显示相应的连接点,选择连接点,连接点被选中并被传送的输入 ...