1. 程式人生 > >編譯Android原始碼製作ROM,燒錄。

編譯Android原始碼製作ROM,燒錄。

簡介

Android原始碼編譯後,在out/target/product/generic下生成的三個映象文 件:ramdisk.img,system.img,userdata.img以及它們對應的目錄樹root,system,data。 ramdisk.img是根檔案系統,system.img包括了主要的包、庫等檔案,userdata.img包括了一些使用者資料,android載入 這3個映像檔案後,會把 system和 userdata分別載入到 ramdisk檔案系統中的system和 data目錄下。

三個映象檔案及其三個目錄樹之間的生成關係是我們進行ROM製作的基礎,下面將做詳細介紹。

Ramdisk.img
Ramdisk映象是採用cpio打包,gzip壓縮的。用file驗證:

# file ramdisk.img

輸出:

# ramdisk.img: gzip compressed data, from Unix

為了便於說明問題,我們將ramdisk.img拷貝到其它一個目錄,然後按以下步驟將ramdisk.img還原為目錄樹:

# mv ramdisk.img ramdisk.img.gz

# gunzip ramdisk.img.gz

# mkdir ramdisk

#cd ramdisk

# cpio –i –F ../ramdisk.img

這樣,就得到一個完整的ramdisk目錄,與out/target/product/generic/root對比後,我們發現它們是一樣的內容。

通過執行以下的操作,我們可由目錄樹再生成ramdisk映象

# cd ramdisk

# find . | cpio -o -H newc | gzip > ../ramdisk-new.img

system.img & userdata.img
這兩個映象都屬於yaffs2檔案格式,生成方式是一樣的。我們就以system.img為例來說明。

# mkdir system

# cd system

# unyaffs ../system.img

system目錄樹 >> system.img

所需工具 mkyaffs2image,Android原始碼編譯後會生成該工具,在 out/host/linux-x86/bin 目錄下。

命令格式:
進入mkyaffs2image所在目錄,設定執行許可權chmod a+x ./mkyaffs2image

# ~/Code/cbin/mkyaffs2image ~/Code/system ~/Code/system_new.img

瞭解以上方法的意義在於,我們可以對映象檔案映象修改,定製,以符合自己的需求。

Android ROM的製作方法

網上有很多製作Android ROM的教程,這裡羅列一些連結:

北理工的陳罡寫的兩篇文章,是我目前發現的最好的教程,寫的非常詳細

這兩篇文章參考了國外論壇的幾個經典教程:

國內還有一篇文章寫的也不錯,這篇文章更側重於製作類似Patch的ROM包

這裡基於自己的理解和測試,總結了一些方法步驟。

一、從可用的ROM起步

Android 的ROM包通常稱為update.zip包,你可以到www.hiapk.com上下載現成的.zip包。要學習ROM包的製作,我們可以從這樣一個zip包開始。解開zip包後,通常有這樣一些內容:

boot.img檔案
這是編譯核心原始碼生成的核心映像,然後與android原始碼編譯出來的ramdisk.img一起通過mkbootimg工具創建出來的,圖省事的朋友也可以從網上其他的刷機包裡面拷貝一個能用的出來即可,基本上都差不多。
META-INF目錄
這個目錄是手工建立的,主要用來存放一個升級指令碼update-script(這個指令碼的內容與system目錄中包含的檔案有很大關聯)以及簽名。
system目錄
這個目錄就是編譯android的平臺原始碼生成的,要建立自己的ROM,我們通常會涉及到以下的一些工作:

1. 編譯核心生成核心映像。但一般情況下,我們沒有必要自己去編,直接從刷機包裡面取出一個就可以。譬如,你要做一個2.2版本的升級包。可以到網上找一個與自己機型相匹配的刷機包,從裡面取出相應的kernel.img。

2. ramdisk.img的修改。ramdisk.img 是根檔案系統,裡面包含了啟動配置指令碼。

3. update-script的修改。

4. System的修改。

我們先做個簡單的測試工作,來為後面更復雜的工作做好鋪墊。測試內容為:先對zip進行解包,然後分別在ramdisk和system的根目錄下新增一個小檔案,接著,生成新的ROM,並驗證ROM是否可用。

詳細的步驟可以參考http://blog.chinaunix.net/u/26691/showart_2194274.html。這裡要指出 的是,這篇文章以及網上許多類似網站提到的方法都是針對HTC G1或 Nexus one的。而我在測試的時候,用的是HTC G3 Hero。以上的方法導致的一個後果是,重新打包後再燒錄,機器無法正常啟動,adb shell也無法登陸。後來在國外的一篇部落格上看到了對此問題的說明,問題的根源很簡單,從G3開始,打包的時候需要指定 “--base”引數。對於Hero,引數為”--base 0x19200000”,但對於其它型號的機器,”--base"要設定為多少,需要參考核心程式碼的實現。

解包打包可用兩個指令碼完成unpack-bootimg.pl, repack-bootimg.pl。其中打包指令碼用到的mkbootimg工具,在out/host/linux-x86/bin目錄下。 unpack-bootimg.pl可直接將boot.img生成核心映象boot.img-kernel和ramdisk目錄樹boot.img- ramdisk。repack-bootimg.pl可將boot.img-kernel和boot.img-ramdisk重新生成boot.img。

在解包後,我們在ramdisk和system目錄下,各新增一個測試小檔案(譬如叫mytest)。做完這些開始組包,重新生成 update.zip。到這裡我們的工作並沒有完全結束,還有最後的一步——簽名。簽名需要用到簽名工具testsign.jar,這是一個基於java 1.6版本的工具。在編譯Android原始碼的時候,我們強調要用java 1.5。在這裡,我們必須切換到1.6版本。切換辦法見這裡。

