返回介绍

4. Binder 驱动

发布于 2024-12-23 21:29:01 字数 6124 浏览 0 评论 0 收藏 0

关于 binder 驱动建议参考另一篇文章 深入分析 Android Binder 驱动 [原文]( Android Binder ,本小节仍需要完善。

Binder 驱动是 Binder 的最终实现, ServiceManager 和 Client/Service 进程间通信最终都是由 Binder 驱动投递的。

Binder reference

Binder 驱动的代码位于 kernel 代码的 drivers/staging/android 目录下。主文件是 binder.hbinder.c

进程间传输的数据被称为 Binder 对象,它是一个 flat_binder_object ,结构如下

struct flat_binder_object {
  /* 8 bytes for large_flat_header. */
  unsigned long     type;
  unsigned long     flags;

  /* 8 bytes of data. */
  union {
    void    *binder;  /* local object */
    signed long handle;   /* remote object */
  };

  /* extra data associated with local object */
  void      *cookie;
};

其中 类型 type 描述了 Binder 对象的类型,包含 BINDER (本地对象)、 HANDLE (远程对象)、 FD 三大类(五种)

enum {
  BINDER_TYPE_BINDER  = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),
  BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),
  BINDER_TYPE_HANDLE  = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
  BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
  BINDER_TYPE_FD    = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
};

flags 则表述了 传输方式 ,如异步、无返回等

enum transaction_flags {
  TF_ONE_WAY  = 0x01, /* this is a one-way call: async, no return */
  TF_ROOT_OBJECT  = 0x04, /* contents are the component's root object */
  TF_STATUS_CODE  = 0x08, /* contents are a 32-bit status code */
  TF_ACCEPT_FDS   = 0x10, /* allow replies with file descriptors */
};

flat_binder_object 中的 union 联合体 就是要传输的数据,当类型为 BINDER 时, 数据就是一个本地对象 *binder ,而类型为 HANDLE 时,数据则是一个远程对象 handle

flat_binder_object 在进程间传递时, Binder 驱动会修改它的类型和数据,交换的代码参考 binder_transaction 的实现。

该如何理解本地 BINDER 对象和远程 HANDLE 对象呢?其实它们都代表同一个对象,不过是从不同的角度来看。举例来说,假如进程 RemoteService 有个对象 mBinder ,对于 RemoteService 来说, mBinder 就是一个本地的 BINDER 对象;如果进程 app 通过 Binder 驱动访问 RemoteServicemBinder 对象,对于 app 来说, mBinder 就是一个 HANDLE 。因此,从根本上来说 handlebinder 都指向 RemoteServicemBinder 。本地对象还可以带有额外的数据,保存在 cookie 中。

Binder 驱动直接操作的最外层数据结构是 binder_transaction_data , Binder 对象 flat_binder_object 被封装在 binder_transaction_data 结构体中。

binder_transaction_data 数据结构才是真正传输的数据,其定义如下

struct binder_transaction_data {
  /* The first two are only used for bcTRANSACTION and brTRANSACTION,
   * identifying the target and contents of the transaction.
   */
  union {
    size_t  handle; /* target descriptor of command transaction */
    void  *ptr;   /* target descriptor of return transaction */
  } target;
  void    *cookie;  /* target object cookie */
  unsigned int  code;     /* transaction command */

  /* General information about the transaction. */
  unsigned int  flags;
  pid_t     sender_pid;
  uid_t     sender_euid;
  size_t    data_size;  /* number of bytes of data */
  size_t    offsets_size;   /* number of bytes of offsets */

  /* If this transaction is inline, the data immediately
   * follows here; otherwise, it ends with a pointer to
   * the data buffer.
   */
  union {
    struct {
      /* transaction data */
      const void  *buffer;
      /* offsets from buffer to flat_binder_object structs */
      const void  *offsets;
    } ptr;
    uint8_t buf[8];
  } data;
};

flat_binder_object 就被封装在 *buffer 中,其中的 unsigned int code; 则是传输命令,描述了 Binder 对象执行的操作。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文