i.mx6 Android5.1.1 servicemanager本地服务
接在之前的
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本地服务的更多相关文章
- i.mx6 Android5.1.1 初始化流程之init.rc解析(未完成)
接上一篇:i.mx6 Android5.1.1 初始化流程之init进程 参考资料:http://blog.csdn.net/mr_raptor/article/category/799879 这个博 ...
- i.mx6 Android5.1.1 初始化流程之框架
Android启动过程分为以下几个步骤: 1. Boot ROM: 上电后启动芯片固话代码. 2. BootLoader:固话代码会根据启动模式启动bootloader,(一般为启动引脚的电平的 ...
- i.mx6 Android5.1.1 System server
1. 概述: 1. Zygote进程是Android Java世界的开创者,所有的Java应用程序进程都由Zygote进程创建: 2. Zygote创建应用程序进程过程其实就是复制自身进程地址空间作为 ...
- i.mx6 Android5.1.1 初始化流程之init进程(未完成)
概述: 接在i.mx6 Android5.1.1 初始化流程之框架之后 参考资料:http://blog.csdn.net/mr_raptor/article/category/799879 相关源码 ...
- Python 启动本地服务
在 Linux 服务器上或安装了 Python 的机器上,Python自带了一个WEB服务器 SimpleHTTPServer,我们可以很简单的使用 python -m SimpleHTTPServ ...
- 利用node构建本地服务
利用node构建本地服务 首先安装下node.js,地址为https://nodejs.org/en/,然后安装npm. node.js的中文api地址http://nodeapi.ucdok.com ...
- Android Service学习之本地服务
Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过来声明.可以通过contect.startservice和contect.bindse ...
- Anroid四大组件service之本地服务
服务是Android四大组件之一,与Activity一样,代表可执行程序.但Service不像Activity有可操作的用户界面,它是一直在后台运行.用通俗易懂点的话来说: 如果某个应用要在运行时向用 ...
- webpack-dev-server 搭建本地服务以及浏览器实时刷新
一.概述开发项目中为了保证上线,开发项目是都需要使用localhost进行开发,以前的做法就是本地搭建Apache或者Tomcat服务器.有的前端开发人员 对服务器的搭建和配置并不熟悉,这个时候需要后 ...
随机推荐
- C# 连接sqlite数据库
web.config <connectionStrings> <add name="SQLiteDB" connectionString="Data S ...
- c# 生成二维码图片
转载自:https://blog.csdn.net/hyunbar/article/details/78271778 1.在C#中直接引用ThoughtWorks.QRCode.dll 类 2.封装方 ...
- JVM垃圾收集器(1)
此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法& ...
- django系列6--Ajax04 请求设置(设置csrf_token)
Ajax请求设置csrf_token 官方文档 csrf_token: https://docs.djangoproject.com/en/1.11/ref/csrf/ CSRF 跨站请求攻击,简单地 ...
- 安装zlib的过程(Compression requires the (missing) zlib module)(Python2.6升级为2.7出现的问题)
觉得有必要把解决问题的过程写下来 1,因为要安装flask,所以安装pip,所以安装setuptools,所以安装zlib.(具体过程http://www.cnblogs.com/aiyr/p/726 ...
- 部署LVS-DR群集
一.LVS-DR原理剖析 (一)LVS-DR数据包流向分析 1.Client向目标VIP发出请求,Director(负载均衡器)接收.此时IP包头及数据帧头信息为: 2.Director根据负载均衡算 ...
- jmeter服务器监控插件指标简单说明
以下是下载了服务器监控插件的各个组件的功能介绍,有助于以后jmeter的性能测试 1.jp@gc - Actiive Threads Over Time:不同时间的活动用户数量展示(图表) 当前的时间 ...
- 为什么说 Gumroad 是一家 “失败” 的创业公司?
Gumroad 是一家 "失败" 的创业公司. 创立于 2012 年,Gumroad 是一个面向创造者的电商平台.创始人 Sahil Lavingia,一名 19 岁的少年,Pin ...
- /proc/xxx/maps简要记录
定位内存泄漏基本上是从宏观到微观,进而定位到代码位置. 从/proc/meminfo可以看到整个系统内存消耗情况,使用top可以看到每个进程的VIRT(虚拟内存)和RES(实际占用内存),基本上就可以 ...
- Python【每日一问】16
问: [基础题]TCP/UDP/HTTP协议区别 [提高题]在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数, ...