【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
|
存储 监控 安全
探究Linux操作系统的进程管理机制及其优化策略
本文旨在深入探讨Linux操作系统中的进程管理机制,包括进程调度、内存管理以及I/O管理等核心内容。通过对这些关键组件的分析,我们将揭示它们如何共同工作以提供稳定、高效的计算环境,并讨论可能的优化策略。
262 20
|
消息中间件 程序员 数据处理
探究操作系统中的进程间通信(IPC)机制及其在现代软件开发中的应用
本文深入探讨了操作系统中的核心概念——进程间通信(IPC),揭示了其在现代软件开发中的关键作用。通过对各种IPC机制如管道、消息队列、共享内存等的详细分析,本文旨在为读者提供一个清晰的理解框架,帮助他们掌握如何在实际应用中有效利用这些技术以实现进程间的协同工作。此外,文章还将探讨IPC在高并发环境下的性能优化策略,以及如何避免常见的IPC编程错误。通过结合理论与实践,本文不仅适合希望深入了解操作系统原理的技术人员阅读,也对那些致力于提升软件质量和开发效率的程序员具有重要参考价值。
339 12
|
消息中间件 存储 网络协议
操作系统的心脏:深入理解进程间通信(IPC)机制
在现代计算机系统中,操作系统扮演着至关重要的角色,而进程间通信(IPC)作为操作系统的核心功能之一,极大地影响着系统的性能和稳定性。本文将通过浅显易懂的语言,详细探讨进程间通信的基本原理、主要类型及其实际应用,旨在为读者提供一个清晰且全面的理解和认识。 ##
758 1
|
算法 调度 UED
探索操作系统的心脏——进程管理机制
本文将深入探讨操作系统中至关重要的部分——进程管理机制。我们将从基本概念入手,逐步解析进程的定义、状态及其在操作系统中的角色。随后,我们会详细讨论进程调度算法,包括先来先服务、短作业优先、时间片轮转和优先级调度等,分析它们的优势与应用情景。最后,通过实例展示这些算法在实际系统运作中的运用,帮助读者更好地理解进程管理的核心原理。
|
消息中间件 安全 Kafka
Python IPC机制全攻略:让进程间通信变得像呼吸一样自然
【9月更文挑战第12天】在编程领域,进程间通信(IPC)是连接独立执行单元的关键技术。Python凭借简洁的语法和丰富的库支持,提供了多种IPC方案。本文将对比探讨Python的IPC机制,包括管道与消息队列、套接字与共享内存。管道适用于简单场景,而消息队列更灵活,适合高并发环境。套接字广泛用于网络通信,共享内存则在本地高效传输数据。通过示例代码展示`multiprocessing.Queue`的使用,帮助读者理解IPC的实际应用。希望本文能让你更熟练地选择和运用IPC机制。
258 10
|
人工智能 Kubernetes 算法
探究操作系统的心脏——进程管理机制
本文深入探讨了操作系统核心组件之一——进程管理机制。进程管理作为操作系统的基础功能,负责协调和控制计算机系统内运行的所有进程,确保系统资源的有效分配与利用。通过详细介绍进程的定义、状态转换、调度算法以及多线程技术等关键概念,本文揭示了进程管理如何支撑起整个操作系统的运行框架,并保障用户任务的顺利执行。同时,文章还讨论了现代操作系统在进程管理方面的创新与挑战,为读者提供了一个全面而深入的理解视角。
219 1
|
消息中间件 Python
深入理解操作系统的进程间通信(IPC)机制
本文将探讨操作系统中的核心概念——进程间通信(IPC),揭示其在系统运作中的重要性及实现方式。通过分析不同类型的IPC手段,如管道、信号、共享内存等,帮助读者更好地理解操作系统的内部工作原理及其在实际应用中的表现。
616 1
|
消息中间件 安全 数据库
动手实操!Python IPC机制,打造高效协同的进程军团
【9月更文挑战第10天】在软件开发领域,进程间的高效协作对应用性能与稳定性至关重要。Python提供了多种进程间通信(IPC)机制,如管道、消息队列、套接字、共享内存等,帮助开发者构建高效协同的系统。本文将通过动手实践,使用`multiprocessing`模块演示如何利用队列实现进程间通信。示例代码展示了如何创建一个工作进程从队列接收并处理数据,从而实现安全高效的进程交互。通过实际操作,读者可以深入了解Python IPC的强大功能,提升系统的并发处理能力。
165 1
|
消息中间件 存储 大数据
深入理解操作系统中的进程间通信(IPC)机制
本文旨在探讨操作系统中进程间通信(IPC)的核心机制与其重要性。通过对不同IPC手段如管道、信号、消息队列及共享内存等的详细解析,揭示它们如何高效地促进进程间的信息交换与同步。文章不仅阐述各种IPC技术的实现原理,还探讨了它们在实际系统应用中的场景与优化策略,为系统开发者提供全面而深入的理解。

热门文章

最新文章