【Binder 机制】Native 层 Binder 机制分析 ( service_manager.c | 开启 Binder | 注册 Binder 进程上下文 | 开启 Binder 循环 )(一)

简介: 【Binder 机制】Native 层 Binder 机制分析 ( service_manager.c | 开启 Binder | 注册 Binder 进程上下文 | 开启 Binder 循环 )(一)

文章目录

一、系统服务

二、系统服务主函数

三、开启 Binder

四、注册上下文

五、开启 Binder 循环

六、binder_write 方法

七、binder_ioctl 内核方法

八、binder_ioctl_write_read 内核方法





一、系统服务


System Server 是由 Zygote 进程 fork() 出来的 ;


Init 进程 启动 Zygote , Zygote 启动 System Server 进程 ;


System Server 注册服务时 , 会执行 service_manager.c 中的方法 ;






二、系统服务主函数


service_manager.c 从 int main(int argc, char** argv) 方法开始执行 , 在该 main 函数中 , 执行了 3 33 个重要操作 :


① 开启 Binder : 获取 Binder 驱动 , 并且申请了 128 KB 的内存映射地址 , bs = binder_open(driver, 128*1024); ;

② 注册上下文 : 将自己注册成 Binder 进程的上下文 , binder_become_context_manager(bs) ;

③ 开启 Binder 循环 : 不停的轮询 , 是否有消息发送 , binder_loop(bs, svcmgr_handler); ;

int main(int argc, char** argv)
{
  // 开启 Binder , 获取 Binder 驱动 , 并且申请了 128 KB 的内存映射地址
    bs = binder_open(driver, 128*1024);
  // 将自己注册成 Binder 进程的上下文
    if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
  // 开启 Binder 循环 
    binder_loop(bs, svcmgr_handler);
    return 0;
}


完整代码参考 /frameworks/native/cmds/servicemanager/service_manager.c ;






三、开启 Binder


通过调用 bs = binder_open(driver, 128*1024); 开启 Binder 的方法 struct binder_state *binder_open(const char* driver, size_t mapsize) , 定义在 /frameworks/native/cmds/servicemanager/binder.c 中 ;


首先分析下 binder_state 结构体 , 其中有 3 33 个参数 ,


int fd : Binder 驱动的文件描述

void *mapped : 内存映射首地址

size_t mapsize : 内存映射的大小 , 128 KB

方法最终返回一个 binder_state 结构体 ;


struct binder_state
{
    int fd;   // Binder 驱动的文件描述
    void *mapped; // 内存映射首地址
    size_t mapsize; // 内存映射的大小 , 128 KB 
};
// 打开 Binder , 并获取 Binder 的状态描述
struct binder_state *binder_open(const char* driver, size_t mapsize)
{
    struct binder_state *bs;  // 返回的结构体
    struct binder_version vers;
    bs = malloc(sizeof(*bs)); // 为返回值申请内存
    if (!bs) {
        errno = ENOMEM;
        return NULL;
    }
    bs->fd = open(driver, O_RDWR | O_CLOEXEC);
    if (bs->fd < 0) {
        fprintf(stderr,"binder: cannot open %s (%s)\n",
                driver, strerror(errno));
        goto fail_open;
    }
    if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
        (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
        fprintf(stderr,
                "binder: kernel driver version (%d) differs from user space version (%d)\n",
                vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
        goto fail_open;
    }
    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    if (bs->mapped == MAP_FAILED) {
        fprintf(stderr,"binder: cannot map device (%s)\n",
                strerror(errno));
        goto fail_map;
    }
    return bs;
fail_map:
    close(bs->fd);
fail_open:
    free(bs);
    return NULL;
}


完整代码参考 /frameworks/native/cmds/servicemanager/binder.c#97;






四、注册上下文


通过调用 binder_become_context_manager(bs) , 将自己注册成 Binder 进程的上下文 ; 其中调用的 ioctl 方法是内核中的方法 , 这是 IO Control 的简称 ; 这个代码得去内核中查找 ;


int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}


完整代码参考 /frameworks/native/cmds/servicemanager/binder.c#147


