Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save chuanwang66/67de920d871e54ae9906 to your computer and use it in GitHub Desktop.
Save chuanwang66/67de920d871e54ae9906 to your computer and use it in GitHub Desktop.
drivers/staging/android/binder.c细节剖析
参见博客《深入分析Android Binder驱动》 http://blog.csdn.net/yangwen123/article/details/9316987
参见系列博客《binder驱动-交互时的传输实现》 http://www.360doc.com/content/12/0103/15/7891085_176883095.shtml
binder驱动不像其他Linux驱动那样有特定的硬件设备与之对应,唯一和硬件沾点边的是它需要对内存操作,不过只是使用内存存储数据罢了。
和其他驱动一样,binder驱动采用了标准的Linux驱动架构,所以才将其纳入驱动之列。
binder_init()
{
//debugfs_create_dir()
//debugfs_create_file
//本函数做什么:
// 1. 新建工作队列binder_deferred_workqueue和工作者内核线程binder来处理可以稍后执行的一些工作
// 2. 为binder驱动注册一个misc设备,设备节点/dev/binder
// 3. 创建一下目录和文件
// /proc/binder
// /proc/binder/proc
// /proc/state
// /proc/stats
// /proc/transactions
// /proc/transaction_log
// /proc/failed_transaction_log
// 这些接口文件对应的proc读取函数分别为:
// binder_read_proc_state(), binder_read_proc_stats(), binder_read_proc_transactions(), binder_read_proc_transaction_log(), binder_read_proc_transaction_log()
}
静态编译驱动模块device_initcall(binder_init); vs. 动态编译的驱动模块module_init(binder_init)
static int binder_open(struct inode *nodp, struct file *filp)
{
//binder_proc结构体:
// 一个进程打开binder设备节点,就会有一个binder_proc生成来记录这个进程的一些信息。
// 用于保存调用Binder的各个进程或线程的信息,比如进程ID, 线程ID, Binder状态信息等。
//下面仅列举出binder_open()函数初始化的binder_proc的域
//struct binder_proc *proc {
// struct hlist_node proc_node; //链入全局(双向)链表binder_procs的节点
// int pid;
// struct task_struct *tsk;
// struct list_head todo; //进程的全局任务队列
// wait_queue_head_t wait; //进程空闲进程等待任务的等待队列
// struct list_head delivered_death; //和binder死亡通知相关
// long default_priority; //记录当前task的默认nice值
// ...
//};
struct binder_proc *proc;
//kzalloc
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
//struct task_struct {...}: 进程描述符
//current就是当前进程的task_struct
get_task_struct(current); //增加当前进程引用计数
proc->tsk = current; //记录当前task_struct的地址
... //设置proc的各个域
binder_lock(__func__);
binder_stats_created(BINDER_STAT_PROC); //在全局统计计数数据结构binder_stats中记录下创建一个binder_proc
hlist_add_head(&proc->proc_node, &binder_procs); //将代表当前进程的binder_proc结构体加入全局链表binder_procs中
proc->pid = current->group_leader->pid; //如果当前task是进程,那么取得当前进程的pid;
//如果当前task是线程,那么取得创建该线程的进程的pid
...
filp->private_data = proc; //binder_proc保存在struct file的private_data域中
binder_unlock(__func__);
//以proc->pid为名字在/binder/proc/下创建一个入口文件,以便上层查看该进程的所有binder通信
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;
}
static unsigned int binder_poll(struct file *filp, struct poll_table_struct *wait)
{
//Linux poll() & poll_wait() ==> poll & select : http://www.makelinux.net/ldd3/
}
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
//struct file
//copy_from_user
//copy_to_user
//binder_thread_write
//binder_thread_read
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment