Android 創世紀 第二天

來源:互聯網
上載者:User

第二天,google說,荒蕪要被開墾,系統便運作了,它是linux。

               --xxx

     荒蠻大地就要變得肥沃,linux已經運行起來了。。。。

 

     linux就不多講了,這裡只講講被google大刀闊斧改了核心後的linux。

 

     第一天最後,核心init已經幹完了自己的事,把控制權交給了第一個使用者級進程,也叫做init。

 

     想知道這個init幹了什麼事,我們只能看看源碼,不貼代碼,這裡只說說它幹了什麼。

     (system/core/init/init.c -->main)

 

一、清空umask

     也就是設定預設許可權,這裡設定為0,umask為0000的話,就相當於chmod中的0777,經常使用linux對於chmod 777應該很熟悉,就是賦予某個檔案的許可權為,所有組、所有使用者可讀可寫可運行,也就是最寬鬆的許可權。

 

二、建立並掛載一些基本的目錄

      建立目錄並掛載相應系統:

        /dev   裝置目錄,所有的外圍裝置都在這裡了,包括真實的裝置如sim卡,也包括虛擬裝置如必不可少的null裝置。掛載關係是 /dev -> tmpfs,tmpfs顧名思義就是臨時檔案系統,這個系統只佔用記憶體空間。

       /proc  系統資訊目錄,包含了當前系統的所有資訊,比如進程、時鐘等等動態資訊。掛載關係是 /proc -> proc

        /sys  這裡儲存的東西,都是硬體裝置在linux上映射的對象,比如pci裝置。掛載關係是 /sys -> sysfs

        /dev/pts  這個是遠程終端控制台裝置,字元終端啦,如果木有這個的話,就不可能adb shell調試android。掛載關係是 /dev/pts -> devpts

        /dev/socket  服務於android的,socket是linux中進程通訊的一種方式,/dev/socket下面就是已經被系統分配的soket資源,這裡基本上是一些本地服務,比如ridl,有興趣可以adb shell查看一下。

 

三、初始化NULL裝置,重新導向標準輸入輸出,初始化kmsg系統,並且解析init.rc檔案

      null是Linux的一個標準裝置,也就是所謂的黑洞,至於為什麼有它,就得從輸入輸出重新導向說起,比如linux控制台下運行一個程式,有時會輸出一大堆東西,這是它向標準輸出寫的,我們不想讓它顯示出來,就是用 > NULL給它的輸出重新導向到了這個黑洞裝置,系統呢會給這個程式返回一個寫入成功的操作,實質上,系統什麼都木有幹。

      kmsg是linux下的一個核心級的日誌系統,kernel message。就好比anroid提供的Log系統一樣,只是針對核心層級的。

      對於init.rc檔案,這裡只進行瞭解析,並沒有執行裡面的一些命令。

 

四、獲得核心命令參數並且解析特定機型的init.*.rc檔案

      獲得核心命令參數,也就是顯式說明的一些參數,如果配置過grub或者Loli的話,就可能與這個打過交道。

     

      每個手機硬體平台都不一樣,adb shell一下,會發現有兩個rc檔案,其中一個就是與特定平台有關的rc設定檔,比如我的defy就是init.mapphone_umts.rc,為什麼叫這個?中間就是手機硬體平台的名字,可以 cat /proc/cpuinfo來獲得Hardware資訊,我的如下:

# cat cpuinfocat cpuinfoProcessor       : ARMv7 Processor rev 2 (v7l)BogoMIPS        : 299.11Features        : swp half thumb fastmult vfp edsp neon vfpv3CPU implementer : 0x41CPU architecture: 7CPU variant     : 0x3CPU part        : 0xc08CPU revision    : 2Hardware        : mapphone_UMTSRevision        : 0000Serial          : 0000000000000000CPU Tier        : 10

 

可以看到Hardware的值就是rc的副名稱。

       init首先會獲得/porc/cpuinfo中的這個屬性值,然後根據這個字串尋找特定的rc檔案,最後根據rc中的配置內容,解析它。

 

五、執行rc檔案中的命令

      上一步,init已經解析了那兩個rc檔案,這裡,會根據rc檔案中的具體內容,來分別執行對應的動作,後面會獨立分析rc檔案的格式內容,以及執行方法。

 

