2012年9月26日 星期三

把玩"魔術師" -- 編譯 AOSP 2.2 (Froyo) 原始碼

把玩"魔術師" -- 編譯 AOSP 2.2 (Froyo) 原始碼

This document is provided as is. You are welcomed to use it for non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
請勿轉貼

在不斷嘗試編譯 Android 2.2 的過程中,我發現了三份比較重要的文件,分別是 編譯在G1上運行的android 2.2(froyo)代碼編譯在G1上運行的android 2.2(froyo)代碼_正規版、以及 [HOW-TO] Compile AOSP Froyo + [ROM] Latest AOSP Froyo for Sapphire。經過幾個階段的測試、彙整,目前得到以下的方式最為完整。 之前所寫的另一個版本,也提供在 這裡 僅供參考。 既然能編譯出一個堪用的 HTC Magic 32A ROM,自然要把過程寫一下給有興趣的人試試看。 不過,這絕對不是一份任何人都一定看得懂的(我有些部分也還在摸索);因為 是給自己當筆記,我只能先假設你懂一些 Linux 的基本概念。我把編譯的過程 分成幾個步驟來說:(以下的步驟絕大部分都是在 Ubuntu/Linux 上執行)


  1. 你需要幫自己安裝一部執行 Linux 的電腦,AOSP 的文件建議使用 Ubuntu,而我安裝的是 Ubuntu 10.04 x86 32 bit 版。為了不影響平常的 使用,我是將 Ubuntu 安裝在一個名為 VirtualBox 的虛擬機器上;VirtualBox 是一套 Windows 的免費軟體,當在 VirtualBox 內執行 Ubuntu 的時候,電腦 基本上就同時執行 Windows 和 Ubuntu。當你將 Ubuntu 安裝完後,記得先用 "更新管理員"將所有軟體進行更新。
  2. 在編譯 AOSP 原始碼之前,我們必須先安裝一些套件。這些步驟主要是參考 dferreira 發表的 [HOW-TO] Compile AOSP Froyo + [ROM] Latest AOSP Froyo for Sapphire
    1. /etc/apt/sources.list 檔案的最後加上下列兩行:
        deb http://pl.archive.ubuntu.com/ubuntu/ jaunty multiverse
        deb http://pl.archive.ubuntu.com/ubuntu/ jaunty universe
        
    2. 檔案修改完後,請執行下列指令來該新 apt 的資料庫:
        sudo apt-get update
        
    3. 請執行下列指令(只有一行)來安裝必要的軟體:
        sudo apt-get install git-core gnupg sun-java5-jdk flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev valgrind libreadline5-dev gcc-multilib g++-multilib libc6-dev libncurses5-dev x11proto-core-dev libx11-dev libreadline5-dev libz-dev
        
    4. 請在自己的家目錄($HOME)底下新增一個 bin 目錄,並將 repo 安裝到 bin 內。安裝後可以登出然後登入,剛安裝的 repo 就可以開始使用。
        cd ~
        mkdir bin
        curl http://android.git.kernel.org/repo >~/bin/repo
        chmod a+x ~/bin/repo
        
    5. 決定 AOSP 原始碼放置的目錄,並建立該目錄。假設目錄的名稱是 froyo,且 位於 $HOME,以下為執行並進入 froyo 目錄:
        mkdir ~/froyo
        cd ~/froyo
        
  3. 軟硬體的環境設定好了之後,我們就開始要從 AOSP 的網站把原始碼抓下來。
    1. 由於 Android 的版本眾多,你必須定義出究竟是哪一個版本是你要的。 由於我們參考的 文件是編譯 Android 2.2 版的,因此我們的指令如下:
      repo init -u git://android.git.kernel.org/platform/manifest.git -b android-2.2.1_r1
      
      請特別注意以上指令的綠色部分:因為編譯的是 Android 2.2.1 版的,所以我們使用 android-2.2.1_r1,那麼如果有一天我要編譯 3.0 版呢?它的值應該是什麼 呢?其實,這個資料可以從 http://android.git.kernel.org/ 的網頁上找尋 platform/manifest.git,然後在它之後的 summary 連結上點一下,就可以知道。 在 http://android.git.kernel.org/?p=platform/manifest.git;a=summary 網頁的 下方的 tags 部分就可以看到所有可能的值。
    2. 執行 repo sync 把定義好的原始碼抓回來,這個可能會等待比較久的 時間。
  4. 編譯 kernel 以及無線網路的驅動程式。就像在 把玩"魔術師" -- 編譯 AOSP 2.1 (Eclair) 原始碼 所說的,如果你能找到適當的 kernel 和 wlan.ko,那麼這個步驟可以省略。其實使用正確的 kernel 版本很重要,但是 哪一版的 Android 應該配合哪一版的 kernel 呢?目前在網路上看到的情形是 "如果使用 Android x.x 版,但是 kernel 比較舊的 y.y 版,那麼一些新的功能 是無法執行的";所以從以上的圖片可以看出,HTC 的 kernel 是 2.6.27 版, 而 Android 是 2.2,所以應該會有一些 2.2 的功能無法發揮。為了能夠編譯 正確版本的 kernel,找到了 Wiki 上的 Android (operating system) 的 列表,我把它整理如下:
    • Android 1.5 (Cupcake): Kernel 2.6.27
    • Android 1.6 (Donut): Kernel 2.6.29
    • Android 2.0/2.1 (Eclair): Kernel 2.6.29
    • Android 2.2 (Froyo): Kernel 2.6.32
  5. 把新編譯的 kernel 和無線網路的驅動程式複製到適當的位置 -- ~/froyo/device/htc/dream-sapphire/。指令為
      cp ~/froyo/kernel/arch/arm/boot/zImage ~/froyo/device/htc/dream-sapphire/kernel
      cp ~/froyo/system/wlan/ti/sta_dk_4_0_4_32/wlan.ko ~/froyo/device/htc/dream-sapphire/wlan.ko
      
  6. 請在 device/htc/dream-sapphire/BoardConfigCommon.mk 的第 49 行 之後,新增一行在產生 boot.img 所需要的 base address 給 32A 的手機用,修改後, 第 49 和 50 行設定如下:
      BBOARD_KERNEL_CMDLINE := no_console_suspend=1 console=null
      BOARD_KERNEL_BASE := 19200000
      
  7. 將專屬於 HTC Magic 手機的重要的程式庫納入 system.img。這些程式庫 必須存在才能順利的編譯 Android,但是由於抓取的(或者說 HTC 提供的)都已經是 舊版的(明確的說是 1.6 版),所以常常造成編譯 出來的 image 檔雖然能夠在手機上執行,但是也造成許多程式(如之前提到的 Calendar 和 Music 等)無法順利執行的原因。
    1. 取得 HTC 的檔案,並解壓縮。抓取並解壓縮檔案的指令為
        wget --referer=http://developer.htc.com/google-io-device.html http://member.america.htc.com/download/RomCode/ADP/signed-google_ion-ota-14721.zip?
        mv signed-google_ion-ota-14721.zip sapphire_update.zip
        cd ~/froyo/device/htc/sapphire
        ./unzip-files.sh
        
      重要更新: 由於加拿大電信商 Rogers 以及美國電信商 T-Mobile 分別釋出了 Android 2.1 以及 2.2 (前者有 Sense UI,後者就是陽春 的 Google UI;這可能是因為目前的更新是針對 32B 的手機,而該手機的記憶體 有限所致),所以以上的 sapphire_update.zip 可以使用不同的來源。
      • 若使用 Rogers 的 2.1 版,可以下載 Rogers stock rom with root,下載後可以將檔案名稱從 Rogers_21_capychimp.zip 改成 sapphire_update.zip 即可。印象中,解出來的檔案只缺一個,也就是 libstagefrighthw.so,所以下一個步驟只需要刪除一行即可。
      • 若使用 T-Mobile 的 2.2.1 版,可以下載 Froyo OTA,下載後可以將檔案名稱從 e059adc603a3.signed-opal-ota-60505.e059adc6.zip 改成 sapphire_update.zip 即可。印象中,所需的檔案都有,因此下一個步驟 可以省略。
    2. 執行 unzip-files.sh 的過程中,總共有四個檔案找不到;這四個檔案分別是 libGLES_qcom.so、liblvmxipc.so、liboemcamera.so、libstagefrighthw.so。請修改 vendor/htc/sapphire/device_sapphire-vendor-blobs.mk 將包含該四個 檔案的四行敘述刪除。
  8. 編譯 Android 平台,編譯成功的話,會產生必要的 image 檔。
    1. 加入繁體以及簡體中文的支援,指令如下:
        cd ~/froyo
        
      並新增 buildspec.mk 檔案,在該檔案內加入
        CUSTOM_LOCALES:=zh_TW zh_CN
        
      在一些蒐集到的資料中,也顯示我們可以直接更改 build/target/product/full.mk,把第 43 行的
        $(call inherit-product, build/target/product/languages_small.mk)
        
      改成
        $(call inherit-product, build/target/product/languages_full.mk)
        
    2. 設定編譯的平台,包含以下指令:
        source build/envsetup.sh
        lunch full_sapphire-userdebug  # 也可以執行 lunch 並選擇平台
        
      lunch 指令後面那一串字包含一些重要資訊,我們把它拆開來看:第一個 aosp 也可以是 full,目前我不清楚它的差異;第二個 sapphire 代表 Magic 32A,可以是 dream, 也可以是 generic(代表基本型,僅適用模擬器);第三個是 us(代表美國),另一個 是 eu(代表歐洲);最後一個是 eng(代表有 root 權限),也可以是 userdebug(代表一般環境)。
    3. 執行 make -j2 編譯 image 檔;這會需要一段時間,完成後在 ~/froyo/out/target/product/sapphire 內可以看到 image 檔。
  9. 複製必要的字形檔,然後將新的字形檔與之前的結果,重新整理到 system.img 中。
      cp frameworks/base/data/fonts/DroidSansFallback.ttf  out/target/product/sapphire/system/fonts/
      make snod
      

