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

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

六、binder_write 方法


在 binder_write 方法中 , 调用了内核中的 ioctl(bs->fd, BINDER_WRITE_READ, &bwr) 方法 ; 具体方法参考 【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 ) 博客进行分析 ;


int binder_write(struct binder_state *bs, void *data, size_t len)
{
    struct binder_write_read bwr;
    int res;
    bwr.write_size = len;
    bwr.write_consumed = 0;
    bwr.write_buffer = (uintptr_t) data;
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;
    // 此处调用了内核方法 
    res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    if (res < 0) {
        fprintf(stderr,"binder_write: ioctl failed (%s)\n",
                strerror(errno));
    }
    return res;
}


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






七、binder_ioctl 内核方法


分析调用内核方法 ioctl(bs->fd, BINDER_WRITE_READ, &bwr) , 传入 BINDER_WRITE_READ 常量 , 走如下分支代码 ; 主要调用了 binder_ioctl_write_read 方法 ;


case BINDER_WRITE_READ:
  ret = binder_ioctl_write_read(filp, cmd, arg, thread);
  if (ret)
    goto err;
  break;


android-mainline/drivers/android/binder.c 部分内核 Binder 驱动代码 :


static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
  int ret;
  struct binder_proc *proc = filp->private_data;
  struct binder_thread *thread;
  unsigned int size = _IOC_SIZE(cmd);
  void __user *ubuf = (void __user *)arg;
  /*pr_info("binder_ioctl: %d:%d %x %lx\n",
    proc->pid, current->pid, cmd, arg);*/
  binder_selftest_alloc(&proc->alloc);
  trace_binder_ioctl(cmd, arg);
  ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  if (ret)
  goto err_unlocked;
  thread = binder_get_thread(proc);
  if (thread == NULL) {
  ret = -ENOMEM;
  goto err;
  }
  switch (cmd) {
  case BINDER_WRITE_READ:
  ret = binder_ioctl_write_read(filp, cmd, arg, thread);
  if (ret)
    goto err;
  break;
  default:
  ret = -EINVAL;
  goto err;
  }
  ret = 0;
err:
  if (thread)
  thread->looper_need_return = false;
  wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  if (ret && ret != -EINTR)
  pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
err_unlocked:
  trace_binder_ioctl_done(ret);
  return ret;
}


完整代码参考 https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/binder.c ;






八、binder_ioctl_write_read 内核方法


在 方法中 , 调用了 2 22 个重要的方法 , copy_from_user(&bwr, ubuf, sizeof(bwr)) 从用户空间的进程缓冲区中读取到内核空间缓冲区 , copy_to_user(ubuf, &bwr, sizeof(bwr)) 从内核空间写出到用户空间进程中 ;

如果写出的数据大于 0 , 则调用 binder_thread_write 方法 ;

如果读取的数据大于 0 , 则调用 binder_thread_read 方法 ;


static int binder_ioctl_write_read(struct file *filp,
    unsigned int cmd, unsigned long arg,
    struct binder_thread *thread)
{
  int ret = 0;
  struct binder_proc *proc = filp->private_data;
  unsigned int size = _IOC_SIZE(cmd);
  void __user *ubuf = (void __user *)arg;
  struct binder_write_read bwr;
  if (size != sizeof(struct binder_write_read)) {
  ret = -EINVAL;
  goto out;
  }
  // 从用户空间的进程缓冲区中读取到内核空间缓冲区 
  if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
  ret = -EFAULT;
  goto out;
  }
  binder_debug(BINDER_DEBUG_READ_WRITE,
       "%d:%d write %lld at %016llx, read %lld at %016llx\n",
       proc->pid, thread->pid,
       (u64)bwr.write_size, (u64)bwr.write_buffer,
       (u64)bwr.read_size, (u64)bwr.read_buffer);
  // 如果写出的数据大于 0 
  if (bwr.write_size > 0) {
  ret = binder_thread_write(proc, thread,
       bwr.write_buffer,
       bwr.write_size,
       &bwr.write_consumed);
  trace_binder_write_done(ret);
  if (ret < 0) {
    bwr.read_consumed = 0;
    if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
    ret = -EFAULT;
    goto out;
  }
  }
  // 如果读取的数据大于 0 
  if (bwr.read_size > 0) {
  ret = binder_thread_read(proc, thread, bwr.read_buffer,
      bwr.read_size,
      &bwr.read_consumed,
      filp->f_flags & O_NONBLOCK);
  trace_binder_read_done(ret);
  binder_inner_proc_lock(proc);
  if (!binder_worklist_empty_ilocked(&proc->todo))
    binder_wakeup_proc_ilocked(proc);
  binder_inner_proc_unlock(proc);
  if (ret < 0) {
    if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
    ret = -EFAULT;
    goto out;
  }
  }
  binder_debug(BINDER_DEBUG_READ_WRITE,
       "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
       proc->pid, thread->pid,
       (u64)bwr.write_consumed, (u64)bwr.write_size,
       (u64)bwr.read_consumed, (u64)bwr.read_size);
  // 从内核空间写出到用户空间进程中 
  if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
  ret = -EFAULT;
  goto out;
  }
out:
  return ret;
}


完整代码参考 https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/binder.c ;


目录
相关文章
|
8月前
|
弹性计算 运维 监控
基于进程热点分析与系统资源优化的智能运维实践
智能服务器管理平台提供直观的可视化界面,助力高效操作系统管理。核心功能包括运维监控、智能助手和扩展插件管理,支持系统健康监控、故障诊断等,确保集群稳定运行。首次使用需激活服务并安装管控组件。平台还提供进程热点追踪、性能观测与优化建议,帮助开发人员快速识别和解决性能瓶颈。定期分析和多维度监控可提前预警潜在问题,保障系统长期稳定运行。
325 17
Linux源码阅读笔记10-进程NICE案例分析2
Linux源码阅读笔记10-进程NICE案例分析2
Linux源码阅读笔记09-进程NICE案例分析1
Linux源码阅读笔记09-进程NICE案例分析1
|
监控 Linux 应用服务中间件
探索Linux中的`ps`命令:进程监控与分析的利器
探索Linux中的`ps`命令:进程监控与分析的利器
394 13
|
Android开发 移动开发 小程序
binder机制原理面试,安卓app开发教程
binder机制原理面试,安卓app开发教程
binder机制原理面试,安卓app开发教程
|
算法 Linux 编译器
技术笔记:LINUX2.6.32下的进程分析
技术笔记:LINUX2.6.32下的进程分析
101 0
|
缓存 监控 调度
第六十一章 使用 ^PERFSAMPLE 监控进程 - 分析维度
第六十一章 使用 ^PERFSAMPLE 监控进程 - 分析维度
150 0
|
11月前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
431 4
|
运维 JavaScript jenkins
鸿蒙5.0版开发:分析CppCrash(进程崩溃)
在HarmonyOS 5.0中,CppCrash指C/C++运行时崩溃,常见原因包括空指针、数组越界等。系统提供基于posix信号机制的异常检测能力,生成详细日志辅助定位。本文详解CppCrash分析方法,涵盖异常检测、问题定位思路及案例分析。
445 4
|
运维 监控 JavaScript
鸿蒙next版开发:分析JS Crash(进程崩溃)
在HarmonyOS 5.0中,JS Crash指未处理的JavaScript异常导致应用意外退出。本文详细介绍如何分析JS Crash,包括异常捕获、日志分析和典型案例,帮助开发者定位问题、修复错误,提升应用稳定性。通过DevEco Studio收集日志,结合HiChecker工具,有效解决JS Crash问题。
493 4