- Fd是通过binder可以透传(即client进程在收到此fd之后是可以作为自己进程已经打开的fd来是使用的)的信息之一
- 在binder驱动的binder_transaction(…)方法中,有对Fd的特殊处理:
- 在分析传递给驱动层的flat_binder_object 对象 fp时:
- 如果fp->type是BINDER_TYPE_FD, 那么说明这次要传递的是一个跨进程的Fd:
- 调用file(类型是struct file * 即Linux内核规定的file数据结构) = fget(fp->handle);
- 对于struct file的解释: 文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码中,struct file的指针通常被命名为file或filp
- file = fget(fp->handle), fget(…)函数基于输入的fd来得到此fd”指向”的file数据结构体: current(当前进程的进程结构体)->files->fd[fd], 此时file里保存的就是fd对应的file结构体的指针.
- 调用security_binder_transfer_file(proc->tsk, target_proc->tsk, file)基于**检查目标进程(target_proc)是否具有访问文件file的权限。如果有的话,那么就允许源进程将它传递给目标进程访问.
- target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); 在target进程中找一个该进程还没有被使用的Fd编号.
- task_fd_install(target_proc, target_fd, file), 将得到targetFd和file指针指向的file结构体在target进程中挂接起来
- fp->handle = target_fd.
- task_fd_install(struct binder_proc *proc, unsigned int fd, struct file *file)函数将file指向的file结构体和fd关联起来,会在proc指定的进程中生效.
- binder_proc是binder驱动自己定义的结构体,是一个进程在binder驱动内的信息保存者, 每个进程只会open binder一次,binder进而将这个特殊的结构体和该进程打开binder时的fd对应的file结构体对应起来
- struct files_struct *files = proc->files:
- 对一个进程来说,其binder_proc对象被建立的时机是binder_open(…)的时候:
- struct binder_proc *proc = kzalloc(sizeof(*proc), GFP_KERNEL); 为binder_proc申请一块内存.
- proc->tsk = current; 将当前进程的task struct指针保存在binder_proc的task中.
- proc->pid = current->group_leader->pid; 保存进程Id.
- filp->private_data = proc; 将申请出来的binder_proc对象指针保存在打开/dev/binder对应的file结构的private_data中这是binder驱动能够识别不同进程的关键, binder驱动在进程打开他时给其一个特殊的binder_proc对象,进程将此对象保存在打开binder文件的file结构体中, 后面只要还使用这个file结构体和binder驱动交互, binder启动就可以根据private_data中的binder_proc对象来识别该进程(private_data的说明: 系统在调用驱动程序的open方法前将这个指针置为NULL。驱动程序可以将这个字段用于任意目的,也可以忽略这个字段。驱动程序可以用这个字段指向已分配的数据,但是一定要在内核释放file结构前的release方法中清除它。即这个字段是由驱动来根据自己的需要进行扩展的)
- 在binder_mmap时, 会将binder_proc对象的files指针赋值: proc->files = get_files_struct(proc->tsk(当前进程对应的task struct)) 得到此进程的files结构体数组的指针
- fdt = files_fdtable(files); files_fdtable: 去读取files所在进程(目的进程)的文件描述表
- rcu_assign_pointer(fdt->fd[fd], file); 将file指针和fd关联起来. 这样在target process中就可以使用这个fd操作另外一个proc中打开的file结构体了.