接在之前的

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/servicemanagerclass coreuser system         group systemcriticalonrestart restart healthdonrestart restart zygoteonrestart restart mediaonrestart restart surfaceflingeronrestart 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(128*1024);if (!bs) {ALOGE("failed to open binder driver\n");return -1;}//在binder驱动层设置服务管理者角色  if (binder_become_context_manager(bs)) {ALOGE("cannot become context manager (%s)\n", strerror(errno));return -1;}selinux_enabled = is_selinux_enabled();sehandle = selinux_android_service_context_handle();if (selinux_enabled > 0) {if (sehandle == NULL) {ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");abort();}if (getcon(&service_manager_context) != 0) {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 0;
}

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, 0);。。。
}

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

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[32];bwr.write_size = 0;bwr.write_consumed = 0;bwr.write_buffer = 0;readbuf[0] = BC_ENTER_LOOPER;binder_write(bs, readbuf, sizeof(uint32_t));for (;;) {bwr.read_size = sizeof(readbuf);bwr.read_consumed = 0;bwr.read_buffer = (uintptr_t) readbuf;//读取binder节点数据
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);if (res < 0) {ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));break;}//解析
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);if (res == 0) {ALOGE("binder_loop: unexpected reply?!\n");break;}if (res < 0) {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[256/4];struct binder_io msg;struct binder_io reply;int res;bio_init(&reply, rdata, sizeof(rdata), 4);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 -1;}}return r;
}

小结:

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

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

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

转载于:https://www.cnblogs.com/maogefff/p/7661289.html

i.mx6 Android5.1.1 servicemanager本地服务相关推荐

  1. Android Binder机制:编写自己的本地服务

    原址 前面几篇博客中系统地介绍了本地服务的注册.检索以及使用过程.这篇博客我们将完成一个属于自己的本地服务:AllenService. 由前面的学习知道,要完成一个自己的本地服务,需要有IAllenS ...

  2. 工作流编程循序渐进(9:使用本地服务在宿主和工作流之间通信)

    工作流编程循序渐进(9:使用本地服务在宿主和工作流之间通信) 作者  朱先忠 [摘要]       在本篇中,首先详细分析本地服务有关概念,探讨本地服务在工作流运行时.工作流实例及工作流宿主间的地位及 ...

  3. centos7 搭建本地git_本地服务调用K8S环境中的SpringCloud微服务实战

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:原创文章分类汇总及配套源码,涉及Java.Docker.K8S.Devops等 下图是典型的微 ...

  4. windows的服务中的登录身份本地系统账户、本地服务账户和网络服务账户修改

    以一个redis服务为例: 一个redis注册服务后一般是网络服务账户,但是当系统不存在网络服务账户时,就会导致redis服务无法正常启动.接下来修改redis服务的登录身份. cmd下输入如下命令: ...

  5. Android Service学习之本地服务

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

  6. 增加 oracle服务名,oracle本地服务名配置说明

    本地oracle客户端连接远程oracle数据库服务器配置说明如下: 1.找到本地oracle客户端安装目录,如:%path%\Oracle 2.再找配置文件tnsnames.ora,其目录为 %pa ...

  7. WF(9):本地服务之事件处理

    一:先来介绍两个活动 EventDrivenActivity和 ListenActivity. EventDrivenActivity是一个等侍事件触发的容器,EventDrivenActivity第 ...

  8. 如何给Android应用创建本地服务

    Android系统给应用提供了两种类型的服务:启动型本地服务和绑定型本地服务,这两种服务的详细信息请参考"Android Service开发指南" Android Service开 ...

  9. mac如何将本地服务暴露到外网?

    在做微信公众号开发时,需要将本地服务暴露到外网,除了ngrok外,还有什么方法呢? 假设本地有个test文件夹,那么如何才能使别人通过浏览器访问到你的文件夹?接下来介绍另一个方法:localtunne ...

最新文章

  1. 下次迟到的借口有了!牛津大学发现时钟越准确,产生的熵越高
  2. qt combox 向上弹出_一睹芳容!人类首次拍到活的公羊角乌贼 手臂和触须向上飞速穿过水柱...
  3. java将数据封装为树结构_JAVA代码实现多级树结构封装对象
  4. Android布局中涉及的一些属性
  5. CAN总线的初步认识
  6. 灯塔的出现给那些有想法,有能力而又缺乏资金的社区人士提供了一条途径
  7. MFC的六大关键技术
  8. Could not autowire. No beans of 'xxxx' type found的错误提示
  9. java,类的构造方法
  10. maven setting文件_只用一招,让你Maven依赖下载速度快如闪电
  11. 计算机建模报告,计算机三维建模及分析实验报告单.doc
  12. 尴尬又暖心!学生知乎上提问导师人品如何,没想到导师亲自回答了...
  13. 虹膜识别与虹膜定位(续)算法实现
  14. 《推荐系统实践》算法纯享(附代码链接)(四)—— UGC推荐篇
  15. 《商务与经济统计》学习笔记(三)
  16. 世界各国国家代码简称
  17. python 地震数据可视化
  18. php文章下一页,php获取文章上一页与下一页的方法,_PHP教程
  19. 湖南计算机应用技术专科学校排名,湖南所有职业技术学院排名
  20. torch.mul torch.bmm

热门文章

  1. C# Keywords - as
  2. PostgreSQL 行变列的小应用
  3. Yii框架常见问题汇总
  4. python读写kafka集群(转载+自己验证)
  5. 快速保留小数点后面几位(转)
  6. CNN中的权重维度解析以及卷积核中的数值是怎么确定的
  7. navicat使用触发器
  8. ubuntu16.04下面流畅运行pycharm设置
  9. idea 快捷键java
  10. iOS标准库中常用数据结构和算法之二叉排序树