二、利用自己編譯的映象生成ROM

1)重新生成boot.img

將前面解包得到的boot.img-ramdisk 和 編譯原始碼後out/target/product/generic/下的root目錄樹放在一個目錄下,然後用repack-bootimg.pl重新生成boot.img

2) 建立一個目錄 myupdate,將上面生成的boot.img放到這個目錄下

3)將編譯Android後,out/target/product/generic/生成的system目錄樹拷貝到myupdate目錄

4)在myupdate目錄下建立update-script指令碼目錄

# mkdir -p META-INF/com/google/android

5)刪除system/bin目錄下的“符號連結”,建立update-script指令碼

update-script指令碼的語法可以參考 這裡 。研究原有的update-script指令碼,我們可以大致看出update-script負責檔案刪除拷貝,許可權設定,符號連結建立等工作。我們可以在 原有update-script的基礎上進行修改以得到我們自己的update-script。這裡,我們要注意的是,要保證update-script 的link建立成功,必須把/system/bin下的link刪除。我們可以用一個指令碼來做這個工作 delsymlink。我修改後與自己編譯的Android2.2 system目錄樹相匹配的指令碼。

6)重新打包並簽名

7)自制ROM下載時報錯

在試驗過程中,我經常遇到如下的報錯

Can't open/sdcard/download/update.hiapk

問題原因:當 update-script 中有命令操作錯誤,指令碼就會停止,並報這個錯誤,解決的辦法就是修正指令碼。你可以從這個錯誤前面的提示,知道指令碼哪一行出錯了。

三、 建立一個Patch功能的ROM

很多時候,你並不需要建立一個完整的ROM包。你需要的只是,新增刪除或修改一些功能(譬如你僅想新增一個應用,或者你想新增busybox工具)。我們可以參考這裡,來實現這個目的。

我用一個簡單的例子來說明這個過程。該例子是在system目錄下新增一個mytest檔案,同時建立一個指向這個檔案的符合連結mylink。以下是過程:

1) 建立patch_update目錄,並在該目錄下執行

# mkdir system

# mkdir –p META-INF/com/google/android

2) 在system目錄下生成mytest檔案

3) 在 META-INF/com/google/android 建立如下的update-script

show_progress 0.1 0

copy_dir PACKAGE:system SYSTEM:

symlink mytest SYSTEM:mylink

set_perm 0 0 0755 SYSTEM:mytest

4) 打包簽名

如果前面的3步曲,你已經很好的掌握了,應付你的日常工作應該沒有太大的問題。但要成為真正的ROM高手,你還有很多東西要修煉。你要了解整個啟動過程,核心編譯,Android原始碼的編譯及配置,檔案系統及啟動配置。。。

燒錄 Android 機器
HTC的官網上有一篇文章 這裡 詳細介紹了映象包及燒機方法。通常用兩種燒錄方式:recovery模式,fastboot模式。通過一些組合鍵,可以進入燒錄模式。以HTC G3 Hero為例,“Home + Power”同時按,可以進入Recovery模式,“Back + Power”可以進入fastboot模式。

Recovery模式比較常用,它相當選單介面的下載模式。直接把前面所述的update.zip檔案放到SD卡上,然後通過在機器上操作控制菜 單,就可完成燒錄。Fastboot是基於命令列的較低階的下載模式,它可直接燒錄.img檔案。Fastboot工具也在out/host /linux-x86/bin目錄下。

在我測試過程中,發現fastboot模式無法燒錄,當我試圖燒錄system.img的時候,出現下面的出錯資訊:

# fastboot flash system system.img

# writing 'system'... INFOsignature checking...

FAILED (remote: signature verify fail)

在網上查了之後,發現這和簽名有關係,SPL要重新刷一下才可,預設是SPL-on,即檢測簽名,改成SPL-off,就不會出現這個問題,目前沒有什麼好辦法來處理這個問題。好在recovery模式已經能很好地滿足需求了,可以先放棄fastboot。

如果你通過recovery模式燒錄後,發現系統無法正常啟動,沒有關係,recovery還是可以進去的。在recovery模式下,你可以通過 adb shell登陸機器。可能你進去後,發現SD卡並沒有掛接上來(執行mount就可以檢視掛載情況)。但recovry模式要求update.zip必須 放在SD卡根目錄下,怎麼辦?很簡單,執行“mount –a”就可把SD卡區域掛接上來。如果這招也不行,還有一招,就是把userdata分割槽手動掛接到sdcard目錄,這樣就騙過了recovery。

# mount /dev/mtdblock5 /sdcard

然後,你再用adb push把新的update.zip拷貝到sdcard目錄,重新進行燒錄。一般來說,在執行“Flash zip from sdcard”之前,都要先進行Wipe操作,以清除舊的使用者資料。

如何更新recovery?

可以參考http://bbs.gfan.com/viewthread.php?tid=66973,按照這個攻略,把自己的G3 Hero更新成了recovery-RA-hero-v1.6.2-blue.img。不過,一般無特別的需求,最好不要更新recovery。畢竟有一 定風險,一不小心就成了板磚。

其它參考資訊:
知名的Android論壇:

國內:www.hiapk.com

國外:http://android-dls.com 很多國內論壇的文章都是參考或翻譯http://android-dls.com 的

Android 檔案系統

Android init指令碼的語法