Binder驱动研究

本文从Binder驱动的注册开始,逐步分析驱动的初始化、打开操作`binder_open`及`binder_ioctl`中的数据处理流程。重点探讨了在读取操作`binder_thread_read`中的等待与唤醒机制,以及写操作如何将数据放入待处理队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         好久没写过博客了,也没怎么研究过源码,偶尔看到别人的博客都是系列研究,自愧不如啊,所以也下下来android源码开始看了,参考网上的讲解,结合源码。希望这样记录下自己的阅读历程,也不枉虚度时光了。

         先从android的Binder驱动说起吧,以前也不懂Linux驱动,有说错的地方敬请谅解,欢迎指正。

一、驱动注册就不详细说了binder_init

1、初始化工作队列binder_deferred_workqueue = create_singlethread_workqueue("binder");

2、注册设备misc_register(&binder_device->miscdev);

3、注册到内核的函数

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,
};

自己的一些理解:binder_deferred_workqueue用于延时任务,以后再详细说,其它的都好理解,虽然机制不了解,但是不影响后续分析,不再深入研究。

二、然后就是打开binder的操作binder_open

1、分配binder_proc结构体,设置相关属性,记录当前进程的binder相关的信息

2、其它一些统计信息binder_stats_created(BINDER_STAT_PROC);记录open的个数。

自己的一些理解:binder_dev = container_of(filp->private_data, struct binder_device,miscdev);这句一开始没有理解,没看到给filp->private_data赋值,怎么就得到了binder_dev呢,原来在misc.c中misc_open中file->private_data = c;进行了赋值然后调用file->f_op->open(inode,file);的,因此file->private_data通misc_register(&binder_device->miscdev);指向&binder_device->miscdev,而container_of通过结构体成员的地址获取结构体的地址因此获取的是misc_register时传入的&binder_device。

三、binder_ioctl,这个函数比较复杂,主要实现也是在这里,先简单说下自己迷惑的地方。

1、总的流程,binder_ioctl处理数据分两种一种类似BINDER_SET_MAX_THREADS等,直接操作数据结构,直接返回这种比较简单,还有一种需要传递到相应的进程或线程处理。

2、先看读取操作最终在binder_thread_read中处理

调用 binder_wait_for_work等待

    for (;;) {
        prepare_to_wait(&thread->wait, &wait, TASK_INTERRUPTIBLE);
        if (binder_has_work_ilocked(thread, do_proc_work))
            break;
        if (do_proc_work)
            list_add(&thread->waiting_thread_node,
                 &proc->waiting_threads);
        binder_inner_proc_unlock(proc);
        schedule();
        binder_inner_proc_lock(proc);
        list_del_init(&thread->waiting_thread_node);
        if (signal_pending(current)) {
            ret = -ERESTARTSYS;
            break;
        }
    }
    finish_wait(&thread->wait, &wait);

等待thread->wait,和线程相关,等待唤醒,binder_has_work_ilocked判断等待条件  => return !binder_worklist_empty_ilocked(&thread->todo) ||
        thread->looper_need_return ||
        (do_proc_work &&
         !binder_worklist_empty_ilocked(&thread->proc->todo));  todo队列不为空或者looper_need_return需要返回,或者do_proc_work。

然后就是进行数据处理了,以后再详细分析,主要根据transaction_stack查找相对应的线程。

3、写操作对于进程间操作也是写入相应的todo队列,后面再进行详细的分析。

就先大概写一下吧,整体还是比较复杂的,说的比较简略,以后再接着写。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值