MIUI ROM適配之旅第一天——認識Android手機

寫這篇文章時想起我的第一部Android手機HTC Hero。買回來後,同事告訴我可以去刷機玩玩。刷機,怎麼刷?同事說,你個土人,刷機都不知道,很多刷機論壇的,你去逛逛,挺簡單的。我去逛了逛機鋒論壇(那時還不知道MIUI),打開一看,什麼recovery, radio, root各種詞彙撲面而來,oh my lady gaga,這麼複雜。但是爲了不被鄙視,而且閒着也是閒着,還是刷着玩玩吧。後來就結識MIUI來到了小米。這是題外話,咱們言歸正傳。

 在這紛紛擾擾的Android世界裏,如何找到那條刷機大道呢,或許它只是個傳說,我們只是一直在探索。讓我們從零開始來看一看,看能發現點什麼。
  1. bootloader
    當我們拿到一款手機,第一件事應該就是按下電源鍵開機,那麼從開機到進入到桌面程序這中間發生了些什麼呢,我們從下面這張簡化了的手機結構圖開始:

    注意:該結構圖並不反映手機的實際分區順序和位置,只是一個邏輯結構圖。

    大家可以簡單的把手機的ROM存儲類比爲我們電腦上的硬盤,這個硬盤被分成了幾個分區:bootloader分區,boot分區,system分區等等。後面我們會逐漸介紹各個分區的用途。所謂的刷機我們可以簡單的理解成把軟件安裝在手機的某些分區中,類似於我們在電腦上安裝Windows系統。

    當按下電源鍵手機上電啓動後,首先從bootloader分區中一個固定的地址開始執行指令,如圖所示,bootloader分區分成兩個部分,分別叫做primary bootloader和secondary stage bootloader。Primary bootloader主要執行硬件檢測,確保硬件能正常工作後將secondary stage bootloader拷貝到內存(RAM)開始執行。Secondary stage bootloader會進行一些硬件初始化工作,獲取內存大小信息等,然後根據用戶的按鍵進入到某種啓動模式。比如說大家所熟知的通過電源鍵和其它一些按鍵的組合,可以進入到recovery,fastboot或者選擇啓動模式的啓動界面等。我們在論壇上看到的bootloader通常指的就是secondary stage bootloader。不過我們不需要關心太多的細節,可以簡單的理解爲bootloader就是一段啓動代碼,根據用戶按鍵有選擇的進入某種啓動模式。

    fastboot模式:fastboot是android定義的一種簡單的刷機協議,用戶可以通過fastboot命令行工具來進行刷機。比如說fastboot flash boot boot.img這個命令就是把boot.img的內容刷寫到boot分區中。一般的手機廠商不直接提供fastboot模式刷機,而是爲了顯示他們的牛B之處,總是會提供自己專有的刷機工具和刷機方法。比如說三星的Odin,摩托的RSD,華爲的粉屏等等。但是其本質實際上是相同的,都是將軟件直接flash到各個分區中。

    recovery模式:recovery是android定義的一個標準刷機協議。當進入recovery模式時,secondary stage bootloader從recovery分區開始啓動,recovery分區實際上是一個簡單的Linux系統,當內核啓動完畢後,開始執行第一個程序init(init程序是Linux系統所有程序的老祖宗)。init會啓動一個叫做recovery的程序(recovery模式的名稱也由此而來)。通過recovery程序,用戶可以執行清除數據,安裝刷機包等操作。一般的手機廠商都提供一個簡單的recovery刷機,而大名鼎鼎的CWM Recovery就是一個加入了很多增強功能的recovery,要想用上CWM Recovery前提是recovery分區可以被刷寫。大家在論壇上看到的解鎖bootloader,通常指的就是解鎖recovery或fastboot,允許刷寫recovery分區,這樣大家就可以用上喜愛的CWM Recovery了。

    手機除了普通的CPU芯片以外,還有MODEM處理器芯片。該芯片的功能就是實現手機必需的通信功能,大家通常所的刷RADIO就是刷寫modem分區。

  2. 正常啓動

    當我們只是按下電源鍵開機時,會進入正常啓動模式。Secondary stage bootloader會從boot分區開始啓動。Boot分區的格式是固定的,首先是一個頭部,然後是Linux內核,最後是用作根文件系統的ramdisk。

    一般針對每個機型的完整刷機包中會有一個boot.img文件,這就是boot分區鏡像文件。如何編輯該鏡像文件可以參照這篇文章http://android-dls.com/wiki/inde … Re-Pack_Boot_Images。

    當Linux內核啓動完畢後,就開始執行根文件系統中的init程序,init程序會讀取啓動腳本文件(init.rc和init.xxxx.rc)。啓動腳本文件的格式大家可以在網上找到很多參考資料,這裏就不寫了,而且我們在原廠ROM上移植MIUI的原則是不修改boot分區,因爲有一些機型無法修改boot分區。

    根文件系統中有一個重要的配置文件,叫default.prop,該文件的內容一般爲:
    #

