본문 바로가기
Programming/Android Kernel,Native

Binder Source Analysis (바인더 소스 분석)

by 개Foot/Dog발?! 2014. 10. 13.

URL : http://victor8481.tistory.com/239


.....


Binder는 service_manager와 함께 시작된다.

service_manager의 main함수를 살펴보자.

binder_open()함수를 통해서 "/dev/binder"를 open하고 binder_loop()함수를 실행하는데,

[ bs->fd = open("/dev/binder", O_RDWR); ]

이 때 인자로 binder_state 포인터 변수와 BINDER_SERVICE_MANAGER를 넘긴다.

이것은 필요에 따라 실행되는 프로세스가 아닌, 안드로이드 부팅과 함께 실행되어 종료될때까지 동작한다.


<frameworks/base/cmds/servicemanager/service_manager.c>



BINDER_SERVICE_MANAGER는 다음과 같이 정의되어있다.
<frameworks/base/cmds/servicemanager/binder.h>



binder_loop()함수에서는 무한루프에서 ioctl()함수와 binder_parse()함수를 호출한다.

뭐 ioctl()함수로 메시지를 가져오고 binder_parse()함수로 parsing한 후 적절한 동작을 수행할 것이다.

<frameworks/base/cmds/servicemanager/binder.c>



그럼 어떻게 메시지가 Binder device driver로 보내지는지, 그리고 parsing한 후 보내야할 프로세스로 메시지를 보내는

지를 알아보자.


Binder 통신을 하기 전에 먼저 메시지를 수신할 프로세스는 자신을 service_manager에 등록해야한다.

service_manager가 알지도 못하는 프로세스로 메시지를 보낼 순 없으니 말이다.

service_manager에 등록하기 위해서 IServiceManager의 인스턴스를 얻어야 하는데, 이때 사용하는 함수가

defaultServiceManager()이다.

<frameworks/base/libs/binder/IServiceManager.cpp>


IServiceManager 인스턴스를 통해서 addService()함수를 이용하여 프로세스를 등록한다.
이제 메시지를 수신할 프로세스를 service_manager에 등록했으니 메시지가 있으면 프로세스의 onTransact()함수를
호출할 것이다.
그럼 메시지를 보내는 것은 어떻게 될까.
addService()가 있으니 반대로 getService()함수가 있다.
getService 함수로 메시지를 수신할 프로세스의 Binder 인스턴스를 획득하고 transact()함수를 호출한다.



** 위 소스들은 언제것인지 모르겠으나 최근 4.4버전의 소스는 약간 다르다


</frameworks/native/cmds/servicemanager/service_manager.c>

int main(int argc, char **argv)

{

    struct binder_state *bs;


    bs = binder_open(128*1024);

    if (!bs) {

        ALOGE("failed to open binder driver\n");

        return -1;

    }


    if (binder_become_context_manager(bs)) {

        ALOGE("cannot become context manager (%s)\n", strerror(errno));

        return -1;

    }


    svcmgr_handle = BINDER_SERVICE_MANAGER;

    binder_loop(bs, svcmgr_handler);


    return 0;

} 



</frameworks/native/cmds/servicemanager/binder.h>

/* the one magic handle */

#define BINDER_SERVICE_MANAGER  0U


#define SVC_MGR_NAME "android.os.IServiceManager"


enum {

    /* Must match definitions in IBinder.h and IServiceManager.h */

    PING_TRANSACTION  = B_PACK_CHARS('_','P','N','G'),

    SVC_MGR_GET_SERVICE = 1,

    SVC_MGR_CHECK_SERVICE,

    SVC_MGR_ADD_SERVICE,

    SVC_MGR_LIST_SERVICES,

}; 


</frameworks/native/cmds/servicemanager/binder.c>

* 앞서 설명된 binder.c와 동일


</frameworks/native/libs/binder/IServiceManager.cpp>

* 앞서 설명된 IServiceManager.cpp와 동일