android中binder的初始化

來源:互聯網
上載者:User

binder是android專屬的一種IPC機制,它是在/system/bin/servicemanager進程(可以用ps看到)中完成初始化的,它的父進程是init. 

1. 代碼: 

     frameworks\base\cmds\servicemanager\,這個目錄下,有service_manager.c,binder.c。

 
(1) 在service_manager.c中,有main函數,代碼如下:
int main(int argc, char **argv)
{
    struct binder_state *bs;
    void *svcmgr = BINDER_SERVICE_MANAGER;

    bs = binder_open(128*1024);

    if (binder_become_context_manager(bs)) {
        LOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    svcmgr_handle = svcmgr;
    binder_loop(bs, svcmgr_handler);
    return 0;
}

(2) binder_open:  位於binder.c中,binder_open函數實現如下: 
struct binder_state *binder_open(unsigned mapsize)
{
    struct binder_state *bs;

    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return 0;
    }

    bs->fd = open("/dev/binder", O_RDWR);
    if (bs->fd < 0) {
        fprintf(stderr,"binder: cannot open device (%s)\n",
                strerror(errno));
        goto fail_open;
    }

    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    if (bs->mapped == MAP_FAILED) {
        fprintf(stderr,"binder: cannot map device (%s)\n",
                strerror(errno));
        goto fail_map;
    }

        /* TODO: check version */

    return bs;

fail_map:
    close(bs->fd);
fail_open:
    free(bs);
    return 0;
}

2. 說明:
   (1) 在frameworks\base\cmds\servicemanager目錄下的Android.mk中,指定產生的模組為servicemanager:
         LOCAL_MODULE := servicemanager //
   (2) dev/binder會映射到一塊記憶體虛擬空間中,通過mmap系統調用來實現。
   (3) binder.c中還提供了一系列函數,用於支援binder的訪問。
   (4) binder通訊機制的實現中,是用ioctl的方式與核心進行互動的。

   (5) binder的初始化一定是在jvm的初始化之前,因為jvm初始化一直到上層的system_server的過程中,會有啟動很多的service,這些service都會去用到binder。

    (6) servicemanager這個進程的許可權是system,這個通過ps也能看出來,它是在init.rc中指定的。

3. 補充:

  mmap的使用:

    #include <sys/mman.h>  
 (1)   void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)。  
    描述: 把檔案或者裝置映射到記憶體。這個函數在調用進程的虛擬位址空間中建立一區塊對應地區。
     
    參數說明:
        addr: 指定映射地區的首地址, 如果addr是NULL,那麼由核心來選擇一個地址來建立映射的地區,否則建立的時候會儘可能地使用addr的地址。在linux系統中,建立映射的時候應該是在下一個頁面的邊界建立,addr是NULL的時候,程式的可移植性最好。
        length:指定映射地區的長度。
        offset:指定從檔案的哪個位移位置開始映射,offset必須是頁面大小的整數倍頁面的大小可以由sysconf(_SC_PAGE_SIZE)來返回。
        flags指定地區在不同進程之間的共用方式,以及地區是否同步到相應的檔案等等。
        fd: 檔案描述符.在binder中,指的就是:bs->fd = open("/dev/binder", O_RDWR)。

    傳回值: 這個函數返回新建立的頁面的地址。成功的時候這個函數返回0。   失敗的時候,返回-1。


  (2)  int munmap(void *addr, size_t length); 
    作用: munmap  取消address指定位址範圍的映射。以後再引用取消的映射的時候就會導致非法記憶體的訪問。這裡address應該是頁面的整數倍。 成功的時候這個函數返回0。   失敗的時候,返回-1.。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.