在 【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 ) 博客中分析了该 ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0) 方法对应的源码 ;






五、开启 Binder 循环


在 service_manager.c 的 main 函数中 , 调用 binder_loop(bs, svcmgr_handler) 开启 Binder 循环 ;


binder_loop 方法定义在 /frameworks/native/cmds/servicemanager/binder.c 中 ;


在 binder_loop 方法中 , 先调用了 binder_write 方法 , 然后开启了死循环 ;


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;
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }
  // 如果收到 Binder 读写消息信息 , 调用 binder_parse 方法处理 ;
        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;
        }
    }
}


完整代码参考 /frameworks/native/cmds/servicemanager/binder.c ;



目录
相关文章
Linux源码阅读笔记10-进程NICE案例分析2
Linux源码阅读笔记10-进程NICE案例分析2
Linux源码阅读笔记09-进程NICE案例分析1
Linux源码阅读笔记09-进程NICE案例分析1
|
弹性计算 运维 监控
基于进程热点分析与系统资源优化的智能运维实践
智能服务器管理平台提供直观的可视化界面,助力高效操作系统管理。核心功能包括运维监控、智能助手和扩展插件管理,支持系统健康监控、故障诊断等,确保集群稳定运行。首次使用需激活服务并安装管控组件。平台还提供进程热点追踪、性能观测与优化建议,帮助开发人员快速识别和解决性能瓶颈。定期分析和多维度监控可提前预警潜在问题,保障系统长期稳定运行。
761 17
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
742 4
|
运维 JavaScript jenkins
鸿蒙5.0版开发:分析CppCrash(进程崩溃)
在HarmonyOS 5.0中,CppCrash指C/C++运行时崩溃,常见原因包括空指针、数组越界等。系统提供基于posix信号机制的异常检测能力,生成详细日志辅助定位。本文详解CppCrash分析方法,涵盖异常检测、问题定位思路及案例分析。
846 4
|
运维 监控 JavaScript
鸿蒙next版开发:分析JS Crash(进程崩溃)
在HarmonyOS 5.0中,JS Crash指未处理的JavaScript异常导致应用意外退出。本文详细介绍如何分析JS Crash,包括异常捕获、日志分析和典型案例,帮助开发者定位问题、修复错误,提升应用稳定性。通过DevEco Studio收集日志,结合HiChecker工具,有效解决JS Crash问题。
1037 4
|
存储 监控 安全
探究Linux操作系统的进程管理机制及其优化策略
本文旨在深入探讨Linux操作系统中的进程管理机制,包括进程调度、内存管理以及I/O管理等核心内容。通过对这些关键组件的分析,我们将揭示它们如何共同工作以提供稳定、高效的计算环境,并讨论可能的优化策略。
469 20
|
消息中间件 存储 Linux
|
消息中间件 程序员 数据处理
探究操作系统中的进程间通信(IPC)机制及其在现代软件开发中的应用
本文深入探讨了操作系统中的核心概念——进程间通信(IPC),揭示了其在现代软件开发中的关键作用。通过对各种IPC机制如管道、消息队列、共享内存等的详细分析,本文旨在为读者提供一个清晰的理解框架,帮助他们掌握如何在实际应用中有效利用这些技术以实现进程间的协同工作。此外,文章还将探讨IPC在高并发环境下的性能优化策略,以及如何避免常见的IPC编程错误。通过结合理论与实践,本文不仅适合希望深入了解操作系统原理的技术人员阅读,也对那些致力于提升软件质量和开发效率的程序员具有重要参考价值。
680 13
|
算法 调度 UED
探索操作系统的心脏——进程管理机制
本文将深入探讨操作系统中至关重要的部分——进程管理机制。我们将从基本概念入手,逐步解析进程的定义、状态及其在操作系统中的角色。随后,我们会详细讨论进程调度算法,包括先来先服务、短作业优先、时间片轮转和优先级调度等,分析它们的优势与应用情景。最后,通过实例展示这些算法在实际系统运作中的运用,帮助读者更好地理解进程管理的核心原理。

热门文章

最新文章