六、變為守護神

        到這裡,init就進入了死迴圈了for(;;){}。那麼它都守護了些什嗎?

   

    1、porpety service  啟動並守護屬性服務

        android下特有的。就好比windows下面的註冊表,記錄了各種資訊。大到系統是否成功啟動並執行標誌,小到簡訊聲音。使用者在設定一些手機設定的時候,在底層,實際就是和propety service打交道。

        

屬性首碼

描述

樣本(shell下操作)

ro. 唯讀屬性 setprop ro.media.capture.maxres 5m
網路攝影機的最大像素

persist.

額外儲存到/data/property目錄下 setprop persist.sys.country CN
不解釋。注意,每個屬性都儲存為單獨的一個檔案
net. 連網相關,比如gprs、藍芽…

setprop net.bt.name CAPF

藍芽的網路名稱為CAPF

net.change的值為最後一次更改net.*屬性的屬性名稱,例如:

net.change=net.gprs.local-ip

ctrl.start

控制命令

啟動init.rc中標註為service的服務

setprop ctl.start bootanim

啟動boot生動影像(第二屏啟動畫面)

一個服務設定後,其結果會以下面的屬性返回,例如

init.svc.bootanim=running

ctrl.stop

停止init.rc中標註為service的服務

setprop ctl.stop bootanim

停止boot生動影像(第二屏啟動畫面)

一個服務設定後,其結果會以下面的屬性返回,例如

