亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1232 | 回復(fù): 0
打印 上一主題 下一主題

Android110215: Android binder driver的簡記 [復(fù)制鏈接]

    1. <blockquote id="clw3t"><font id="clw3t"></font></blockquote>

      論壇徽章:
      0
      跳轉(zhuǎn)到指定樓層
      1 [收藏(0)] [報告]
      發(fā)表于 2011-02-15 18:17 |只看該作者 |倒序瀏覽
      Android110215:Android binder driver的簡記


      Email:    zcatt@163.com
      Blog    http://zcatt.cublog.cn

       
      內(nèi)容提要
      文檔簡要整理binder driver的內(nèi)容。以供備忘和參考。



      聲明
      僅限學(xué)習(xí)交流,禁止商業(yè)用途。轉(zhuǎn)載需注明出處。


      版本記錄
      Date        Ver        Note
      2011-02-15    0.1        Draft.  zcatt, Beijing
       
       
      1.    緣起
        Binder是android提供的IPC, 由driver, framework, jni,和相應(yīng)java程序組成. 其中binder driver是實現(xiàn)這個IPC的基石.這里簡記了binder driver的分析.

      2.    binder driver的輪廓
        binder driver基本組成如下, 其中重要的兩個方法是open和ioctl. open完成設(shè)備的打開. ioctl完成IPC的具體通信, 定義了幾條命令,最常用的命令是BINDER_WRITE_READ和BINDER_SET_CONTEXT_MGR. 這里將備忘open和ioctl的BINDER_WRITE_READ和BINDER_SET_CONTEXT_MGR。

              static const struct file_operations binder_fops = {
                  .owner = THIS_MODULE,
                  .poll = binder_poll,
                  .unlocked_ioctl = binder_ioctl,
                  .mmap = binder_mmap,
                  .open = binder_open,
                  .flush = binder_flush,
                  .release = binder_release,
              };

              static struct miscdevice binder_miscdev = {
                  .minor = MISC_DYNAMIC_MINOR,
                  .name = "binder",
                  .fops = &binder_fops
              };
         
        本質(zhì)上binder driver就是一塊共享內(nèi)存, 發(fā)送者進(jìn)程發(fā)送數(shù)據(jù)到driver, 接收者從driver接收數(shù)據(jù).這種機(jī)制屬于c/s模型. c發(fā)送請求數(shù)據(jù), 阻塞等待s的回應(yīng), s阻塞在讀driver上, 如果有數(shù)據(jù), 則處理, 然后將結(jié)果發(fā)回c, 繼續(xù)阻塞讀driver.
        app使用binder driver的方式是這樣的, 每次傳送稱作一次write_read操作. 這樣一次操作的參數(shù)中包括兩部分: 1)write data, 需要傳出的數(shù)據(jù); 2)read data, 容納讀入數(shù)據(jù)的空間. 也就是每次傳送實際有兩個操作, 先寫操作, 后讀操作.如果write data為空, 則忽略寫操作;read data大小為0, 則忽略讀操作.
        為了方便表述, 數(shù)據(jù)的發(fā)送者進(jìn)程/線程我們稱為源,接收者進(jìn)程/線程稱為宿.在driver中, 每個進(jìn)程/線程都有一個數(shù)據(jù)鏈表, 其它進(jìn)程/線程發(fā)過來的數(shù)據(jù)都將先掛接到這個數(shù)據(jù)鏈表上等待處理. binder driver的read_write簡要算法如下:

                  write_read(writeData, readData)
                  {
                      if (writeData != null)
                      {
                          wnode = new node(writeData);
                          append wnode to 宿.todoList;
                          wakeup(宿.wait);
                      }

                      if (readData != null)
                      {
                          waitOn(當(dāng)前.wait);
                          while(1)
                          {
                              rnode = detachNodeFrom(當(dāng)前.todoList);
                              readData += dataIn(rnode);
                          }
                      }
                  }

        首先,writeData會被掛到宿的數(shù)據(jù)鏈表上,將來宿進(jìn)程/線程會處理, 然后wakeup宿進(jìn)程/線程的信號量. 接下來處理讀操作. 阻塞(waitOn)在當(dāng)前進(jìn)程/線程的型號量, 隨后從自己的數(shù)據(jù)鏈表上摘下其它進(jìn)程/線程發(fā)過來的數(shù)據(jù), 放入readData.

      3.    proc和log
        binder driver提供了proc項, 如下
              /proc/binder/
                  failed_transaction_log
                  transaction_log
                  transactions
                  stats
                  state
                  proc/

                 
      4.    主要數(shù)據(jù)結(jié)構(gòu)
        binder_proc結(jié)構(gòu)代表的是進(jìn)程相關(guān)的信息, 存放在filp->private_data. 使用binder driver的每個進(jìn)程都有自己的binder_proc實例. 依賴于進(jìn)程的數(shù)據(jù)都存放到binder_proc或能由此追溯到. 使用binder driver的所有binder_proc實例都鏈接到鏈表binder_procs中.

              struct 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 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;
              };

            .threads    進(jìn)程中所有的線程。一個進(jìn)程允許多進(jìn)程。
            .nodes    進(jìn)程中所有的binder_node實例. 關(guān)于binder_node后文介紹.
            .refs_by_desc    進(jìn)程中指向binder_node的binder_ref實例, 這些實例的desc是當(dāng)前進(jìn)程中累加指定的.
            .refs_by_node 進(jìn)程中指向binder_node的binder_ref實例。實際同.refs_by_desc。
            .todo        進(jìn)程中的binder_work鏈表。WRITE_READ操作的read操作時應(yīng)該處理的工作。
            .wait        進(jìn)程的信號量。其它進(jìn)程/線程向一進(jìn)程.todo加入工作后,應(yīng)當(dāng)wakeup這個進(jìn)程的.todo,喚醒這個進(jìn)程的read操作,執(zhí)行讀取操作。

        binder_thread結(jié)構(gòu)代表的是線程相關(guān)的信息。唯一標(biāo)識thread的是pid。

                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; /* Write failed, return error code in read buf */
                  uint32_t return_error2; /* Write failed, return error code in read */
                      /* buffer. Used when sending a reply to a dead process that */
                      /* we are also waiting on */
                  wait_queue_head_t wait;
                  struct binder_stats stats;
              };

          .*proc        所屬進(jìn)程的binder_proc。
          .rb_node    用于binder_proc.threads。
          .*transaction_stack    鏈表,node是線程發(fā)起的binder_transaction實例。
          .todo        線程中的binder_work鏈表。
          .wait        線程的信號量。其它進(jìn)程/線程向一進(jìn)程.todo加入工作后,應(yīng)當(dāng)wakeup這個線程的.todo,喚醒這個線程的read操作,執(zhí)行讀取操作。

        binder_work是一個鏈表的node結(jié)構(gòu)。WRITE_READ操作中的write操作處理完writeData后會根據(jù)data的信息將工作分成不同的種類,也就是binder_work.type,然后加入到宿進(jìn)程/線程的todo鏈表中。宿進(jìn)程/線程執(zhí)行read操作時根據(jù)binder_work.type進(jìn)行不同的處理。binder_node, binder_ref_death, binder_transaction是binder_work的擴(kuò)展結(jié)構(gòu)。各種類型和binder_work及擴(kuò)展結(jié)構(gòu)的對應(yīng)關(guān)系如下
          binder_work: BINDER_WORK_NODE, BINDER_WORK_TRANSACTION_COMPLETE
          binder_node: BINDER_WORK_NODE
          binder_ref_death: BINDER_WORK_DEAD_BINDER, BINDER_WORK_DEAD_BINDER_AND_CLEAR, BINDER_WORK_CLEAR_DEATH_NOTIFICATION
          binder_transaction: BINDER_WORK_TRANSACTION


              struct binder_work {
                  struct list_head entry;
                  enum {
                      BINDER_WORK_TRANSACTION = 1,
                      BINDER_WORK_TRANSACTION_COMPLETE,
                      BINDER_WORK_NODE,
                      BINDER_WORK_DEAD_BINDER,
                      BINDER_WORK_DEAD_BINDER_AND_CLEAR,
                      BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
                  } type;
              }; 

      5.    open
        binder_open完成設(shè)備的打開操作,算法如下
              binder_open(*filp)
              {
                  struct binder_proc *proc;

                  proc = kzalloc();
                  初始化各參數(shù);
                  proc加入到鏈表binder_procs中
                  filp->private_data = proc;
                  在/proc/binder/proc下創(chuàng)建以pid為名的file entry.
              }


      6.    ioctl
        binder driver的具體操作是通過ioctl擴(kuò)展命令的方式達(dá)到的。binder ioctl實現(xiàn)了幾條命令,重要的當(dāng)屬BINDER_SET_CONTEXT_MGR和BINDER_WRITE_READ,這里分別記述。

      6.1    BINDER_SET_CONTEXT_MGR
        雖然一般多個進(jìn)程/線程同時使用,但binder driver有唯一一個線程稱作binder driver的context mgr,使用靜態(tài)變量binder_context_mgr_node存儲。context mgr特殊的地方在于,往handle=0上發(fā)的所有數(shù)據(jù)都是發(fā)到context mgr的。android中, context mgr負(fù)責(zé)service的登記和查詢工作。
       
                  case BINDER_SET_CONTEXT_MGR:
                      ... ... ...
                      binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
                      ... ... ...
                      break;

      6.2    BINDER_WRITE_READ
        IPC的通信操作最終靠的是這個命令。前面已經(jīng)描述了它的基本算法。源碼中可以參看binder_thread_write()和binder_thread_read()。

      7.    HANDLE type和BINDER type
        Binder object做為對象IPC傳遞時binder driver有特別的處理。A進(jìn)程中本地實現(xiàn)了BBinder的服務(wù),如何將這個Binder obj傳遞到B進(jìn)程,B進(jìn)程才能使用? 顯然直接傳遞obj的指針是不行的,因為兩個進(jìn)程各有自己的地址空間,并不能直接的互相引用。解決的辦法是使用BpInterface, 也就是說Binder driver不會傳給B進(jìn)程obj,而是傳給一個obj的引用ref. B進(jìn)程拿到這個ref后,生成相應(yīng)的BpInterface。在binder driver自己的數(shù)據(jù)結(jié)構(gòu)中,這個ref就唯一對應(yīng)了binder obj,當(dāng)收到發(fā)往ref的數(shù)據(jù)時,driver就把數(shù)據(jù)發(fā)往這個obj。
        binder obj和ref的關(guān)系是1對n的關(guān)系。
        下面的源碼可以參照
              binder_transaction() @ driver/binder.c
              writeStrongBinder() @ parcel.cpp
              IInterface.h

       




      Locations of visitors to this page
      您需要登錄后才可以回帖 登錄 | 注冊

      本版積分規(guī)則 發(fā)表回復(fù)

        

      北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
      未成年舉報專區(qū)
      中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
      感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

      清除 Cookies - ChinaUnix - Archiver - WAP - TOP