• 9.3 Binder系统_驱动情景分析_服务获取过程


    4. 服务获取过程

    test_client客户端:

    (1)在用户态先构造name=“hello”的数据(服务的名字是hello),调用ioctl发送数据给service_manager(handle=0)

    (2)进入内核态后根据handle=0找到service_manger,把数据放入它的todo链表,唤醒service_manager进程,自己休眠

    (5)在内核态被唤醒后返回handle=1给用户态,在用户态中得到handle=1,然后就可以根据handle来给服务发送数据了(传数据给服务的时候根据handle在test_client的binder_proc结构体中根据refs_by_desc找到binder_ref,在找到服务binder_node,在找到服务进程,驱动程序把数据放到服务进程的todo链表,这样test_server就可以处理数据了)

    service_manager端:

    (3)其在内核态被唤醒后返回数据到他的用户态,取出数据,得到“hello”后在svclist链表里根据hello找到一项,得知其hello服务的handle=1,用ioctl把这个handle发给驱动,在service_manager的内核态中,从它的的binder_pro结构体中根据handle,从refs_by_desc树中找到binder_ref,然后找到hello服务的binder_node,然后根据proc找到服务进程

    (4)接着在内核态为test_client创建binder_ref,其desc=1,表示在test_client进程中hello服务对应的handle=1,,binder_ref的node是指向test_server提供的hello服务节点,同时表示test_client的binder_proc结构体的refs_by_desc树被加入这个刚创建的binder_ref,内核态把组织的数据(handle=1)放入test_client的todo链表,接着唤醒test_client

    ./test_client hello

    open("/dev/binder")

    ioctl

    构造数据,并调用binder_call发送BC_TRANSACTION类型数据,数据的组织格式:四字节全零+len(android.os.IServiceManager)(长度用四字节表示)+android.os.IServiceManager(每个字符用两字节表示)+len("hello")(长度用四字节表示)+hello(每个字符用两字节表示),接着去读,先读到一个BR_NOOP类型数据,然后在内核态休眠
    [21334.646270] test_client (1379, 1379), binder_thread_write : BC_TRANSACTION
    [21334.646361] binder: 1379:1379 BC_TRANSACTION 6 -> 1369 - node 1, data beccaa6c-beccaa5c size 80-0
    [21334.646465] test_client (1379, 1379), binder_transaction , print data :
    [21334.646540] 0000: 00 . 00 . 00 . 00 . 1a . 00 . 00 . 00 . 61 a 00 . 6e n 00 . 64 d 00 . 72 r 00 .
    [21334.655133] 0016: 6f o 00 . 69 i 00 . 64 d 00 . 2e . 00 . 6f o 00 . 73 s 00 . 2e . 00 . 49 I 00 .
    [21334.663985] 0032: 53 S 00 . 65 e 00 . 72 r 00 . 76 v 00 . 69 i 00 . 63 c 00 . 65 e 00 . 4d M 00 .
    [21334.672839] 0048: 61 a 00 . 6e n 00 . 61 a 00 . 67 g 00 . 65 e 00 . 72 r 00 . 00 . 00 . 00 . 00 .
    [21334.681692] 0064: 05 . 00 . 00 . 00 . 68 h 00 . 65 e 00 . 6c l 00 . 6c l 00 . 6f o 00 . 00 . 00 .
    [21334.690570] test_client (1379, 1379), binder_thread_read : BR_NOOP

    open

    ioctl

    mmap

    service_manager被唤醒后读到BR_TRANSACTION类型数据,数据值与发送的一样

    [21334.696735] service_manager (1369, 1369), binder_thread_read : BR_TRANSACTION
    [21334.703848] service_manager (1369, 1369), binder_thread_read , print data :
    [21334.710791] 0000: 00 . 00 . 00 . 00 . 1a . 00 . 00 . 00 . 61 a 00 . 6e n 00 . 64 d 00 . 72 r 00 .
    [21334.719627] 0016: 6f o 00 . 69 i 00 . 64 d 00 . 2e . 00 . 6f o 00 . 73 s 00 . 2e . 00 . 49 I 00 .
    [21334.728477] 0032: 53 S 00 . 65 e 00 . 72 r 00 . 76 v 00 . 69 i 00 . 63 c 00 . 65 e 00 . 4d M 00 .
    [21334.737335] 0048: 61 a 00 . 6e n 00 . 61 a 00 . 67 g 00 . 65 e 00 . 72 r 00 . 00 . 00 . 00 . 00 .
    [21334.746188] 0064: 05 . 00 . 00 . 00 . 68 h 00 . 65 e 00 . 6c l 00 . 6c l 00 . 6f o 00 . 00 . 00 .
    [21334.755072] test_client (1379, 1379), binder_thread_read : BR_TRANSACTION_COMPLETE

    [21334.762623] service_manager (1369, 1369), binder_thread_write : BC_FREE_BUFFER

    service_manager根据hello名字找到handle之后构造一个flat_binder_object类型的数据给test_client,flat_binder_object结构体的type是BINDER_TYPE_HANDLE表示引用,handle是handle=1,这个结构体数据通过ioctl发给驱动程序,驱动程序最后会调用binder_transaction来处理BC_REPLY数据,找到其要回复给那个进程,并把数据从service_manager用户态把数据复制进内核态,发到target_proc(test_client进程)的空间中去,先处理flat_binder_object数据,根据数据中handle在当前进程service_manager中找到binder_ref,接着给test_client创建一个binder_ref节点,其中的node指向hello服务,然后修改flat_binder_object数据的handle值为新建的这个binder_ref.desc,接着把数据放入test_client进程的todo链表,唤醒test_client
    [21334.769822] service_manager (1369, 1369), binder_thread_write : BC_REPLY
    [21334.776508] binder: 1369:1369 BC_REPLY 7 -> 1379:1379, data bee71a5c-bee71a4c size 16-4
    [21334.784503] service_manager (1369, 1369), binder_transaction , print data :
    [21334.791426] 0000: 85 . 2a * 68 h 73 s 7f . 01 . 00 . 00 . 01 . 00 . 00 . 00 . 00 . 00 . 00 . 00 .
    [21334.800285] test_client (1379, 1379), binder_thread_read : BR_NOOP
    [21334.806455] service_manager (1369, 1369), binder_thread_read : BR_NOOP


    [21334.812986] test_client (1379, 1379), binder_thread_read : BR_REPLY
    [21334.819195] test_client (1379, 1379), binder_thread_read , print data :
    [21334.825795] 0000: 85 . 2a * 68 h 73 s 7f . 01 . 00 . 00 . 01 . 00 . 00 . 00 . 00 . 00 . 00 . 00 .
    [21334.834653] service_manager (1369, 1369), binder_thread_read : BR_TRANSACTION_COMPLETE
    [21334.842584] test_client (1379, 1379), binder_thread_write : BC_ACQUIRE
    [21334.849076] service_manager (1369, 1369), binder_thread_read : BR_NOOP
    [21334.855583] test_client (1379, 1379), binder_thread_write : BC_FREE_BUFFER
    [21334.862530] test_client (1379, 1379), binder_thread_write : BC_RELEASE

     


    x

  • 相关阅读:
    公有云数据库服务的申请与使用
    linux集群
    shell基础知识
    LNMP环境配置
    LAMP环境搭建与配置
    12月17日linux学习
    12月16日linux学习(文档的压缩与打包)
    12月13、14号linux学习
    12月12日linux学习
    目录结构
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9148904.html
Copyright © 2020-2023  润新知