Chinaunix首页 | 论坛 | 博客
  • 博客访问: 54535
  • 博文数量: 11
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-12 16:43
文章分类

全部博文(11)

文章存档

2013年(1)

2010年(10)

我的朋友

分类: LINUX

2010-04-27 09:02:59

第一部分Binder的组成
1.1 程序部分驱动程序的部分在以下的文件夹中:
kernel/include/linux/binder.h
kernel/drivers/android/binder.c

    binder
驱动程序是一个miscdevice,主设备号为10,此设备号使用动态获得(MISC_DYNAMIC_MINOR),其设备的节点为:

/dev/binder
    binder驱动程序会在proc文件系统中建立自己的信息,其文件夹为/proc/binder,其中包含如下内容:
proc目录:调用Binder各个进程的内容
state文件:使用函数binder_read_proc_state
stats文件:使用函数binder_read_proc_stats
transactions文件:使用函数binder_read_proc_transactions
transaction_log文件:使用函数binder_read_proc_transaction_log,其参数为binder_transaction_log (类型为struct binder_transaction_log)
failed_transaction_log文件:使用函数binder_read_proc_transaction_log 其参数为
binder_transaction_log_failed (类型为struct binder_transaction_log)


    在binder文件被打开后,其私有数据(private_data)的类型:

struct binder_proc
    在这个数据结构中,主要包含了当前进程、进程ID、映射信息、Binder的统计信息和线程信息等。
    在用户空间对Binder驱动程序进行控制主要使用的接口是mmap、poll和ioctl,ioctl主要使用的ID为:
#define BINDER_WRITE_READ        _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT  _IOW('b', 3, int64_t)
#define BINDER_SET_MAX_THREADS   _IOW('b', 5, size_t)
#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int)
#define BINDER_SET_CONTEXT_MGR   _IOW('b', 7, int)
#define BINDER_THREAD_EXIT       _IOW('b', 8, int)
#define BINDER_VERSION           _IOWR('b', 9, struct binder_version)


    BR_XXX等宏为BinderDriverReturnProtocol,表示Binder驱动返回协议。
    BC_XXX等宏为BinderDriverCommandProtocol,表示Binder驱动命令协议。
    binder_thread是Binder驱动程序中使用的另外一个重要的数据结构,数据结构的定义如下所示:
struct binder_thread {
      struct binder_proc *proc;
     struct rb_node rb_node;
     int pid;
     int looper;
     struct binder_transaction *transaction_stack;
     struct list_head todo;
     uint32_t return_error;
     uint32_t return_error2;
     wait_queue_head_t wait;
     struct binder_stats stats;
};

    binder_thread 的各个成员信息是从rb_node中得出。
    BINDER_WRITE_READ是最重要的ioctl,它使用一个数据结构binder_write_read定义读写的数据。
struct binder_write_read {
     signed long write_size;
     signed long write_consumed;
     unsigned long write_buffer;
     signed long read_size;
     signed long read_consumed;
     unsigned long read_buffer;
};

各个类之间的关系如下所示:
 

 

1.2 servicemanager部分       

        servicemanager是一个守护进程,用于这个进程的和/dev/binder通讯,从而达到管理系统中各个服务的作用。
        可执行程序的路径:
        /system/bin/servicemanager        
开源版本文件的路径:
frameworks/base/cmds/servicemanager/binder.h
frameworks/base/cmds/servicemanager/binder.c
frameworks/base/cmds/servicemanager/service_manager.c

       程序执行的流程:

open()
:打开binder驱动


mmap()
:映射一个128*1024字节的内存


ioctl(BINDER_SET_CONTEXT_MGR)
:设置上下文为mgr

       进入主循环binder_loop()
             ioctl(BINDER_WRITE_READ)
,读取

                       binder_parse()进入binder处理过程循环处理
         binder_parse()的处理,调用返回值:
        当处理BR_TRANSACTION的时候,调用svcmgr_handler()处理增加服务、检查服务等工作。各种服务存放在一个链表(svclist)中。其中调用binder_等开头的函数,又会调用ioctl的各种命令。
        处理BR_REPLY的时候,填充binder_io类型的数据结构

1.3 binder的库的部分
7 b1 R- T7 f/ |0 N* H: D) t  binder相关的文件作为Android的uitls库的一部分,这个库编译后的名称为libutils.so,是Android系统中的一个公共库。7 ~! }7 C6 {, Z& v+ G
  主要文件的路径如下所示:bbs.chinabyte.com( s! B6 C6 c3 d0 W- j& F
frameworks/base/include/utils/*
( w0 c% r9 ?/ d4 _1 ]0 sframeworks/base/libs/utils/*
3 ~( ^# j& y: e: [# M   
9 B" U& V5 \1 w: t% B  主要的类为:
) B" y; x* Q; m5 }3 i1 r/ gRefBase.h :bbs.chinabyte.com4 N2 ~3 \- ~/ o% h) w; R0 L3 y% _: w
  引用计数,定义类RefBase。
6 P! C0 g2 F# Fbbs.chinabyte.comParcel.h :( W( M/ P0 y; R
  为在IPC中传输的数据定义容器,定义类Parcelbbs.chinabyte.com3 L5 X7 c; i5 y
IBinder.h:
# m+ w" a/ \2 X  Binder对象的抽象接口, 定义类IBinder: _' H# a& D4 ~8 U* l
Binder.h:比特网论坛" s5 c1 \) E% I
  Binder对象的基本功能, 定义类Binder和BpRefBase
+ j. s. a$ n% O5 w8 }: B! r7 ABpBinder.h:9 ^! b- l, B6 y  p4 [% H% j
BpBinder的功能,定义类BpBinder( \0 _3 z. L( m3 `' X% W" u
IInterface.h:8 I: A" a& m( @. ~6 {
  为抽象经过Binder的接口定义通用类,% {7 w8 n& U$ c- {/ A) J
  定义类IInterface,类模板BnInterface,类模板BpInterface
/ C$ x% k& I: k) \: \2 a- L8 q比特网论坛ProcessState.h* x0 C4 y7 S3 M4 K$ \" t) f, b
  表示进程状态的类,定义类ProcessState
3 v- s# f% X7 e7 UIPCThreadState.h" {* {2 D% r2 ^9 [; n
  表示IPC线程的状态,定义类IPCThreadState
/ O  r6 o; E  N, Z. [  在IInterface.h中定义的BnInterface和BpInterface是两个重要的模版,这是为各种程序中使用的。0 [5 H  z8 P4 s+ h
BnInterface模版的定义如下所示:
9 N/ r3 p8 d9 P% wtemplate比特网论坛  G4 e( s; V+ c6 E4 u" V! I
class BnInterface : public INTERFACE, public BBinder. n0 x- _# b3 R5 z
{比特网论坛4 I3 C4 G4 t% p  i- F9 e( n8 [
public:比特网论坛( h3 {- H1 Z$ V1 `$ s
  virtual sp  queryLocalInterface(const String16& _descriptor);+ [* i! y( v" q3 u6 C
  virtual String16        getInterfaceDescriptor() const;
( j/ r$ S5 U1 @' B: v/ Eprotected:. ^4 n# g  Y# B5 ]
    virtual IBinder*        onAsBinder();bbs.chinabyte.com' _1 V/ l7 H) |/ b1 K
};
5 ], H, |& i/ _' \% d; Jbbs.chinabyte.com  BnInterface模版的定义如下所示:2 W7 Y! R9 Z7 w, R7 f6 A( S
template
8 V+ H) z) C% H( t比特网论坛class BpInterface : public INTERFACE, public BpRefBase
5 V- W/ {$ v( q; @! e! ebbs.chinabyte.com{
2 P. x! t1 m5 {" ppublic:" y/ ^0 e# H7 \+ h, ^3 H* Q
                            BpInterface(const sp& remote);: z* ~4 B4 H. w" p1 i
protected:bbs.chinabyte.com8 z/ ?; G3 e: Q
    virtual IBinder*    onAsBinder();
7 Z) n& w5 S5 K% E6 e# F* Q  \! d比特网论坛};
! W% ^2 h9 j( s  这两个模版在使用的时候,起到得作用实际上都是双继承:使用者定义一个接口INTERFACE,然后使用BnInterface和BpInterface两个模版结合自己的接口,构建自己的BnXXX和BpXXX两个类。
2 f7 J* N8 R. |$ w9 @1 R比特网论坛         DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE两个宏用于帮助BpXXX类的实现: 比特网论坛( V) t& }6 Q9 H% I
#define DECLARE_META_INTERFACE(INTERFACE)                               bbs.chinabyte.com9 \* B" m* S3 G% Q
    static const String16 descriptor;                                   
" {; @$ `2 U5 O8 ~$ X    static sp asInterface(const sp& obj);        
( h# A8 `% t+ C. U. b7 Y/ _. w  u* n" _bbs.chinabyte.com    virtual String16 getInterfaceDescriptor() const;                    
5 Q5 s7 Q4 f* ~, S比特网论坛#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       比特网论坛8 n7 P" ?, i+ E3 Y% v* E
    const String16 I##INTERFACE::descriptor(NAME);                     
7 v" T" @8 H/ @# ^6 E, m6 n    String16 I##INTERFACE::getInterfaceDescriptor() const {            
" v$ I3 _" |3 x/ j6 w        return I##INTERFACE::descriptor;                                + g1 ]* F- X2 O2 {7 N% {
    }                                                                   bbs.chinabyte.com0 x$ z2 G2 @' `
    sp I##INTERFACE::asInterface(const sp& obj) - v$ V" A! t6 P1 D. a: P/ v
    {                                                                  
: m8 H( W' ?& ?; Z9 P' y        sp intr;                                          , b- z: R3 o6 o" D& c" W% f. N
        if (obj != NULL) {                                             
  U# S7 O! W9 {6 o, qbbs.chinabyte.com            intr = static_cast(                         # ?9 ^+ Y3 a: f5 x4 ?8 E
                obj->queryLocalInterface(                              
( G) Z  @& w" s                        I##INTERFACE::descriptor).get());               
  [! Y6 v8 O, Q# Y& y            if (intr == NULL) {                                         
- L# s) P9 b$ g/ s' k8 ~6 O                intr = new Bp##INTERFACE(obj);                          bbs.chinabyte.com9 }: g, t% E% ^$ h/ \: H/ x  w: b
            }                                                           ! `) z$ d0 ~" o- y
        }                                                               ) T# B  j2 H; _4 {1 j( f7 r( W/ L
        return intr;                                                    比特网论坛: x3 `5 ]  `$ l* B/ H/ d
    }
' k7 M, Y2 W/ c  H  H$ M   在定义自己的类的时候,只需要使用DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE两个接口,并结 合类的名称,就可以实现BpInterface中的asInterface()和getInterfaceDescriptor()两个函数。

阅读(1965) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~