進程在使用Binder進程間通訊機制以前,首先要調用函數open打開設備文件/dev/binder來獲取一個文件描述符,而後經過這個文件描述符和binder驅動程序交互,驅動程序會和其餘進程交互,最終實現進程間通訊。驅動程序至關於郵局,而/dev/binder至關於郵箱。node
在上一篇咱們知道,在建立/dev/binder的時候咱們已經註冊了open方法對應的函數 binder_openlinux
static int binder_open(struct inode *nodp, struct file *filp) { //建立了一個binder_proc用來表示 使用binder的進程 struct binder_proc *proc; binder_debug(BINDER_DEBUG_OPEN_CLOSE, "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); //初始化當前進程的結構體(linux定義,包含進程今夕) proc->tsk = current; //初始化 待執行任務 鏈表 INIT_LIST_HEAD(&proc->todo); //初始化等待隊列 init_waitqueue_head(&proc->wait); //初始化進程優先級 proc->default_priority = task_nice(current); binder_lock(__func__); //設置binder_stat狀態爲 BINDER_STAT_PROC binder_stats_created(BINDER_STAT_PROC); //將當前binder_proc存入 binder_procs鏈表頭部,而且將該節點賦值給binder_proc 中的 proc_node字段 hlist_add_head(&proc->proc_node, &binder_procs); //設置進程組id proc->pid = current->group_leader->pid; //初始化死亡通知隊列 INIT_LIST_HEAD(&proc->delivered_death); filp->private_data = proc; binder_unlock(__func__); // if (binder_debugfs_dir_entry_proc) { char strbuf[11]; snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO, binder_debugfs_dir_entry_proc, proc, &binder_proc_fops); } return 0; }
首先建立了一個binder_proc結構體而且初始化(過程見註釋),初始化完成以後將binder_proc結構體proc保存在參數filp的成員變量private_data中。參數filp指向一個打開文件結構體,當進程調用函數open打開設備文件/dev/binder以後,內核就會返回一個文件描述符給進程,而這個文件描述符與參數filp所指向的打開文件結構體是關聯在一塊兒的。所以,當進程後面以這個文件描述符爲參數調用函數mmap或者ioctl來與Binder驅動程序交互時,內核就會將與該文件描述符相關聯的打開文件結構體傳遞給Binder驅動程序,這時候Binder驅動程序就能夠經過它的成員變量private_data來得到前面在函數binder_open中爲進程建立的binder_proc結構體proc。函數
最後,在目標設備上的/proc/binder/proc目錄下建立一個以進程ID爲名稱的只讀文件,經過讀取文件/proc/binder/proc/的內容,咱們就能夠得到進程的Binder線程池、Binder實體對象、Binder引用對象,以及內核緩衝區等信息。該文件的操做方法表示 binder_proc_fops,可是實在不知道這個東西是什麼…………源碼中沒找到定義,求指導!spa