Binder机制
- 跨进程通信IPC
- 远程过程调用手段RPC
- 4个角色进行粘合,Client、Server、Service Manager和Binder驱动程序
- 整个过程只需要一次拷贝
Binder Driver misc设备
/dev/binder
//没有read,write, ioctl实现
static struct file_operations binder_fops = {
.owner = THIS_MODULE,
.poll = binder_poll,
.unlocked_ioctl = binder_ioctl,
.mmap = binder_mmap,
.open = binder_open,
.flush = binder_flush,
.release = binder_release,
};
static struct miscdevice binder_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "binder",
.fops = &binder_fops
};
static int __init binder_init(void)
{
int ret;
binder_proc_dir_entry_root = proc_mkdir("binder", NULL);
if (binder_proc_dir_entry_root)
binder_proc_dir_entry_proc = proc_mkdir("proc", binder_proc_dir_entry_root);
ret = misc_register(&binder_miscdev);
if (binder_proc_dir_entry_root) {
create_proc_read_entry("state", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_state, NULL);
create_proc_read_entry("stats", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_stats, NULL);
create_proc_read_entry("transactions", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_transactions, NULL);
create_proc_read_entry("transaction_log", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_transaction_log, &binder_transaction_log);
create_proc_read_entry("failed_transaction_log", S_IRUGO, binder_proc_dir_entry_root, binder_read_proc_transaction_log, &binder_transaction_log_failed);
}
return ret;
}
device_initcall(binder_init);
binder_open
创建一个struct binder_proc数据结构来保存打开设备文件/dev/binder的进程的上下文信息
并且将这个进程上下文信息保存在打开文件结构struct file的私有数据成员变量private_data中
static int binder_open(struct inode *nodp, struct file *filp)
{
struct binder_proc *proc; //proc
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
printk(KERN_INFO "binder_open: %d:%d\n", current->group_leader->pid, current->pid);
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
if (proc == NULL)
return -ENOMEM;
get_task_struct(current);
INIT_LIST_HEAD(&proc->todo);
init_waitqueue_head(&proc->wait);
proc->default_priority = task_nice(current);
mutex_lock(&binder_lock);
binder_stats.obj_created[BINDER_STAT_PROC]++;
hlist_add_head(&proc->proc_node, &binder_procs);
proc->pid = current->group_leader->pid;
INIT_LIST_HEAD(&proc->delivered_death);
filp->private_data = proc; //private_data
mutex_unlock(&binder_lock);
...
}
binder_mmap
对打开的设备文件进行内存映射操作mmap
重点:同一物理地址,当内核地址为kernel_addr,则进程地址为proc_addr = kernel_addr + user_buffer_offset
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
sta