init.svc.bootanim=stoped

        想要查看並設定屬性,可以通過以下三種途徑:

    shell瀏覽檔案:

           /default.prop

           /system/build.prop

           /data/property/*

    java:

           System.getProperty(“xxxx”);

           System.setProperty(“xxxx”);

     c/c++:

           demo.c:

#include <cutils/properties.h>#include <stdio.h>void print_prop(const char* key,const char* value,void* cookie){printf("key=%s,value=%s/n",key,value);}int main(){property_list(print_prop,NULL);}

 

           Android.mk:

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= /list_property.cpp /LOCAL_SHARED_LIBRARIES := /libcutils /libutils /LOCAL_MODULE:= list_propinclude $(BUILD_EXECUTABLE)include $(call all-makefiles-under,$(LOCAL_PATH))

 

    2、動態產生裝置節點

       android的linux下面是沒有udev的,udev可以說是一個根據核心的硬體訊息來自動探索裝置的一個程式,android下面根據硬體相應的,也就是鍵盤與記憶卡,在平板上面的話就更多了,比如滑鼠、鍵盤等等。沒有udev的話,android是如何?硬體的熱插拔呢?

       和udev一樣,init守護神同樣監聽了uevent事件,自己根據uevent的內容來做相應的事情,與udev做了異曲同工之事。

       看一下大致流程。首先裝置狀態更改,核心會檢測到,並發出uevent訊息(字串),init檢測到訊息,交給相應函數處理,這個函數根據uevent的內容,再做進一步處理。除了插拔記憶卡等(android有專門的外存管理機制,就是vold),其它(比如資料線插入、滑鼠插入)都會處理。

 

    3、監聽keychord事件

       keychord是組合按鍵,從源碼的行為來看,應該是考慮到按鍵組合盤這種外設,大部分情況不會用到手機上,而多用在智慧型裝置上,也就是沒有觸屏以及按鍵很少的android裝置,比如運行android的手錶神馬的,通過不同的按鍵組合,來代表一個標準鍵盤的輸入。

       這個東東估計用的不多。

 

    4、殺死殭屍進程

       什麼是殭屍進程?

       linux的進程有個特點,一個主進程可以分裂(fork)子進程(android的受精卵zygote完美的發揚了這種精神),在案頭版的一些linux中,查看系統監視器,仔細看看進程資訊,會發現很多進程會是樹狀結構,點擊一個進程後面又展開了好幾個進程,而且是個多級樹。這都是一個進程有fork了好幾個子進程的結果。

       如果主進程被kill的話,那麼它的子進程就有可能成為殭屍進程,所謂殭屍就是不幹活但佔用空間的程式死屍,這時,init守護神就負責回收這些無辜的靈魂,來釋放本來就稀缺的記憶體資源。

 

     5、守護重要服務

        這些服務是native層面的服務,比如servicemanager、vold。例如重要的zygote,有時候(不經常)碰到的感覺和突然重啟一樣,這八成就是zygote崩潰並重啟了,要知道java世界可是zygote孵化出來的。

       

 

 

解讀init.rc

       android的init.rc文法是專屬的,可以說是一種語言吧。

       init.rc的文法分為行為(Actions),、命令(Commands) 、服務(Services)、選項(Options)

類別

名稱

描述

SECTION on 觸發條件
同上.. service 解析service
COMMAND chdir 更改當前工作目錄
同上.. chroot 更改參考的根目錄位置
.. class_start 啟動某個設定了class名稱的服務
.. class_stop 停止某個設定了class名稱的服務
.. domainname 網域名稱
.. exec 調用程式並轉移進程
.. export 提交變數
.. hostname 主機名稱
.. ifup 啟用網卡
.. insmod 掛載模組
.. import 引入配置,比如etc下的一些rc檔案,和java中的import差不多
.. mkdir 建立目錄
.. mount 掛載檔案系統
.. setkey 從源碼看,應該是設定一個命令的關鍵字縮寫,比如可以將domainname映射為dn
.. setprop 設定一個屬性
.. setrlimit

設定當前程式可以開啟的最大檔案數到系統規定程式可以開啟的最大檔案數

.. start 啟動服務
.. stop 停止服務
.. trigger 不清楚,難道是自訂觸發器?
.. symlink 建立符號連結
.. sysclktz

設定基準時間

.. wait 等待檔案準備好?Linux中這是進程調度的函數
.. write 向檔案、裝置寫個什麼東西。肯定不是傳訊息的那個wirte
.. copy 不解釋
.. chown 更改所有者
.. chmod 更改許可權
.. loglevel Log輸出層級,低於這個層級的就輸出
.. restart 重啟服務
OPTION capability 能力,也就是系統對進程的一種許可權控制。
同上.. class 設定class name
.. console 啟用控制台
.. critical 是否關鍵,也就是4分鐘之內重啟超過4次的話,重啟之後就進入recovery模式
.. disabled 不隨class自動啟動
.. group 組歸屬
.. keycodes 不明白。。。。。
.. oneshot 只啟動一次,意外退出後不必重啟
.. onrestart 重啟時
.. setenv 增加環境變數
.. socket 申請socket資源
.. user 使用者歸屬
.. ioprio io調度優先順序

(很多屬性與命令用法都與linux中同名命令差球不多)

       init是分段(section)解析init.rc的,在keywords.h中可以查看關鍵字的定義。init是以什麼標誌來分段解析init.rc呢?結合init.rc的內容,可以看出,分區段標記是以on 和 service來標記的。下面詳細說明。

    on   啥時候幹什麼

        on屬於行為。

      on early-init   

             init之前、載入完所有rc檔案後即執行,在miui的rom中,init.rc在early-init執行的是start ueventd,根據keywords.h的定義,start是個命令(COMMAND)。

             這裡順便說下ueventd,android中底層(一般指驅動)通知上層的事件,用的是uevent,java層通過觀察者模式實現,用到的類為 UEventObserver,使用intent來傳遞;native層用的是android_os_UEventObserver.cpp,使用uevent.c通過socket傳遞。當然,這是framework及以下的層面,一般開發不經常用到,更何況這幾個類都沒有被暴露出來。

      on init

             載入propety各項屬性檔案之前執行,在init變為propety service之前都屬於init階段。            

      on early-boot

             啟動屬性服務後即執行。

      on boot

             boot的時候執行。

      on property:xxxxx=x

             當某個屬性設定為預期值時執行。 

     關於init.rc,其實結合/src/system/core/init/* 源碼和init.rc檔案來看,會明白許多。

水平有限,錯誤之處請指正,多謝!   

  創世紀:第一天串連:http://www.cnblogs.com/hangxin1940/archive/2011/10/01/2196964.html

  創世紀:第三天串連:http://www.cnblogs.com/hangxin1940/archive/2011/10/22/2221451.html

原創文章,轉載請說明出處:

http://www.cnblogs.com/hangxin1940/archive/2011/10/01/2196964.html

相關文章

聯繫我們

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