android之init進程-uevent

來源:互聯網
上載者:User

標籤:

轉載!

    Init是linux kernel啟動的第一個進程,理解init,對熟悉android系統非常重要。

   Android的每個目錄下面都有一個非常重要的檔案Android.mk,負責編譯該目錄下面的代碼。

   System/core/init/android.mk

[cpp] view plaincopy  
  1.   <span style="font-size:18px;"> </span><span style="font-size:18px;"><span style="color:#ff0000;">LOCAL_MODULE:= init  
  2. </span>  
  3.    LOCAL_FORCE_STATIC_EXECUTABLE := true  
  4.    LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)  
  5.    
  6.    <span style="color:#ff0000;">include $(BUILD_EXECUTABLE</span>)  
  7.   
  8.    SYMLINKS := $(TARGET_ROOT_OUT)/sbin/ueventd  
  9.    $(SYMLINKS): INIT_BINARY := $(LOCAL_MODULE)  
  10.    $(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk  
  11.     @echo "Symlink: [email protected] -> ../$(INIT_BINARY)"  
  12.     @mkdir -p $(dir [email protected])  
  13.     @rm -rf [email protected]  
  14.     </span><span style="font-size:18px;color:#ff0000;">$(hide) ln -sf ../$(INIT_BINARY) [email protected]  
  15. </span>  


  

     上面的代碼會產生一個叫init的可執行程式,它會被放在/下面,且同時    會產生一個符號連結/sbin/eventd,指向/init. 我們不禁要問,為什麼這樣做?

      Init是一個指令碼解譯器,它會對目標系統下的兩個檔案解析,

     /init.rc

     /init.xxx.rc (xxx代表平台平台名)

     先看看原始碼目錄/device/xxx/init.rc

[cpp] view plaincopy  
  1. <span style="font-size:18px;">  on early-init  
  2.      start ueventd  
  3.   </span>  

     

     看來init在解析指令碼的時候又啟動了一個自己的進程,只是進程名變成了ueventd.

    

     System/core/init/init.c/main

[cpp] view plaincopy  
  1. <span style="font-size:18px;">  if (!strcmp(basename(argv[0]), "ueventd"))  
  2.         return ueventd_main(argc, argv);  
  3.   </span>  

     

     根據進程名不同,程式執行路徑不同。Ueventd顧名思義應該是接收uvent的守護進程,這裡它的主要作用根據uevent是建立或刪除/dev/xxx(xxx裝置名稱),我們知道在linux下面建立裝置節點的介面mknod,我們跟進去看看這個介面是在哪裡調用的

     

     System/core/init/Ueventd.c/ueventd_main

       

[cpp] view plaincopy  
  1.    <span style="font-size:18px;">ueventd_parse_config_file("/ueventd.rc");  
  2.   
  3.   snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);  
  4.   ueventd_parse_config_file(tmp);  
  5.   
  6.   device_init();  
  7. </span>  


 

 

          ueventd有兩個指令碼需要解析,ueventd.rc,ueventd.xxx.rc,指令碼,又見指令碼這個指令碼可以讓客戶設定/dev 或 /sys目錄及子目錄的許可權.

    system/core/rootdir/ueventd.rc 

[cpp] view plaincopy  
  1. <span style="font-size:18px;">  /dev/binder               0666   root       root</span>  

    

     這裡請注意,ueventd_parse_config_file並不建立裝置節點,它的作用是提供資料庫,當有裝置節點產生的時候,eventd會參考這個資料庫設定裝置節點的許可權。

    

      system/core/init/devices.c/device_init

         

[cpp] view plaincopy  
  1.    <span style="font-size:18px;"> device_fd = open_uevent_socket();  
  2.    coldboot("/sys/class");  
  3.    coldboot("/sys/block");  
  4.    coldboot("/sys/devices");  
  5. </span>  

 

        

       這個函數很簡單,主要是建立了uevent的socket handle,同時觸發/sys/clas,/sys/block,/sys/devices這三個目錄及其子目錄下的uevent,然後接受並建立裝置節點,至此裝置節點才算建立,coldboot裡面有個很有意思的函數do_coldboot,這是一個遞迴調用函數,實現的很有意思,大家可以看看.

      

     system/core/init/Ueventd.c/ueventd_main  

[cpp] view plaincopy  
  1. <span style="font-size:18px;">  while(1) {  
  2.         ufd.revents = 0;  
  3.         nr = poll(&ufd, 1, -1);  
  4.         if (nr <= 0)  
  5.             continue;  
  6.         if (ufd.revents == POLLIN)  
  7.                handle_device_fd();  
  8.     }  
  9. </span>  


 

          死迴圈,接受kernel傳過來的uevent,動態建立或刪除節點.

      handle_device_fd會最終調用mknod建立裝置節點,流程如下:

      handle_device_fd-> handle_device_event-> make_device-> mknod

android之init進程-uevent

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.