浅析android下native层binder的部分具体实现

浅析android下native层binder的部分具体实现

在defaultServiceManager( ) 方法中:[ luther. gliethttp]
= = > defaultServiceManager
= = >
sp< IServiceManager> gDefaultServiceManager; 的m_ptr指向new BpServiceManager( obj) ; 因为= 这个操作符被sp类模板重载
这个obj就是ProcessState: : self( ) - > getContextObject( NULL ) 返回的gProcess.
sp< ProcessState> gProcess; 的m_ptr指向new BpBinder( handle) ; [ ProcessState: : self( ) 函数返回] 因为= 这个操作符被sp类模板重载
看看BpServiceManager构造函数:
    BpServiceManager( const sp< IBinder> & impl)
        : BpInterface< IServiceManager> ( impl)
    {
    }

    template < typename INTERFACE>
    inline BpInterface< INTERFACE> : : BpInterface( const sp< IBinder> & remote)
        : BpRefBase( remote)
    {
    }

    BpRefBase: : BpRefBase( const sp< IBinder> & o)
        : mRemote( o. get( ) ) , mRefs( NULL ) , mState( 0) //这里o.get()就是gProcess.get(),返回gProcess指向new BpBinder(handle);的m_ptr
    { //mRemote在类IBinder中的定义:IBinder* const mRemote;[luther.gliethttp]
        extendObjectLifetime( OBJECT_LIFETIME_WEAK) ;

        if ( mRemote) {
            mRemote- > incStrong( this ) ; // Removed on first IncStrong().
            mRefs = mRemote- > createWeak( this ) ; // Held for our entire lifetime.
        }
    }