ADDITIONAL_DEFAULT_PROPERTIES

#
ro.secure=1
ro.allow.mock.location=1
ro.debuggable=0
persist.service.adb.enable=1。
文件中的每一行對某個屬性賦值,在後續的文章中我們還會談到屬性。這裏面大家需要注意的兩個屬性:ro.secure和ro.debuggable。如果ro.secure=0允許我們運行adb root命令。在下一篇我們會詳細介紹adb,這是我們做ROM移植的利器。通常大家說得內核ROOT指的就是ro.secure=0。ROOT權限只是的手機上有一個名爲授權管理的程序(Superuser.apk)可以授予程序root用戶的權限。ro.deguggable=1允許調試系統APP。

init程序讀取啓動腳本,執行腳本中指定的動作和命令,腳本中的一部分是運行system分區的程序,下一節我們就來看看system分區的結構。
  1. system分區
    在講system分區之前,我們先來看下面這張Android的軟件系統架構圖。

    從上到下依次爲:
    核心應用層:這一層就是大家平常所接觸的各種各樣的系統自帶應用,比如聯繫人,電話,音樂等。應用層往下就是開發人員所接觸的。

    框架層:這一層是Android系統的核心,它提供了整個Android系統運作的機制,像窗口管理,程序安裝包管理,開發人員所接觸的Activity, Service, broadcast等等。

    JNI層:JNI層是Java程序和底層操作系統通信的一個機制,它使得Java代碼可以調用C/C++代碼來訪問底層操作系統的API。

    Dalvik虛擬機:Android開發使用Java語言,應用程序的Java代碼會被編譯成dalvik虛擬機字節碼,這些字節碼由dalvik虛擬機解釋執行。

    本地庫:本地庫一般是由C/C++語言所開發,直接編譯成相應CPU的機器碼,這其中包含標準C庫,用以繪製圖形的skia庫,瀏覽器核心引擎webkit等。

    HAL:硬件抽象層,爲了和各個廠家的不同硬件工作,Android定義了一套硬件接口,比如說爲了使用相機,廠家的相機驅動必須提供的接口方法。這樣使得上層的代碼可以獨立於不同的硬件運行。

    廠家適配層:本來Android定義的HAL層是直接和廠家提供的設備驅動打交道的,但是目前廠家不想開源HAL部分的代碼,因此很多廠家都提供了一個我稱之爲廠家適配層的代碼,這樣在HAL層接口的實現只是一個簡單的對廠家適配層接口函數的調用。

    內核:這一層就是大家熟悉的Linux內核,內核中包含有各種硬件驅動,這些驅動不同的手機廠商不同的手機是不一樣的。Linux內核是支持驅動模塊化機制的,簡單的說就是允許用戶動態的加載或者卸載某個硬件驅動,但是目前來看,手機廠商除了提供WIFI驅動單獨加載外,其它驅動都是和內核綁定在一起的。

從這張軟件結構圖來看,除了內核是放在boot分區外,其它層的代碼都是在system分區中。

