接在之前的

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

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

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

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

  1. #名字为servicemanager的服务,可执行文件的路径在/system/bin/servicemanager
  2. #属于core类,用户为:system,用户组为:system
  3. #critical:如果在几分钟内一直没响应则重启服务
  4. #重启servicemanager需要冲入如下的服务healthd,zygote,media,surfaceflinger,drm
  5. service servicemanager /system/bin/servicemanager
  6. class core
  7. user system
  8. group system
  9. critical
  10. onrestart restart healthd
  11. onrestart restart zygote
  12. onrestart restart media
  13. onrestart restart surfaceflinger
  14. onrestart restart drm

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

查看android.mk

  1. include $(CLEAR_VARS)
  2. LOCAL_SHARED_LIBRARIES := liblog libselinux
  3. LOCAL_SRC_FILES := service_manager.c binder.c
  4. LOCAL_CFLAGS += $(svc_c_flags)
  5. LOCAL_MODULE := servicemanager
  6. include $(BUILD_EXECUTABLE)

可以得知,就是在service_manager.c

  1. int main(int argc, char **argv)
  2. {
  3. struct binder_state *bs;
  4.  
  5. //打开binder设备驱动文件,并将Binder设备文件映射到servicemanger进程的地址空间中
  6. bs = binder_open(*);
  7. if (!bs) {
  8. ALOGE("failed to open binder driver\n");
  9. return -;
  10. }
  11.  
  12. //在binder驱动层设置服务管理者角色
  13. if (binder_become_context_manager(bs)) {
  14. ALOGE("cannot become context manager (%s)\n", strerror(errno));
  15. return -;
  16. }
  17.  
  18. selinux_enabled = is_selinux_enabled();
  19. sehandle = selinux_android_service_context_handle();
  20.  
  21. if (selinux_enabled > ) {
  22. if (sehandle == NULL) {
  23. ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
  24. abort();
  25. }
  26.  
  27. if (getcon(&service_manager_context) != ) {
  28. ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
  29. abort();
  30. }
  31. }
  32.  
  33. union selinux_callback cb;
  34. cb.func_audit = audit_callback;
  35. selinux_set_callback(SELINUX_CB_AUDIT, cb);
  36. cb.func_log = selinux_log_callback;
  37. selinux_set_callback(SELINUX_CB_LOG, cb);
  38.   //接收到请求后的需要执行的回调函数
  39. svcmgr_handle = BINDER_SERVICE_MANAGER;
  40. //进入binder.c循环,等待客户请求
  41. binder_loop(bs, svcmgr_handler);
  42.  
  43. return ;
  44. }
  1. struct binder_state *binder_open(size_t mapsize)
  2. {
  3. 。。。
  4.   //打开设备节点
  5. bs->fd = open("/dev/binder", O_RDWR);
  6. 。。。
    //映射
  7. bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, );
  8. 。。。
  9. }

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

  1. int svcmgr_handler(struct binder_state *bs,
  2. struct binder_transaction_data *txn,
  3. struct binder_io *msg,
  4. struct binder_io *reply)
  5. {
  6. 。。。
  7. switch(txn->code) {
  8. case SVC_MGR_GET_SERVICE:
  9. case SVC_MGR_CHECK_SERVICE:
  10. s = bio_get_string16(msg, &len);
  11. if (s == NULL) {
  12. return -1;
  13. }
         //查找相关的服务,如果有,则返回其句柄
  14. handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
  15. if (!handle)
  16. break;
  17. bio_put_ref(reply, handle);
  18. return 0;
  19.  
  20. case SVC_MGR_ADD_SERVICE:
  21. s = bio_get_string16(msg, &len);
  22. if (s == NULL) {
  23. return -1;
  24. }
  25. handle = bio_get_ref(msg);
  26. allow_isolated = bio_get_uint32(msg) ? 1 : 0;
         //想servicemanager添加服务
  27. if (do_add_service(bs, s, len, handle, txn->sender_euid,
  28. allow_isolated, txn->sender_pid))
  29. return -1;
  30. break;
  31.  
  32. case SVC_MGR_LIST_SERVICES: {
  33. uint32_t n = bio_get_uint32(msg);
  34.  
  35. if (!svc_can_list(txn->sender_pid)) {
  36. ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
  37. txn->sender_euid);
  38. return -1;
  39. }
  40. si = svclist;
  41. while ((n-- > 0) && si)
  42. si = si->next;
  43. if (si) {
  44. bio_put_string16(reply, si->name);
  45. return 0;
  46. }
  47. return -1;
  48. }
  49. default:
  50. ALOGE("unknown code %d\n", txn->code);
  51. return -1;
  52. }
  53.  
  54. bio_put_uint32(reply, 0);
  55. return 0;
  56. }
  1. void binder_loop(struct binder_state *bs, binder_handler func)
  2. {
  3. int res;
  4. struct binder_write_read bwr;
  5. uint32_t readbuf[];
  6.  
  7. bwr.write_size = ;
  8. bwr.write_consumed = ;
  9. bwr.write_buffer = ;
  10.  
  11. readbuf[] = BC_ENTER_LOOPER;
  12. binder_write(bs, readbuf, sizeof(uint32_t));
  13.  
  14. for (;;) {
  15. bwr.read_size = sizeof(readbuf);
  16. bwr.read_consumed = ;
  17. bwr.read_buffer = (uintptr_t) readbuf;
  18.      //读取binder节点数据
  19. res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
  20.     
  21. if (res < ) {
  22. ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
  23. break;
  24. }
  25.      //解析
  26. res = binder_parse(bs, , (uintptr_t) readbuf, bwr.read_consumed, func);
  27. if (res == ) {
  28. ALOGE("binder_loop: unexpected reply?!\n");
  29. break;
  30. }
  31. if (res < ) {
  32. ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
  33. break;
  34. }
  35. }
  36. }
  1. int binder_parse(struct binder_state *bs, struct binder_io *bio,
  2. uintptr_t ptr, size_t size, binder_handler func)
  3. {
  4.   。。。
  5. switch(cmd) {
  6.     。。。
  7. binder_dump_txn(txn);
  8. if (func) {
  9. unsigned rdata[/];
  10. struct binder_io msg;
  11. struct binder_io reply;
  12. int res;
  13.  
  14. bio_init(&reply, rdata, sizeof(rdata), );
  15. bio_init_from_txn(&msg, txn);
              //注意:这个是之前我们传进来的回调函数
  16. res = func(bs, txn, &msg, &reply);
  17. binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
  18. }
  19. ptr += sizeof(*txn);
  20. break;
  21. }
  22. 。。。default:
  23. ALOGE("parse: OOPS %d\n", cmd);
  24. return -;
  25. }
  26. }
  27.  
  28. return r;
  29. }

