01.Binder系统 框架分析

Binder系统有两大核心,分别为IPC(Information Processing Center:信息处理中心,进程间的通信)与RPC(远程过程控制调用)。

数据的传输的三大要素分别为源,目的和数据

源(进程A):发送数据,A向serviceManager查询led服务,获取一个handle(对硬件操作的服务),该handle指向进程B。

目的(进程B):B向serviceManager注册LED服务,以便A进程获取

数据:点亮,或者熄灭闪烁等。

A进程调用led_open和Led_ctrl,A进程首先按照约定好的数据封装数据,然后将数据发送出去;B进程取出数据调用本地led_open/led_ctrl

RPC:RPC是在IPC的基础上做了一些封装。可以认为是直接调用某个进程的函数(A进程去调用B进程的函数)。即AB进程约定好相应的格式,如对函数进行编号

  1. 整体框架

  1. service_manager.c

service_manager.c
main()
    //1、open驱动
    bs = binder_open(128*1024);
        //打开用户态binder(前面提到过,进程间的通信都是通过binder)
        bs->fd = open("/dev/binder", O_RDWR);
        //调用驱动的mmap函数
        bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

    //2、告诉驱动他是service_manager
    binder_become_context_manager(bs)
        ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);

    //3、一个循环,读取处理数据,其中的svcmgr_handler为服务处理函数
    binder_loop(bs, svcmgr_handler);
        //读取数据
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        // 解析数据
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
            //处理数据,此处的func就是前面的传入的svcmgr_handler
            res = func(bs, txn, &msg, &reply); 

int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
    case SVC_MGR_CHECK_SERVICE:
        //根据传入的txn->code,在链表中查找服务,查找到之后返回服务
        handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
    case SVC_MGR_ADD_SERVICE:
        //如果传入的是注册服务,则加入本地链表
        do_add_service(bs, s, len, handle, txn->sender_euid,allow_isolated, txn->sender_pid)
  1. test_client.c

test_client.c
int main(int argc, char **argv)
    //1、打开binder驱动,映射内存的大小为128*1024
    bs = binder_open(128*1024);
    /*2、获取服务goodbye get service */
    handle = svcmgr_lookup(bs, svcmgr, "hello");
        binder_call(bs, &msg/*上边构造数据提供的参数*/, &reply/*返回值*/, 
                    target/*向谁发送数据*/, SVC_MGR_CHECK_SERVICE/*调用那个函数*/)
    //3、向handle发送数据
    sayhellobye();

    binder_release(bs, handle);
  1. test_server.c

test_server.c
int main(int argc, char **argv)
    //1、打开binder驱动,映射内存的大小为128*1024
    bs = binder_open(128*1024);
    /*2、注册服务 add service */
    /*注册一个"hello"服务,把hello_service_handler函数指针当做参数,
    为方便后面的调用*/
    ret = svcmgr_publish(bs, 
                         svcmgr/*接口句柄函数编号*/, 
                         "hello"/*服务名称*/, 
                         hello_service_handler/*服务处理函数*/);

    /*3、循环等待,如果有"goodbye或者"hello"服务申请,
    则test_server_handler函数被调用*/
    binder_loop(bs, test_server_handler);
        //读取数据
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        // 解析数据
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
            //处理数据,此处的func就是前面的传入的test_server_handler
            res = func(bs, txn, &msg, &reply); 
  1. 如何构造数据

int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
{
    int status;
    unsigned iodata[512/4];//用户空间传递给内核Binder驱动的数据缓存
    //struct binder_io 主要用来对上述iodata数组缓存区进行有效管理和操作;
    struct binder_io msg/* 发送数据提供的参数*/, reply/*返回值*/;

    /**********数据构造**********/
    //初始化数组的数据,预留16个字节,用于存放flat_binder_object的地址
    bio_init(&msg, iodata, sizeof(iodata), 4);
    
    //构造数据
    bio_put_uint32(&msg, 0);  // 存放四个字节0
    /*可以放入各类型参数,反之通过get方法获取
    * 写入字符串 android.os.IServiceManager
    */
    bio_put_string16_x(&msg, SVC_MGR_NAME);
    
    //写入服务的名字hello
    bio_put_string16_x(&msg, name);//"hello"/*服务名称*/
    
    //服务处理函数--传递一个biner实体传递给内核
    bio_put_obj(&msg, ptr);
    /*------------------------------*/
    
    //在构建完struct binder_io msg后,调用ioctrl向驱动程序发送数据
    if (binder_call(bs, 
                    &msg/* 提供参数*/, 
                    &reply/*返回值*/, 
                    target/*函数编号向谁发送数据*/, 
                    SVC_MGR_ADD_SERVICE/*调用那个函数*/))
        return -1;
    //获得返回值
    status = bio_get_uint32(&reply);

    binder_done(bs, &msg, &reply);

    return status;
}
  1. 总结

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值