学习 binder 我感觉得从上到下:先对 binder 架构/理论有个大概的认识、对 binder 里的数据结构有个印象,再深入代码细节
整个 binder 涉及到应用侧和驱动侧、app 侧和 framework 侧、java 层和 native 层,代码量巨大而且跨度很大,只有对整个 binder 架构有清晰的认识才不会迷失在细节里

linux 系统将设备分为3类:字符设备、块设备和网络设备:
字符设备 是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和 LED 设备等块设备 是指可以从设备的任意位置读取一定长度数据的设备。块设备包括硬盘、磁盘、U 盘和 SD 卡等每个字符设备或块设备都在 /dev 目录下对应一个设备文件,linux 用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备和块设备;驱动调用的实质,就是通过设备文件找到与之对应设备号的设备,再通过设备初始化时绑定的操作函数对硬件进行控制

字符设备、字符设备驱动与用户空间访问该设备的程序三者之间的关系如下图:

在 Linux 字符设备驱动中:
杂项设备也是在嵌入式系统中用得比较多的一种设备驱动,使用 misc_register(struct miscdevice *misc) 注册杂项设备,misc_deregister(struct miscdevice *misc) 释放杂项设备
在 Linux 内核的 include/linux 目录下有 Miscdevice.h 文件,要把自己定义的 misc device 设备定义在这里。其实是因为这些字符设备不符合预先确定的字符设备范畴,所有这些设备采用主编号 10 ,一起归于 misc device,其实 misc_register 就是用主标号 10 调用 register_chrdev() 的,也就是说 misc device 就是特殊的字符设备,可自动生成设备节点
misc device 是特殊字符设备,注册驱动程序时采用 misc_register 函数注册,此函数中会自动创建设备节点(即设备文件),无需 mknod 指令手动创建设备文件,杂项字符设备和一般字符设备的区别:
struct miscdevice{
int minor; // 杂项设备的此设备号(如果设置为 MISC_DYNAMIC_MINOR,表示系统自动分配未使用的 minor)
const char *name;
const stuct file_operations *fops; // 驱动主题函数入口指针
struct list_head list;
struct device *parent;
struct device *this device;
const char *nodename; // 在 /dev 目录下面创建的设备驱动节点
mode_t mode;
};
| 主设备号 | 次设备号 | 文件名 | 设备类型 | 说明 |
|---|---|---|---|---|
| 1 | 3 | /dev/null | char | 空设备。任何写入都将被直接丢弃(但返回“成功”);任何读取都将得到 EOF (文件结束标志) |
| 4 | 0 | /dev/tty0 | char | 当前虚拟控制台 |
| 1 | /dev/tty1 | char | 第 1 个虚拟控制台 | |
| 8 | 0 | /dev/sda | block | 第 1 个磁盘 |
| 16 | /dev/sdb | block | 第 2 个磁盘 | |
| 32 | /dev/sdc | block | 第 3 个磁盘 | |
| 10 | 1 | /dev/psaux | char | PS/2 鼠标 |
| 156 | /dev/lcd | char | 液晶(LCD)显示屏 |
Binder 以杂项设备(misc device,是特殊的字符设备)进行注册,作为虚拟字符设备没有直接操作硬件,只是对设备内存的处理,Binder 驱动的主要方法有: