欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    Binder深入讲解底层 内核实现.docx

    • 资源ID:23600774       资源大小:215.16KB        全文页数:50页
    • 资源格式: DOCX        下载积分:10金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Binder深入讲解底层 内核实现.docx

    1、Binder深入讲解 底层 内核实现第一节 Android Binder星期四, 06/17/2010 - 00:03 williamAndroid Binder是一种在Android里广泛使用的一种远程过程调用接口。从结构上来说Android Binder系统是一种服务器/客户机模式,包括Binder Server、Binder Client和Android Binder驱动,实际的数据传输就是通过Android Binder驱动来完成的,这里我们就来详细的介绍Android Binder驱动程序。通常来说,Binder是Android系统中的内部进程通讯(IPC)之一。在Android系统

    2、中共有三种IPC机制,分别是: 标准Linux Kernel IPC接口 标准D-BUS接口 Binder接口尽管Google宣称Binder具有更加简洁、快速,消耗更小内存资源的优点,但并没有证据表明D-BUS就很差。实际上D-BUS可能会更合适些,或许只是当时Google并没有注意到它吧,或者Google不想使用GPL协议的D-BUS库。我们不去探究具体的原因了,你只要清楚Android系统中支持了多个IPC接口,而且大部分程序使用的是我们并不熟悉的Binder接口。Binder是OpenBinder的Google精简实现,它包括一个Binder驱动程序、一个Binder服务器及Binde

    3、r客户端(?)。这里我们只要介绍内核中的Binder驱动的实现。对于Android Binder,它也可以称为是Android系统的一种RPC(远程过程调用)机制,因为Binder实现的功能就是在本地“执行”其他服务进程的功能的函数调用。不管是IPC也好,还是RPC也好,我们所要知道的就是Android Binder的功能是如何实现的。Openbinder介绍2.1.1 Android Binder协议Android 的Binder机制是基于OpenBinder (Android Binder的协议定义在binder.h头文件中,Android的通讯就是基于这样的一个协议的。 Binder T

    4、ype(描述binder type的功能)Android定义了五个(三大类)Binder类型,如下:enum BINDER_TYPE_BINDER = B_PACK_CHARS(s, b, *, B_TYPE_LARGE), BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS(w, b, *, B_TYPE_LARGE), BINDER_TYPE_HANDLE = B_PACK_CHARS(s, h, *, B_TYPE_LARGE), BINDER_TYPE_WEAK_HANDLE= B_PACK_CHARS(w, h, *, B_TYPE_LARGE), BIND

    5、ER_TYPE_FD = B_PACK_CHARS(f, d, *, B_TYPE_LARGE),; Binder Object进程间传输的数据被称为Binder对象(Binder Object),它是一个flat_binder_object,定义如下:struct flat_binder_object /* 8 bytes for large_flat_header. */ unsigned long type; unsigned long flags; /* 8 bytes of data. */ union void *binder; /* local object */ signed

    6、long handle; /* remote object */ ; /* extra data associated with local object */ void *cookie; 其中,类型字段描述了Binder 对象的类型,flags描述了传输方式,比如同步、异步等。enum transaction_flags TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ TF_ROOT_OBJECT = 0x04, /* contents are the components root object */ TF

    7、_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */;传输的数据是一个复用数据联合体,对于BINDER类型,数据就是一个binder本地对象,如果是HANDLE类型,这数据就是一个远程的handle对象。该如何理解本地binder对象和远程handle对象呢?其实它们都指向同一个对象,不过是从不同的角度来说。举例来说,假如A有个对象X,对于A来说,X就是一个本地的binder对象;如果B想访问A的X对

    8、象,这对于B来说,X就是一个handle。因此,从根本上来说handle和binder都指向X。本地对象还可以带有额外的数据,保存在cookie中。Binder对象的传递是通过binder_transaction_data来实现的,即Binder对象实际是封装在binder_transaction_data结构体中。 binder_transaction_data这个数据结构才是真正要传输的数据。它的定义如下:struct binder_transaction_data /* The first two are only used for bcTRANSACTION and brTRANSAC

    9、TION, * identifying the target and contents of the transaction. */ union size_t handle; /* target descriptor of command transaction */ void *ptr; /* target descriptor of return transaction */ target; void *cookie; /* target object cookie */ unsigned int code; /* transaction command */ /* General inf

    10、ormation about the transaction. */ unsigned int flags; pid_t sender_pid; uid_t sender_euid; size_t data_size; /* number of bytes of data */ size_t offsets_size; /* number of bytes of offsets */ /* If this transaction is inline, the data immediately * follows here; otherwise, it ends with a pointer t

    11、o * the data buffer. */ union struct /* transaction data */ const void *buffer; /* offsets from buffer to flat_binder_object structs */ const void *offsets; ptr; uint8_t buf8; data;结构体中的数据成员target是一个复合联合体对象,请参考前面的关于binder本地对象及handle远程对象的描述。code是一个命令,描述了请求Binder对象执行的操作。 对象的索引和映射Binder中的一个重要概念就是对象的映射和

    12、索引。就是要把对象从一个进程映射到另一个进程中,以实现线程迁移的概念。前面描述过Binder的一个重要概念是进程/线程迁移,即当一个进程需要同另一个进程通信时,它可以“迁移”远程的进程/线程到本地来执行。对于调用进程来说,看起来就像是在本地执行一样。这是Binder与其他IPC机制的不同点或者说是优点。当然迁移的工作是由Binder驱动来完成的,而实现的基础和核心就是对象的映射和索引。Binder中有两种索引,一是本地进程地址空间的一个地址,另一个是一个抽象的32位句柄(HANDLE),它们之间是互斥的:所有的进程本地对象的索引都是本地进程的一个地址(address, ptr, binder)

    13、,所有的远程进程的对象的索引都是一个句柄(handle)。对于发送者进程来说,索引就是一个远端对象的一个句柄,当Binder对象数据被发送到远端接收进程时,远端接受进程则会认为索引是一个本地对象地址,因此从第三方的角度来说,尽管名称不同,对于一次Binder调用,两种索引指的是同一个对象,Binder驱动则负责两种索引的映射,这样才能把数据发送给正确的进程。对于Android的Binder来说,对象的索引和映射是通过binder_node和binder_ref两个核心数据结构来完成的,对于Binder本地对象,对象的Binder地址保存在binder_node-ptr里,对于远程对象,索引就保

    14、存在binder_ref-desc里,每一个binder_node都有一个binder_ref对象与之相联系,他们就是是通过ptr和desc来做映射的,如下图:flat_binder_object就是进程间传递的Binder对象,每一个flat_binder_object对象内核都有一个唯一的binder_node对象,这个对象挂接在binder_proc的一颗二叉树上。对于一个binder_node对象,内核也会有一个唯一的binder_ref对象,可以这么理解,binder_ref的desc唯一的映射到binder_node的ptr和cookie上,同时也唯一的映射到了flat_binde

    15、r_object的handler上。而binder_ref又按照node和desc两种方式映射到binder_proc对象上,也就是可以通过binder_node对象或者desc两种方式在binder_proc上查找到binder_ref或binder_node。所以,对于flat_binder_object对象来说,它的binder+cookie和handler指向了同一个binder_node对象上,即同一个binder对象。 BinderDriverCommandProtocolBinder驱动的命令协议(BC_命令),定义了Binder驱动支持的命令格式及数据定义(协议)。不同的命令所

    16、带有的数据是不同的。Binder的命令由binder_write_read数据结构描述,它是ioctl命令(BINDER_WRITE_READ)的参数。struct binder_write_read signed long write_size; /* bytes to write */ signed long write_consumed; /* bytes consumed by driver */ unsigned long write_buffer; signed long read_size; /* bytes to read */ signed long read_consume

    17、d; /* bytes consumed by driver */ unsigned long read_buffer;对于写操作,write_buffer包含了一系列请求线程执行的Binder命令;对于读(返回)操作,read_buffer包含了一系列线程执行后填充的返回值。Binder命令(BC_)用于BINDER_WRITE_READ的write操作。Binder的BC的命令格式是:| CMD | Data. |Binder CommandsCMDData FormatNotesBC_TRANSACTIONBC_REPLYbinder_transaction_data BC_ACQUIR

    18、E_RESULTBC_ATTEMPT_ACQUIRE Not implementBC_FREE_BUFFERdata_ptrptr to transaction data received on a readBC_INCREFSBC_ACQUIREBC_RELEASEBC_DECREFSinttarget descriptorBC_INCREFS_DONEBC_ACQUIRE_DONEnode_ptr | cookie BC_REGISTER_LOOPERBC_ENTER_LOOPERBC_EXIT_LOOPER No parametersBC_REQUEST_DEATH_NOTIFICATI

    19、ONtarget_ptr | cookie BC_DEAD_BINDER_DONEcookie BinderDriverReturnProtocolBinder驱动的响应(返回,BR_)协议,定义了Binder命令的数据返回格式。同Binder命令协议一样,Binder驱动返回协议也是通过BINDER_WRITE_READ ioctl命令实现的,不同的是它是read操作。Binder BR的命令格式是:| CMD | Data. |Binder BR 命令CMDSData FormatNotesBR_ERRORintError codeBR_OKBR_NOOPBR_SPAWN_LOOPER N

    20、o parametersBR_TRANSACTIONBR_REPLYbinder_transaction_datathe received commandBR_ACQUIRE_RESULTBR_ATTEMPT_ACQUIREBR_FINISHED Not implementBR_DEAD_REPLY The target of the last transaction is no longer with us.bcTRANSACTION or bcATTEMPT_ACQUIREBR_TRANSACTION_COMPLETE No parameters.Always refers to the

    21、last transaction requested (including replies).Note that this will be sent even for asynchronous transactionsBR_INCREFSBR_ACQUIREBR_RELEASEBR_DECREFStarget_ptr | cookie BR_DEAD_BINDERBR_CLEAR_DEATH_NOTIFICATION_DONEcookie BR_FAILED_REPLY The the last transaction(either a bcTRANSACTION or a bcATTEMPT

    22、_ACQUIRE) failed(e.g. out of memory). Android Binder进程/线程模型(描述Android的进程模型)2.1.2 驱动接口Android Binder设备驱动接口函数是device_initcall(binder_init);我们知道一般来说设备驱动的接口函数是module_init和module_exit,这么做是为了同时兼容支持静态编译的驱动模块(buildin)和动态编译的驱动模块(module)。但是Android的Binder驱动显然不想支持动态编译的驱动,如果你需要将Binder驱动修改为动态的内核模块,可以直接将device_ini

    23、tcall修改为module_init,但不要忘了增加module_exit的驱动卸载接口函数。 binder_init初始化函数首先创建了一个内核工作队列对象(workqueue),用于执行可以延期执行的工作任务:static struct workqueue_struct *binder_deferred_workqueue;binder_deferred_workqueue = create_singlethread_workqueue(binder);挂在这个workqueue上的work是binder_deferred_work,定义如下。当内核需要执行work任务时,就通过work

    24、queue来调度执行这个work了。static DECLARE_WORK(binder_deferred_work, binder_deferred_func);queue_work(binder_deferred_workqueue, &binder_deferred_work);既然说到了binder_deferred_work,这里有必要来进一步说明一下,binder_deferred_work是在函数binder_defer_work里调度的:static voidbinder_defer_work(struct binder_proc *proc, enum binder_defe

    25、rred_state defer) mutex_lock(&binder_deferred_lock); proc-deferred_work |= defer; if (hlist_unhashed(&proc-deferred_work_node) hlist_add_head(&proc-deferred_work_node, &binder_deferred_list); queue_work(binder_deferred_workqueue, &binder_deferred_work); mutex_unlock(&binder_deferred_lock);deferred_w

    26、ork有三种类型,分别是BINDER_DEFERRED_PUT_FILES,BINDER_DEFERRED_FLUSH 和BINDER_DEFERRED_RELEASE。它们都操作在binder_proc对象上。enum binder_deferred_state BINDER_DEFERRED_PUT_FILES = 0x01, BINDER_DEFERRED_FLUSH = 0x02, BINDER_DEFERRED_RELEASE = 0x04,;就现介绍到这里了,关于deferred的具体操作在后面还会有详细的介绍。下面回到我们的初始化函数主题上。初始化函数接着使用proc_mkdir

    27、创建了一个Binder的proc文件系统的根节点(binder_proc_dir_entry_root,/proc/binder),并为binder创建了binder proc节点(binder_proc_dir_entry_proc,/proc/binder/proc),注意不要混淆Linux Proc和Binder Proc。然后Binder驱动使用misc_register把自己注册为一个Misc设备(/dev/misc/binder)。最后,如果驱动成功的创建了/proc/binder根节点,就调用create_proc_read_entry创建只读proc文件:/proc/binde

    28、r/state,/proc/binder/stats,/proc/binder/transactions,/proc/binder/transaction_log,/proc/binder/failed_transaction_log。这个初始化函数有个小小的问题,它没有判断Misc设备是否注册成功了,如果注册失败了,那么Binder就不能正常工作了,因此这里应该有个错误处理流程。注:workqueue是Linux2.6内核的一种延期执行任务的一种机制,用于提到古老的任务队列(task queue)机制,workqueue机制非常灵活,简单,易于使用。mutex_lock和 mutex_unl

    29、ock是一种内核同步机制。2.1.3 Binder核心数据在进一步介绍Binder驱动之前,我们有必要了解一下Binder的核心数据。 binder_procstruct 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 task_struct *tsk; struct

    30、files_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; uint32_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_threads_started; int ready_threads; long default_priority;binder_proc用于保存调用b


    注意事项

    本文(Binder深入讲解底层 内核实现.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开