注意:binder的初始化总体调用链:
device_initcall(binder_init);
static int __init binder_init(void)
static int __init init_binder_device(const char *name)
(代码位置:kernel/drivers/android/binder.c)
1、device_initcall
device_initcall(binder_init);
2、binder_init
static int __init binder_init(void)
{
int ret;
char *device_name, *device_tmp;
struct binder_device *device;
struct hlist_node *tmp;
char *device_names = NULL;
ret = binder_alloc_shrinker_init();//注册内存伸缩器
if (ret)
return ret;
//设置一些调试文件和信息,帮助开发人员debug
atomic_set(&binder_transaction_log.cur, ~0U);
atomic_set(&binder_transaction_log_failed.cur, ~0U);
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
if (binder_debugfs_dir_entry_root)
binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
binder_debugfs_dir_entry_root);
······
if (strcmp(binder_devices_param, "") != 0) {
device_names = kstrdup(binder_devices_param, GFP_KERNEL);
......
//读出来其实就是[binder,hwbinder,vndbinder]了
device_tmp = device_names;
while ((device_name = strsep(&device_tmp, ","))) {
// 初始化binder设备列表
ret = init_binder_device(device_name);
......
}
}
......
return ret;
3、初始化各binder设备(binder,hwbinder,vndbinder)
init_binder_device(device_name){
int ret;
struct binder_device *binder_device;
//### 1.给binder_device分配内存
binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL);
if (!binder_device)
return -ENOMEM;
//### 2.设置结构体数据,其中包含设备操作集的三项
binder_device->miscdev.fops = &binder_fops;
binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
binder_device->miscdev.name = name;
binder_device->context.binder_context_mgr_uid = INVALID_UID;
binder_device->context.name = name;
mutex_init(&binder_device->context.context_mgr_node_lock);
//### 3.注册设备miscdev
ret = misc_register(&binder_device->miscdev);
if (ret < 0) {
kfree(binder_device);
return ret;
}
//### 4.添加到hlist头节点
hlist_add_head(&binder_device->hlist, &binder_devices);
}
4、相关结构体:
struct binder_device {
struct hlist_node hlist; //一种列表,经常作为其他结构体(如套接字、文件描述符等)的成员,提高了系统的性能和效率
struct miscdevice miscdev; ///linux标准设备之一,也就是说binder实际上是一种miscdevice
struct binder_context context;
struct inode *binderfs_inode;
};
struct miscdevice {
const struct file_operations *fops; //设备操作方法集合 --->下面的binder_fops
int minor; //次设备号,主设备号已经敲定是10了,后面我们跟进代码看一下。
const char *name; //驱动名字,最终会反映在设备节点名字上。
struct list_head list; //链接到所有杂项设备链表当中。
struct device *parent; //父设备,这个一般为NULL
struct device *this_device;//当前设备的devices结构。
const char *nodename;
umode_t mode;
};
const struct file_operations binder_fops = { //与用户控件操作binder有关的三个成员
.unlocked_ioctl = binder_ioctl,
.mmap = binder_mmap,
.open = binder_open
};
5、总体流程图
-
-
-