後記:

以下是在幾次重新編譯過程中,試出來的一些結果。
  • 我試過將 HTC 的 kernel 和 Froyo 的各個版本做結合,大多可以撥、接電話, Wifi、3G 連線沒問題;相信再加上一些 Google 的應用程式(如 maps、market 等) 應該就算是一個堪用的 Froyo。只可惜,測到目前為止,個人比較在乎的相機以及 GPS 都無法正常運作。
    1. HTC 2.26.29 kernel + T-Mobile myTouch 3G Froyo 的畫面:由於 T-Mobile 的 Froyo 不是 WWE 版本的,不知道要如何中文化(跟 Rogers 2.1 的情形不一樣)。
    2. HTC 2.26.29 kernel + AOSP Froyo 2.2.1 的畫面:這是使用 T-Mobile myTouch 3G Froyo 的程式庫檔(也就是在執行 unzip-files.sh 時,解的是該 ROM 的內容); 如果解的是 Rogers Magic 2.1 的 ROM,將無法開機。
  • 根據 How to build a kernel port for CM6, 我們可以利用以下的方式來檢查你編譯的或者下載的 boot.img 是否能在 Magic 32A 用, 那就是把 boot.img 複製於 ~/froyo/kernel 的目錄下,並執行
      scripts/extract-ikconfig boot.img > test.config
      
    這個指令會把當初編譯這個 boot.img 的 kernel 時所使用的 .config 內容 輸出到 test.config 內;以 HTC Magic 32A 官方的 boot.img 來說,它產生的 test.config 部分內容如下:
    CONFIG_MSM_AMSS_VERSION=6355
    # CONFIG_MSM_AMSS_VERSION_6210 is not set
    # CONFIG_MSM_AMSS_VERSION_6220 is not set
    # CONFIG_MSM_AMSS_VERSION_6225 is not set
    # CONFIG_MSM_AMSS_VERSION_6335 is not set
    # CONFIG_MSM_AMSS_VERSION_6340 is not set
    CONFIG_MSM_AMSS_VERSION_6355=y
    # CONFIG_MSM_AMSS_VERSION_4001 is not set
    # CONFIG_MSM_AMSS_VERSION_1320 is not set
    # CONFIG_MSM_AMSS_VERSION_1330 is not set
    # CONFIG_MSM_AMSS_VERSION_1340 is not set
    # CONFIG_MSM_AMSS_VERSION_1355 is not set
    # CONFIG_MSM_AMSS_VERSION_4110 is not set
    # CONFIG_MSM_AMSS_VERSION_4410 is not set
    CONFIG_MSM_AMSS_SUPPORT_256MB_EBI1=y
      
    這也正好驗證之前的參考資料中所說的,給 Magic 32A 的 kernel 需要定義 CONFIG_MSM_AMSS_SUPPORT_256MB_EBI1=y,而若要編譯給 radio 6.35 版 的則至少要定義 CONFIG_MSM_AMSS_VERSION=6355 以及 CONFIG_MSM_AMSS_VERSION_6355=y。 利用同樣的方式來驗證我之前自以為可以編譯給 32A 的 boot.img,解出的 .config 內容卻沒有 CONFIG_MSM_AMSS_SUPPORT_256MB_EBI1=y 這一行, 所以從這個地方可以看得出來,只在 .config 中加上這項定義應該是不行的, 原因不明。看起來,32B 和 32A 的 kernel 差異絕對不是只靠一項定義就可以 搞定的。

Last Updated: <!--#flastmod file="build22.shtml"
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu

沒有留言:

張貼留言