全面認識Android手機 (MIUI ROM適配之旅第一天——認識Android手機 )

lostinai發表於2014-01-10

http://blog.csdn.net/andy_android/article/details/7211153

在MIUI論壇裡讀了讀“MIUI ROM的適配教程",覺得很不錯,我覺得對大家很有幫助,我就轉載了
原文章論壇地址 :http://www.miui.com/forum-forumdisplay-fid-38-page-1.html

總共六部分:

第一部分:先認識一下Android手機的軟體結構,介紹一些基本概念。

第二部分:準備工作,包括一些工具和環境的搭建。

第三部分:反編譯,介紹APK的結構,資源的修改,smali檔案等。

第四部分:移植MIUI Framework

第五部分:移植MIUI APP

第六部分:製作刷機包

這個系列的文章需要大家瞭解一些Linux基礎知識,瞭解JAVA語言,能有一些Android的程式設計經驗更好。


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分割槽的結構。

3. 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將相機特效所使用的一些檔案也放在這個目錄下。

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

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

5. data和cache分割槽
  這一節簡單的介紹一下data和cache分割槽。當我們開機進入桌面程式後,一般來說我們都會下載安裝一些APP,這些APP都安裝在data/app目錄下。所有的Android程式生成的資料基本上都儲存在data/data目錄下。wipe data實質上就是格式化data分割槽,這樣我們安裝的所有APP和程式資料就都丟失了。
   
  cache分割槽從名字上來看是用來快取一些檔案的,比如說一些音樂下載的臨時檔案,或者下載管理下載的內容基本上放在這個分割槽。

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

相關文章