編譯android原始碼到模擬器上執行

編譯android的原始碼並載入到模擬器上執行

 
Version Notice: 
2. 新增SDK 1.5 r2 版本的相關說明 (2009.5.26)
1. 此文章中的平台版本為 SDK 1.1 r1 (2009.5.10)
 
 
0. 下載android的source code,請參考官方網頁的做法吧!(http://source.android.com/download)
 
1. 取出編譯的kernel設定檔(必須從模擬器那邊去得到,因為要編譯出的image要能在emulator上跑。)
    1.1 打開模擬器:(你可以直接從eclipse那邊開啟或是直接在cmd下打emulator -shell來開啟)
 
    Ex: 我的sdk放在 C:\WT\SoftWare\eclipse,那用cmd進入到tools目錄下,
        (1) 視窗鍵+R,輸入cmd。
        (2) cd C:\WT\SoftWare\eclipse\android-sdk-windows-1.1_r1\tools
        (3) emulator -shell
     
    1.2 拿出在模擬器中的設定檔: 
    (1) 再開啟另一個cmd,步驟如1.1的(1), (2)。
    (2) 輸入 adb pull /proc/config.gz pulldata\config.gz (pull是從模擬器中拿出檔案, 藍色是來源, 綠色的目的路徑, config.gz一般是放在proc目錄下)
    (3) 解開config.gz檔,得到config,改變檔名為 .config。(可以用7-ZIP來解 或是使用 gunzip config.gz)
         p.s. 如果你是在windows上的話,無法改成.config的話,可以等丟到kernel目錄中再改(mv config .config)。
 
    1.3 拿到編譯的設定檔之後,需要把它放進kernel目錄內:
    (1) 把.config放到~/mydroid/kernel 下去覆蓋原本的,如果kernel下原本就沒有.config檔時,可以輸入make menuconfig ,再直接exit。(http://nmc.nchu.edu.tw/linux/kernel.htm)
    
 
2. 修改Makefile:
    2.1 修改android makefile:
    (1) 基本上,編譯需要去設定編譯的目的os和cpu (target os and target cpu),而android的makefile裡的os和cpu預設是linux和arm,也就是說編譯後的程式能在os為linux且cpu為arm的機械中執行。所以如果丟到模擬器中跑的話,應該是不需要設定。
    (2) 如果需要設定可以去參考 build/core/envsetup.mk 這個檔:
        ifeq ($(TARGET_SIMULATOR),true)
            ifneq ($(HOST_OS),linux)
                $(error TARGET_SIMULATOR=true is only supported under Linux)
            endif
            TARGET_ARCH := $(HOST_ARCH)
            TARGET_OS := $(HOST_OS)
        else
            ifeq ($(TARGET_ARCH),)
                TARGET_ARCH := arm
            endif
            TARGET_OS := linux
        endif
 
        本身去執行編譯動作的機械的os和cpu稱為host os和host cpu,如果target與host不一致則需要cross compiler。android預設的cross compiler位置可以從envsetup.mk檔中可以找到,如下:
        ABP:=$(ABP):$(PWD)/prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-eabi-4.2.1/bin
        
    2.2 修改 android kernel makefile:
    (1) 如果你不想直接修改makefile,也可以在下make指令時一緒加入參數,如下。
        make msm_defconfig ARCH=arm
        make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
            
        如果想直接去修改makefile,需要設定cross compile。開啟kernel目錄下的Makefile,並設定CROSS_COMPILE且註解掉LDFLAGS_BUILD_ID,如下。
        CROSS_COMPILE= /android/arm-2008q3/bin/arm-none-linux-gnueabi-
        # LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,$(call ld-option, -Wl$(comma)--build-id,))
    
        corss compiler可以使用android source裡面原有的或是使用自己下載的來用。
        原有的corss compiler的位置在 prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
        也可以從這邊下載:http://www.codesourcery.com/sgpp/lite/arm/portal/release644
                   
        p.s. 其他修改設定可以去點閱參考網址。
 
 
3. 編譯 andoird 與 kernel:
    3.1 編譯kernel:
    (1) 在編譯的部份,要先編譯kernel完後再編android。如果你沒動到kernel,則不需要再重新編譯,可以去prebuilt/android-arm/kernel/ 下找到 kernel-qemu 這個映像檔來用。
    (2) kernel目錄下的輸入make開始編譯。(注意:需要完成步驟1的動作才會有.config,有設定檔才能進行編譯,要不然就要自己慢慢回答編譯的選項!)
    (3)* 編譯完,在kernel/arch/arm/boot/目錄下會產生 zImage。此zImage就是新的kernel image,原始的image是位於sdk/tools/lib/images/kernel-qemu。
        依android官方網頁的emulator的說明(http://developer.android.com/guide/developing/tools/emulator.html):
        kernel-qemu.img: The emulator-specific Linux kernel image.
 
    3.2 編譯android:
    (1) 如果你先前就編譯過android(repo時就make過),可以輸入 make clean去清除舊的編譯物。
    (2) 再來輸入 make 就會看到一堆訊息啦!(等它編譯完吧!在我這邊的server上是接近一個小時!)
    (3) 編譯完,在./out/target/product/generic/下會發現有三個.img檔:system.img, ramdisk.img, userdata.img,依官方網頁說明:
        ramdisk.img: The ramdisk image used to boot the system. 
        system.img: The initial Android system image. 
        userdata.img: The initial user-data disk image
 
 
4. 載入映像檔到模擬器中:
    4.1 映像檔位置(for SDK 1.1):
    (1) 依照android官方網頁的說明,映像檔是放在lib/images下,在我的電腦(os: xp)上是位於 C:\WT\SoftWare\eclipse\android-sdk-windows-1.1_r1\tools\lib\images
        用指令來指定image的方式如下: 
        emulator -image system.img -data userdata.img -ramdisk ramdisk.img 
        如果要重載kernel的image則如下:
        emulator -kernel <your own path>/zImage
    (2) 如果直接把image檔覆蓋掉在lib/images的檔案也能正常執行。
        如果使用指令則會啟動模擬器並載入參數路徑所指的映像檔,如下,其實上原本存在於lib/images的映像檔並沒有被參數載入的覆蓋掉!
        emulator -image backup\system.img
 
 
 
 
    4.1 - 1.5r2 映像檔位置(for SDK 1.5 r2 ):
    (1) 與SDK 1.1的差別是1.5之後多了程式執行的設定,因為在不同環境(G1, G2 or other platform)下的裝置會有所不同,例如G2沒有實體鍵盤。所以在開發與執行程式時,需要設定平台,android引入了AVD,而目前的target主要有三種,分別是android-1.1android-1.5add-ons。add-ons多了額外的外部lib,如google map。google map並不存在於android-1.5內,它已被獨立分開了。
         不同的target,其images存放在不同的位置:
          android-1.1: android-sdk-windows-1.5_r2\platforms\android-1.1\images
          android-1.5: android-sdk-windows-1.5_r2\platforms\android-1.5\images
          add-ons: android-sdk-windows-1.5_r2\add-ons\google_apis-3\images
          其餘的步驟就照著4.1即可順利完成!
          另外一提的是,從官方網頁 sync 的source code 並不包含add-ons,所以本人重新編譯的system image,如果覆蓋add-ons的映像檔後,會使得google map無法作用,但整個系統還是能起來。相對的,在android-1.1中,有內建的google map函式庫。
 
p.s. 有標注 紅星符號的地方 * 表示這些步驟本人尚未進行測試,純參考其他網頁的做法。
 
參考網址: