Jimmy Chen

A Programmer

(原创)Linux中的Binder驱动

前言

  Binder驱动是Android专用的,但是其在Linux底层中的框架和Linux驱动是一样的。Binder驱动是以Misc设备进行注册,binder驱动是一个虚拟的设备驱动,没有和任何的实际硬件相关联,其主要的作用就是进行设备内存的管理。这篇主要看一下Linux下Binder驱动的代码。

Binder驱动代码分析

  既然Binder驱动也是一个Linux驱动,那么必然是按照Linux驱动的规则编写的,所以我们先来查看一下init函数的代码。

在misc_register(&binder_miscdev)中将binder驱动注册为杂项设备驱动,下面看看binder_miscdev结构体相关信息

上面分析了设备的注册入口init函数,接下来分析binder中file_operations结构体内的函数。

binder_open函数

  这个函数的主要作用就是创建一个struct binder_proc数据结构来保存打开设备文件/dev/binder的进程上下文信息,并且将这个进程上下文信息保存到打开文件结构struct file的私有成员变量privet_data中,这样,在执行其他的操作的时候,就能够通过打开struct file来获取这个进程上下文的信息。这个进行上下文的信息还会同步保存到一个全局哈希表binder_procs中,供程序的内部使用。

binder_mmap函数

对于内存映射、vm_struct、vm_area_struct的相关内容大家可以看我写的另一篇博客(https://blog4jimmy.com/2018/01/348.html),看完之后应该会对理解binder_mmap的代码有所帮助的。接下来看一下binder_update_page_range这个函数的内容。

binder_update_page_range函数

这里主要做的工作主要流程是在:

binder_mmap函数内执行get_vm_area()函数分配内核虚拟空间,然后调用到binder_update_page_range函数,在这个函数里面调用alloc_page()函数进行物理内存的分配,然后调用map_vm_area()函数将物理内存映射到内核虚拟空间,之后再调用vm_insert_page()函数将物理页面映射到虚拟用户空间。

biner_ioctl函数

binder_ioctl中包含的函数大部分都比较简单,这里我们只看看用的最多的binder_ioctl_write_read函数,至于binder_ioctl_set_ctx_mgr函数会在serviceManager部分再细讲。

binder_ioctl_write_read函数

binder中各种结构体的信息

声明,这部分博客整理自:http://gityuan.com/2015/11/01/binder-driver/

不得不说这一部分的内容比较无聊,实际可以先不看,到时候用到再回来查吧,我也是结合别人的博客一个一个结构体看的

binder中结构体列表

《(原创)Linux中的Binder驱动》

《(原创)Linux中的Binder驱动》

binder_proc结构体

binder_thread结构体

binder_ref结构体

binder_ref_death结构体

binder_write_read结构体

write_buffer和read_buffer都是包含Binder协议命令的binder_transaction_data结构体。

binder_transaction_data结构体

  • target: 对于BpBinder则使用handle,对于BBinder则使用ptr,故使用union数据类型来表示;
  • code: 比如注册服务过程code为ADD_SERVICE_TRANSACTION,又比如获取服务code为CHECK_SERVICE_TRANSACTION
  • data:代表整个数据区,其中data.ptr指向的是传递给Binder驱动的数据区的起始地址,data.offsets指的是数据区中IPC数据地址的偏移量。
  • cookie: 记录着BBinder指针。
  • data_size:代表本次传输的parcel数据的大小;
  • offsets_size: 代表传递的IPC对象的大小;根据这个可以推测出传递了多少个binder对象。

对于64位IPC,一个IPC对象大小等于8;对于32位IPC,一个IPC对象大小等于4;

flat_binder_object结构体

这里的类型type的可能取值来自enum,成员如下:

《(原创)Linux中的Binder驱动》

说明:

  • 当type等于BINDER_TYPE_BINDER或BINDER_TYPE_WEAK_BINDER类型时, 代表Server进程向ServiceManager进程注册服务,则创建binder_node对象;
  • 当type等于BINDER_TYPE_HANDLE或BINDER_TYPE_WEAK_HEANDLE类型3时, 代表Client进程向Server进程请求代理,则创建binder_ref对象;
  • 当type等于BINDER_TYPE_FD类型时, 代表进程向另一个进程发送文件描述符,只打开文件,则无需创建任何对象。

binder_buffer对象

binder_transaction结构体

binder_work结构体

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注