android开发分享Binder(2)

1.binder_initdevice_initcall(binder_init); static int __init binder_init(void){int ret;char *device_name, *device_names, *device_tmp;struct binder_device *device;struct hlist_node *tmp;ret = binder_alloc_shrinker_init();if (ret)return re

1.binder_init

device_initcall(binder_init);

 static int __init binder_init(void) { 	int ret; 	char *device_name, *device_names, *device_tmp; 	struct binder_device *device; 	struct hlist_node *tmp;  	ret = binder_alloc_shrinker_init(); 	if (ret) 		return ret;  	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 (binder_debugfs_dir_entry_root) { 		debugfs_create_file("state", 				    0444, 				    binder_debugfs_dir_entry_root, 				    NULL, 				    &binder_state_fops); 		debugfs_create_file("stats", 				    0444, 				    binder_debugfs_dir_entry_root, 				    NULL, 				    &binder_stats_fops); 		debugfs_create_file("transactions", 				    0444, 				    binder_debugfs_dir_entry_root, 				    NULL, 				    &binder_transactions_fops); 		debugfs_create_file("transaction_log", 				    0444, 				    binder_debugfs_dir_entry_root, 				    &binder_transaction_log, 				    &binder_transaction_log_fops); 		debugfs_create_file("failed_transaction_log", 				    0444, 				    binder_debugfs_dir_entry_root, 				    &binder_transaction_log_failed, 				    &binder_transaction_log_fops); 	}  	/* 	 * Copy the module_parameter string, because we don't want to 	 * tokenize it in-place. 	 */ 	device_names = kzalloc(strlen(binder_devices_param) + 1, GFP_KERNEL); 	if (!device_names) { 		ret = -ENOMEM; 		goto err_alloc_device_names_failed; 	} 	strcpy(device_names, binder_devices_param);  	device_tmp = device_names; 	while ((device_name = strsep(&device_tmp, ","))) { 		ret = init_binder_device(device_name); 		if (ret) 			goto err_init_binder_device_failed; 	}  #ifdef CONFIG_MILLET 	register_millet_hook(BINDER_TYPE, NULL, 			binder_sendmsg, binder_init_millet); 	register_millet_hook(BINDER_ST_TYPE, binder_recv_hook, 			binder_st_sendmsg, binder_st_init_millet); #endif 	return ret;  err_init_binder_device_failed: 	hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) { 		misc_deregister(&device->miscdev); 		hlist_del(&device->hlist); 		kfree(device); 	}  	kfree(device_names);  err_alloc_device_names_failed: 	debugfs_remove_recursive(binder_debugfs_dir_entry_root);  	return ret; } 

binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES=“binder,hwbinder,vndbinder” 创建3个设备

	ret = init_binder_device(device_name); 
static int __init init_binder_device(const char *name) { 	int ret; 	struct binder_device *binder_device;  	binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL); 	if (!binder_device) 		return -ENOMEM;  	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);  	ret = misc_register(&binder_device->miscdev); 	if (ret < 0) { 		kfree(binder_device); 		return ret; 	}  	hlist_add_head(&binder_device->hlist, &binder_devices);  	return ret; } 

binder_device创建,然后注册misc设备
ret = misc_register(&binder_device->miscdev);
hlist_add_head(&binder_device->hlist, &binder_devices);

关注一下其中的结构体:

struct binder_device { 	struct hlist_node hlist; 	struct miscdevice miscdev; 	struct binder_context context; };   struct miscdevice  { 	int minor;  //次设备号 	const char *name; 	const struct file_operations *fops; 	struct list_head list; 	struct device *parent; 	struct device *this_device; 	const struct attribute_group **groups; 	const char *nodename; 	umode_t mode; }; 

2.binder_open()

open(“/dev/hwbinder”, O_RDWR | O_CLOEXEC);
通过name来找到设备,调用binder_open

servicemanager
processstate创建时,调用,
mDriverFD(open_driver()),然后调用binder_open

进程调用binder方式:

struct binder_state *binder_open(const char* driver, size_t mapsize) {     struct binder_state *bs;     struct binder_version vers;      bs = malloc(sizeof(*bs));     if (!bs) {         errno = ENOMEM;         return NULL;     }      bs->fd = open(driver, O_RDWR | O_CLOEXEC);  //打开/dev/binder调用binder_open     if (bs->fd < 0) {         fprintf(stderr,"binder: cannot open %s (%s)n",                 driver, strerror(errno));         goto fail_open;     }      if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||   //获得版本信息         (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {         fprintf(stderr,                 "binder: kernel driver version (%d) differs from user space version (%d)n",                 vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);         goto fail_open;     }      bs->mapsize = mapsize;     bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);//申请128K内存空间,为servicemanager使用,binder服务进程映射的为1M-8K内存。     if (bs->mapped == MAP_FAILED) {         fprintf(stderr,"binder: cannot map device (%s)n",                 strerror(errno));         goto fail_map;     }      return bs;  fail_map:     close(bs->fd); fail_open:     free(bs);     return NULL; } 

binder_open

static int binder_open(struct inode *nodp, struct file *filp) { 	struct binder_proc *proc; 	struct binder_device *binder_dev;  	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%dn", __func__, 		     current->group_leader->pid, current->pid);  	proc = kzalloc(sizeof(*proc), GFP_KERNEL); 	if (proc == NULL) 		return -ENOMEM; 	spin_lock_init(&proc->inner_lock); 	spin_lock_init(&proc->outer_lock); 	get_task_struct(current->group_leader); 	proc->tsk = current->group_leader; 	mutex_init(&proc->files_lock); 	INIT_LIST_HEAD(&proc->todo); 	if (binder_supported_policy(current->policy)) { 		proc->default_priority.sched_policy = current->policy; 		proc->default_priority.prio = current->normal_prio; 	} else { 		proc->default_priority.sched_policy = SCHED_NORMAL; 		proc->default_priority.prio = NICE_TO_PRIO(0); 	}  	 	 = container_of(filp->private_data, struct binder_device, 				  miscdev); 	proc->context = &binder_dev->context; 	binder_alloc_init(&proc->alloc);  	binder_stats_created(BINDER_STAT_PROC); 	proc->pid = current->group_leader->pid; 	INIT_LIST_HEAD(&proc->delivered_death); 	INIT_LIST_HEAD(&proc->waiting_threads); 	filp->private_data = proc;  	mutex_lock(&binder_procs_lock); 	hlist_add_head(&proc->proc_node, &binder_procs); 	mutex_unlock(&binder_procs_lock);  	if (binder_debugfs_dir_entry_proc) { 		char strbuf[11];  		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); 		/* 		 * proc debug entries are shared between contexts, so 		 * this will fail if the process tries to open the driver 		 * again with a different context. The priting code will 		 * anyway print all contexts that a given PID has, so this 		 * is not a problem. 		 */ 		proc->debugfs_entry = debugfs_create_file(strbuf, 0444, 			binder_debugfs_dir_entry_proc, 			(void *)(unsigned long)proc->pid, 			&binder_proc_fops); 	}  	return 0; } 

创建binder_proc,放在filp->private_data = proc;插入链表
hlist_add_head(&proc->proc_node, &binder_procs);

其中,binder_proc 结构体:

struct binder_proc { 	struct hlist_node proc_node;  // 	struct rb_root threads;   //红黑树,线程状态 	struct rb_root nodes;   //记录binder实体 	struct rb_root refs_by_desc; //红黑树,用于快速查找,以handle为key 	struct rb_root refs_by_node; //红黑树,用于快速查找,以ptr为key 	struct list_head waiting_threads; 	int pid; 	struct task_struct *tsk; 	struct files_struct *files; 	struct mutex files_lock; 	struct hlist_node deferred_work_node; 	int deferred_work; 	bool is_dead;  	struct list_head todo; 	struct binder_stats stats; 	struct list_head delivered_death; 	int max_threads; 	int requested_threads; 	int requested_threads_started; 	int tmp_ref; 	struct binder_priority default_priority; 	struct dentry *debugfs_entry; 	struct binder_alloc alloc; 	struct binder_context *context; 	spinlock_t inner_lock; 	spinlock_t outer_lock; }; 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/893879.html

(0)
上一篇 2021年10月21日
下一篇 2021年10月21日

精彩推荐