小结:

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. C# 连接sqlite数据库

    web.config <connectionStrings> <add name="SQLiteDB" connectionString="Data S ...

  2. c# 生成二维码图片

    转载自:https://blog.csdn.net/hyunbar/article/details/78271778 1.在C#中直接引用ThoughtWorks.QRCode.dll 类 2.封装方 ...

  3. JVM垃圾收集器(1)

    此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法& ...

  4. django系列6--Ajax04 请求设置(设置csrf_token)

    Ajax请求设置csrf_token 官方文档 csrf_token: https://docs.djangoproject.com/en/1.11/ref/csrf/ CSRF 跨站请求攻击,简单地 ...

  5. 安装zlib的过程(Compression requires the (missing) zlib module)(Python2.6升级为2.7出现的问题)

    觉得有必要把解决问题的过程写下来 1,因为要安装flask,所以安装pip,所以安装setuptools,所以安装zlib.(具体过程http://www.cnblogs.com/aiyr/p/726 ...

  6. 部署LVS-DR群集

    一.LVS-DR原理剖析 (一)LVS-DR数据包流向分析 1.Client向目标VIP发出请求,Director(负载均衡器)接收.此时IP包头及数据帧头信息为: 2.Director根据负载均衡算 ...

  7. jmeter服务器监控插件指标简单说明

    以下是下载了服务器监控插件的各个组件的功能介绍,有助于以后jmeter的性能测试 1.jp@gc - Actiive Threads Over Time:不同时间的活动用户数量展示(图表) 当前的时间 ...

  8. 为什么说 Gumroad 是一家 “失败” 的创业公司?

    Gumroad 是一家 "失败" 的创业公司. 创立于 2012 年,Gumroad 是一个面向创造者的电商平台.创始人 Sahil Lavingia,一名 19 岁的少年,Pin ...

  9. /proc/xxx/maps简要记录

    定位内存泄漏基本上是从宏观到微观,进而定位到代码位置. 从/proc/meminfo可以看到整个系统内存消耗情况,使用top可以看到每个进程的VIRT(虚拟内存)和RES(实际占用内存),基本上就可以 ...

  10. Python【每日一问】16

    问: [基础题]TCP/UDP/HTTP协议区别 [提高题]在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数, ...