下面結合這張圖來介紹system分區的主要目錄內容:
system/app: app目錄下存放的是核心應用,也就是大家熟知的系統APP,這些系統自帶的程序是不能簡單的卸載的,要通過一些特殊的方式才能刪除(大家熟悉的一種方法是用RE文件管理器)。

system/lib: lib目錄下存放的是組成JNI層,Dalvik虛擬機,本地庫,HAL層和廠家適配層的所有動態鏈接庫(.so文件)。

system/framework: 該目錄下存放的是框架層的JAR包,其中對MIUI移植來說有3個最重要的JAR包(framework.jar, android.policy.jar, services.jar)。後續的文章會重點介紹這3個包。

system/fonts: 該目錄下存放的是系統缺省的字體文件。

system/media:該目錄下存放的是系統所使用的各種媒體文件,比如說開機音樂,動畫,壁紙文件等。不同的手機該目錄的組織方式可能不一樣。如何修改這些文件請參考網上對應機型形形色色的教程,這裏不再贅敘。

system/bin: 該目錄下存放的是一些可執行文件,基本上是由C/C++編寫的。其中有一個重要的命令叫app_process下一節單獨介紹。

system/xbin: 該目錄下存放的是一些擴展的可執行文件,既該目錄可以爲空。大家常用的busybox就放在該目錄下。Busybox所建立的各種符號鏈接命令都是放在該目錄。

system/build.prop: build.prop和上節說得根文件系統中的default.prop文件格式一樣,都稱爲屬性配置文件。它們都定義了一些屬性值,代碼可以讀取或者修改這些屬性值。屬性值有一些命名規範:
ro開頭的表示只讀屬性,即這些屬性的值代碼是無法修改的。
persist開頭的表示這些屬性值會保存在文件中,這樣重新啓動之後這些值還保留。
其它的屬性一般以所屬的類別開頭,這些屬性是可讀可寫的,但是對它們的修改重啓之後不會保留。
很多ROM製作者都會修改一下build.prop信息,裏面的一些以ro.build開頭的屬性就是你在手機設置中的關於手機裏看到的。可以通過修改build.prop文件來將這個ROM打上自己的印記(XXX所修改)。我見過一個只是刪了system/app的一些程序,然後修改build.prop中的ro.build.display.id和ro.build.version.incremental中的兩個屬性值打上自己的大名的ROM。

system/etc: 該目錄存放一些配置文件,和屬性配置文件不一樣,這下面的配置文件可能稍微沒那麼的有規律。一般來說,一些腳本程序,還有大家所熟悉GPS配置文件(gps.conf)和APN配置文件(apns-conf.xml)放在這個目錄。像HTC將相機特效所使用的一些文件也放在這個目錄下。

  1. Zygote(app_process)
    上一節提到init會執行一個重要的命令程序叫app_process,一般大家稱之爲Zygote。(Zygote是卵的意思,所有的Android進程都是由它生出來的)。Zygote首先會加載dalvik虛擬機,然後產生一個叫做system_server的進程。system_server顧名思義被稱作Android的系統服務程序,它主要管理整個android系統。system_server啓動完成後開始尋找一個叫做啓動器的程序,找到之後由zygote開始啓動執行啓動器,這就是我們常見到的桌面程序。

上面描述的是一個相當簡化的啓動過程,瞭解這些對於適配MIUI基本上就夠了,如果大家對這些想進一步瞭解的話,請關注市面上各種Android內幕書籍。

  1. data和cache分區
    這一節簡單的介紹一下data和cache分區。當我們開機進入桌面程序後,一般來說我們都會下載安裝一些APP,這些APP都安裝在data/app目錄下。所有的Android程序生成的數據基本上都保存在data/data目錄下。wipe data實質上就是格式化data分區,這樣我們安裝的所有APP和程序數據就都丟失了。

    cache分區從名字上來看是用來緩存一些文件的,比如說一些音樂下載的臨時文件,或者下載管理下載的內容基本上放在這個分區。

  2. 小結
    本章主要是介紹了一下Android手機的硬軟件結構以及主要分區的內容,並簡要的介紹了一些開機啓動過程。瞭解這些內容有助於我們從整體上理解ROM移植。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章