Binder驱动创建:
static const struct file_operations binder_fops = {
.owner = THIS_MODULE,
.poll = binder_poll,
.unlocked_ioctl = binder_ioctl,
.compat_ioctl = binder_ioctl,
.mmap = binder_mmap,
.open = binder_open,
.flush = binder_flush,
.release = binder_release,
};
static struct miscdevice binder_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "binder",
.fops = &binder_fops
};
复制代码
Binder驱动初始化:
- static int __init binder_init(void)
- 注册binder设备驱动ret = misc_register(&binder_miscdev);
- 注册设备驱动的操作binder_open、binder_mmap、binder_ioctl、binder_release
Binder主要结构体:
struct binder_work {
struct list_head entry;
enum {
BINDER_WORK_TRANSACTION = 1,
BINDER_WORK_TRANSACTION_COMPLETE,
BINDER_WORK_NODE
BINDER_WORK_DEAD_BINDER,
BINDER_WORK_DEAD_BINDER_AND_CLEAR,
BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
} type;
}
struct binder_node {
int debug_id;
struct binder_work work;
struct rb_node rb_node;
struct hlist_node dead_node;
struct binder_proc *proc;
struct hlist_head refs;
int internal_strong_refs;
int local_weak_refs;
int local_strong_refs;
binder_unitptr_t ptr;
binder_unitptr_t cookie;
unsigned has_strong_ref:1;
unsigned pending_strong_ref:1;
unsigned has_weak_ref:1;
unsigned pending_weak_ref:1;
unsigned has_async_transaction:1;
unsigned accept_fds:1;
unsigned min_priority:8;
struct list_head async_todo;
}
struct binder_ref_death {
struct binder_work work;
binder_unitptr_t cookie;
}
struct binder_ref {
int debug_id;
struct rb_node rb_node_desc;
struct rb_node rb_node_node;
struct hlist_node node_entry;
struct binder_proc *proc;
struct binder_node *node;
unit32_t desc;
int strong;
int weak;
struct binder_ref_death *death;
}
struct binder_buffer {
struct list_head entry;
struct rb_node rb_node;
unsigned free:1;
unsigned allow_user_free:1;
unsigned async_transaction:1;
unsigned debug_id:29;
struct binder_transaction *transaction;
struct binder_node *target_node;
size_t data_size;
size_t offsets_size;
unit8_t data[0];
}
struct binder_proc {
struct hlist_node proc_node;
struct rb_root threads;
struct rb_root nodes;
struct rb_root refs_by_desc;
struct rb_root refs_by_node;
int pid;
struct vm_area_struct *vma;
struct mm_struct *vma_vm_mm;
struct task_struct *files;
struct hlist_node deferred_work_node;
int deferred_work;
void *buffer;
ptrdiff_t user_buffer_offset;
struct list_head buffers;
struct rb_root free_buffers;
struct rb_root allocated_buffers;
size_t free_async_space;
struct page **pages;
size_t buffer_size;
unit32_t buffer_free;
struct list_head todo;
wait_queue_head_t wait;
struct binder_stats stats;
struct list_head delivered_death;
int max_threads;
int requested_threads;
int requested_hreads_started;
int ready_threads;
long default_priority;
struct dentry *debugfs_entry;
}
struct binder_proc {
int debug_id;
struct binder_work work;
struct binder_thread *from;
struct binder_transction *from_parent;
struct binder_proc *to_proc;
struct binder_thread *to_thread;
struct binder_transation *to_parent;
unsigned need_reply:1;
struct binder_buffer *buffer;
unsigned int code;
unsighed int flags;
long priority;
long saved_priority;
kuid_t sender_euid;
}
复制代码
先看看C++层怎么用:
1.源码路径:
C++: /android/frameworks/native/cmds/servicemanager/
Java: /android/frameworks/base/core/java/android/os/
2.servicemanager的启动:
Android在init进程启动以后,通过脚本init.rc,启动ServiceManager:
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart keystore
复制代码
3.主要入口:
int main(int argc, char **argv)
{
struct binder_state *bs;
bs = binder_open(128*1024);
if (!bs) {
ALOGE("failed to open binder driver\n");
return -1;
}
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
selinux_enabled = is_selinux_enabled();
sehandle = selinux_android_service_context_handle();
selinux_status_open(true);
if (selinux_enabled > 0) {
if (sehandle == NULL) {
ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
abort();
}
if (getcon(&service_manager_context) != 0) {
ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
abort();
}
}
union selinux_callback cb;
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
cb.func_log = selinux_log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
binder_loop(bs, svcmgr_handler);
return 0;
}
复制代码
4.binder操作函数
binder_open
复制代码
- 打开设备驱动/dev/binder,文件描述符存储到bs->fd当中
- 映射128k内存到bs->mmaped
binder_loop
复制代码
- 发起 BINDER_WRITE_READ操作 命令BC_ENTER_LOOPER
- 发起 BINDER_WRITE_READ操作 一直等待有数据返回
- 开始解析返回的bind_transaction_data
binder_write
复制代码
- 发起操作 BINDER_WRITE_READ操作 (bs->fd, data, len)
binder_parse
复制代码
- 解析出命令:BR_TRANSACTION、BR_REPLY等
- 解析出数据:binder_transaction_data
5.业务函数:
find_svc()
复制代码
查找svcinfo
svcinfo_death()
复制代码
binder驱动通过handle找到bind_ref释放
do_find_service()
复制代码
查找svcinfo并返回binder句柄
do_add_service()
复制代码
调用binder_acquire向binder驱动中添加一个node、鉴定death通知
svcmgr_handler()
复制代码
接收客户端发来的消息
- 获取服务 得到根据名字得到句柄handle,并写入flat_binder_object到reply中,最后回传reply
- 添加服务 将handle加入到svclist中,binder_acquire注册handle到驱动中,监听death通知
- 列出所有服务 将所有服务命令写入到reply中
总结一下:
- server_manager在init进程解析init.rc时被启动,在入口函数main中首先打开/dev/binder驱动,将自己设为CONTEXT_MGR在内核中成为0号句柄的Binder、进入Binder消息循环读取消息(返回服务、添加服务、列出所有服务),所有的消息都记录在了svcinfo list结构体中,服务在添加时会发送命令注册到/dev/binder驱动中。
- binder驱动的使用方法即:打开设备驱动/dev/binder,ioctl监控驱动消息,处理驱动消息(也可以回发消息)。