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