remote( ) - > transact( ADD_SERVICE_TRANSACTION, data, & reply) ;
这里的remote来自inline IBinder* remote( ) { return mRemote; }
因为mRemote为IBinder类的指针, - > 操作符没有被重载, 所以就是调用BpBinder: : transact方法[ luther. gliethttp]
status_t BpBinder: : transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if ( mAlive) {
        status_t status = IPCThreadState: : self( ) - > transact(
            mHandle, code, data, reply, flags) ;
        if ( status = = DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}


status_t flatten_binder( const sp< ProcessState> & proc,
    const sp< IBinder> & binder, Parcel* out)
{
    flat_binder_object obj;
    
    obj. flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    if ( binder ! = NULL ) {
        IBinder * local = binder- > localBinder( ) ;
//对于BBinder* BBinder::localBinder()
//{
// return this;
//}
//对于BBinder* IBinder::localBinder()
//{
// return NULL;
//}
        if ( ! local) {
            BpBinder * proxy = binder- > remoteBinder( ) ;
            if ( proxy = = NULL ) {
                LOGE( "null proxy" ) ;
            }
            const int32_t handle = proxy ? proxy- > handle( ) : 0;
            obj. type = BINDER_TYPE_HANDLE;
            obj. handle = handle;
            obj. cookie = NULL ;
        } else { //对于IServiceManager::addService将执行到这里
            obj. type = BINDER_TYPE_BINDER;
            obj. binder = local- > getWeakRefs( ) ; //作为红黑节点树的唯一id标号
            obj. cookie = local;
        }
    } else {
        obj. type = BINDER_TYPE_BINDER;
        obj. binder = NULL ;
        obj. cookie = NULL ;
    }
    
    return finish_flatten_binder( binder, obj, out) ;
}

commands/ binder/ service_manager. c
= > svcmgr_handler
= > do_add_service
commands/ binder/ service_manager. c
= = > main
= = > bs = binder_open( 128* 1024) ;
//proc->tsk = current;
//filp->private_data = proc;
= = > binder_become_context_manager( bs) ; //将bs作为context_manager管理binder,发送ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
//这样binder驱动的binder_context_mgr_node就是该bs了
= = > binder_loop( bs, svcmgr_handler) ; //回调函数svcmgr_handler,用来处理消息
void binder_loop( struct binder_state * bs, binder_handler func)
{
    . . .
    readbuf[ 0] = BC_ENTER_LOOPER;
    binder_write( bs, readbuf, sizeof ( unsigned ) ) ;
//thread->looper |= BINDER_LOOPER_STATE_ENTERED;
//struct binder_thread *thread = binder_get_thread()会查找该proc自己是否已经在binder_thread,
//rb_link_node(&thread->rb_node, parent, p);
//rb_insert_color(&thread->rb_node, &proc->threads);将该current[就是proc打开者自己]绑定到binder_thread,然后插入到proc管理的红黑树中.
//proc管理的红黑树的索引依据为pid数值:thread->pid = current->pid;
/*
 *struct binder_stats {
    int br[_IOC_NR(BR_FAILED_REPLY) + 1];
    int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1];
    int obj_created[BINDER_STAT_COUNT];
    int obj_deleted[BINDER_STAT_COUNT];
};

static struct binder_stats binder_stats;
 * */

    for ( ; ; ) {
        . . .
        bwr. read_size = sizeof ( readbuf) ;
        bwr. read_consumed = 0;
        bwr. read_buffer = ( unsigned ) readbuf;
//wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
//没有todo的咚咚
        res = ioctl( bs- > fd, BINDER_WRITE_READ, & bwr) ;
//首先binder推入4字节的BR_NOOP控制头
        . . .
        res = binder_parse( bs, 0, readbuf, bwr. read_consumed, func) ;
        . . .
    }
    . . .
}


driver中
device_initcall( binder_init) ;
= > binder_init
= > 创建/ proc/ binder根目录
= > 创建/ proc/ binder/ proc目录
= > misc_register( & binder_miscdev) ; 注册/ dev/ binder字符设备文件
= >/ dev/ binder节点由init进程在handle_device_fd( device_fd) ; = = > handle_device_event( & uevent) ; 中uevent- netlink处理之后, "/dev/" 目录下创建.
= > 创建只读文件"state""stats""transactions""transaction_log""failed_transaction_log" ,
  帮定读文件函数binder_read_proc_stats
这样binder驱动在内核中登记工作就完成了, 剩下的工作就是应用程序使用这个binder进行IPC了.
        if ( tr- > target. handle) { //目的handle
            struct binder_ref * ref;
            ref = binder_get_ref( proc, tr- > target. handle) ; //返回目的handle的ref,该handle由后面的binder_get_ref_for_node()函数生成
            if ( ref = = NULL ) {
                binder_user_error( "binder: %d:%d got "
                    "transaction to invalid handle/n" ,
                    proc- > pid, thread- > pid) ;
                return_error = BR_FAILED_REPLY;
                goto err_invalid_target_handle;
            }
            target_node = ref- > node;
        } else {
            target_node = binder_context_mgr_node;
            if ( target_node = = NULL ) {
                return_error = BR_DEAD_REPLY;
                goto err_no_context_mgr_node;
            }
        }

static struct binder_ref *
binder_get_ref( struct binder_proc * proc, uint32_t desc)
{
    struct rb_node * n = proc- > refs_by_desc. rb_node; //是否有该desc对应的内容
    struct binder_ref * ref;

    while ( n) {
        ref = rb_entry( n, struct binder_ref, rb_node_desc) ;

        if ( desc < ref- > desc)
            n = n- > rb_left;
        else if ( desc > ref- > desc)
            n = n- > rb_right;
        else
            return ref;
    }
    return NULL ;
}

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 long handle; /* remote object */
    } ;

    /* extra data associated with local object */
    void * cookie;
} ;
= = > binder_transaction
= = > struct flat_binder_object * fp;
        . . .
        switch ( fp- > type) {
        case BINDER_TYPE_BINDER:
        case BINDER_TYPE_WEAK_BINDER: {
            struct binder_ref * ref;
//上面obj.binder = local->getWeakRefs();//作为红黑节点树的唯一id标号,所以这里从红黑树上查找fp->binder节点[luther.gliethttp]
            struct binder_node * node = binder_get_node( proc, fp- > binder) ; //如果从红黑树中没有找到,那么
            if ( node = = NULL ) {
                node = binder_new_node( proc, fp- > binder, fp- > cookie) ; //创建一个新的node
                if ( node = = NULL ) {
                    return_error = BR_FAILED_REPLY;
                    goto err_binder_new_node_failed;
                }
                node- > min_priority = fp- > flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
                node- > accept_fds = ! ! ( fp- > flags & FLAT_BINDER_FLAG_ACCEPTS_FDS) ;
            }
            if ( fp- > cookie ! = node- > cookie) {
                binder_user_error( "binder: %d:%d sending u%p "
                    "node %d, cookie mismatch %p != %p/n" ,
                    proc- > pid, thread- > pid,
                    fp- > binder, node- > debug_id,
                    fp- > cookie, node- > cookie) ;
                goto err_binder_get_ref_for_node_failed;
            }
            ref = binder_get_ref_for_node( target_proc, node) ; //将新创建的node挂接到红黑树上
            if ( ref = = NULL ) {
                return_error = BR_FAILED_REPLY;
                goto err_binder_get_ref_for_node_failed;
            }
            if ( fp- > type = = BINDER_TYPE_BINDER)
                fp- > type = BINDER_TYPE_HANDLE;
            else
                fp- > type = BINDER_TYPE_WEAK_HANDLE;
            fp- > handle = ref- > desc; //获取唯一id号,作为handle用来区分service们
            binder_inc_ref( ref, fp- > type = = BINDER_TYPE_HANDLE, & thread- > todo) ;
            if ( binder_debug_mask & BINDER_DEBUG_TRANSACTION)
                printk( KERN_INFO " node %d u%p -> ref %d desc %d/n" ,
                 node- > debug_id, node- > ptr, ref- > debug_id, ref- > desc) ;
        } break ;
        case BINDER_TYPE_HANDLE:
        case BINDER_TYPE_WEAK_HANDLE: {
            . . .
            new_ref = binder_get_ref_for_node( target_proc, ref- > node) ;
            . . .
= = > binder_thread_write
= = > if ( target = = 0 & & binder_context_mgr_node & &
             ( cmd = = BC_INCREFS | | cmd = = BC_ACQUIRE) ) {
                ref = binder_get_ref_for_node( proc,
                     binder_context_mgr_node) ;

static struct binder_ref *
binder_get_ref_for_node( struct binder_proc * proc, struct binder_node * node)
{
    . . .
    rb_insert_color( & new_ref- > rb_node_desc, & proc- > refs_by_desc) ;
    new_ref- > desc = ( node = = binder_context_mgr_node) ? 0 : 1;
    for ( n = rb_first( & proc- > refs_by_desc) ; n ! = NULL ; n = rb_next( n) ) {
        ref = rb_entry( n, struct binder_ref, rb_node_desc) ;
        if ( ref- > desc > new_ref- > desc)
            break ;
        new_ref- > desc = ref- > desc + 1; //计算service们对应的唯一handle号[luther.gliethttp]
    }
    . . .
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值