在MAC系統中編譯ANDROID源碼與模擬器內核GoldFish

本文是我在MAC下編譯ANDROID源碼和模擬器內核GoldFish時的過程與所遇到的問題解決方案,到目前已經編譯完成並在模擬器中成功加載自己的內核,同時在系統中加載了一個內核模塊進行測試,下面是編譯和問題解決過程:

約定:

1. $代表在Mac終端進行命令操作,#代表在Android終端進行操作

Section 1: 環境準備

首先,在MAC中編譯源碼需要的文件系統格式是case-sensitive的,對所要存儲代碼的盤查看其信息,可知其是否case-sensitive

我的操作系統是MAC OS X 10.8.3,原本是非Case-sensitive的,這裏是遇到的問題一,要下載源碼Android官方已說明需要Case-sensitive,若不是,有兩種解決方案

1. 創建一個Case-sensitive的鏡相

方法如android官網:http://source.android.com/source/initializing.html 所示

2. 使用ipartition將整個盤轉換爲case-sensitive

本人採用的是此方法,畢竟不知道最後會用多少硬盤空間來做Android開發,ipartition網址:http://www.coriolis-systems.com/iPartition.php

因爲需要從Recovery模式啓動,需要用一個U盤作啓動盤然後然後此工具進行case-sensitive的轉換。

然後是相關軟件的一些準備:

1> Xcode4

因爲之前做過iOS開發,所以一直就有。XCode是需要在https://developer.apple.com/註冊後下載的開發工具。

2>安裝MacPorts

因爲在Mac上不可能如Linux中用apt-get install等命令解析依賴獲得庫,需要在http://www.macports.org/install.php 中安裝Macports來獲取庫

並將/opt/local/bin加入環境變量中,寫入.bash_profile即可:

  • export PATH=$PATH:/opt/local/bin

    然後用如下命令獲取相關庫:

    • $ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg

    這裏有可能出現如下的問題:

    Warning: 

    The Command Line Tools for Xcode don't appear to be installed;most ports will likely fail to build.

    解決辦法

    在Terminal中執行sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer

    打開XCODE安裝組件 Command line tools : 

    xcode> preferences >downloads>components然後選擇Command line tools下載並安裝。



    3> JDK6/7

    要編譯Android還需要有JDK的支持,JDK6可在java.sun.com.下載,下載後將其加入到環境變量中,在此我用的JDK7, 並不是官網上推薦的JDK6

    4> Python 2.6--2.7

    直接下載即可 python.org. , 不過好像MAC中是自帶的


    Section 2: Android源碼下載與編譯

    這部分在http://source.android.com/source/downloading.html中有詳細說明每步作用

    1. 準備源碼下載工具repo

    建立一個文件夾用於放工具repo,並將其路徑寫入.bash_profile環境變量

    1. $ mkdir ~/bin
      $ PATH=~/bin:$PATH
    2. 下載工具repo

    $ curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    
    $ chmod a+x ~/bin/repo

    3. 建立源碼文件夾並下載源碼目錄manifest

    建立工作目錄

    $ mkdir Source
    $ cd Source

    建立工作目錄在工作目錄中下載源碼目錄文件manifest

    $ repo init -u https://android.googlesource.com/platform/manifest
    開始同步代碼:

    $ repo sync
    在這個同步代碼過程中,可能會有很多次斷線或停滯,關閉終端重新repo sync即可, 在所有同步完成前,此目錄都會爲空,看不到任何文件,只有用ls -a可以看到一個.git文件夾


    4.建立好環境變量並開始編譯

    $ source build/envsetup.sh
    用源碼中的文件設置好編譯的環境變量

    $ lunch full-eng
    選擇好要編譯的版本爲模擬器版本,具體各版本選項可用lunch命令進行選擇

    $ make goldfish_armv7_defconfig -j4
    然後使用make命令開始編譯,j4爲代碼編譯時所採用的線程數, armv7_defconfig代表將arm V7的.config文件作爲kernel的配置文件


    Section 3:下載模擬器源碼GoldFish編譯並用emulator加載

    這個部分主要是參考 http://blog.csdn.net/flydream0/article/details/7070392

    1. 下載GoldFish源碼於特定文件夾

    $mkdir GoldFish_Source
    $cd GoldFish_Source
    $git clone http://android.googlesource.com/kernel/goldfish.git
    下載過程中同樣是可能多次斷線,重新使用以上第三條命令繼續下即可,在完成前文件夾用ls -a都只能看到一個.git文件夾


    2.切換分支並編譯內核

    下載完成後,會看到有一個goldfish的文件夾,進入文件夾ls看到文件夾內容仍爲空,用git branch -a查看當前的分支



    然後使用如下命令切換到goldfish-3.4分支

    $git checkout remotes/origin/android-goldfish-3.4
    此時使用ls命令使可看到本文件夾下的goldfish內核,接下來我們需要將交叉編譯工具目錄加入到$PATH中去,將下面這行寫入.bash_profile中

    export PATH=/Users/keenite/Android/Source/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.6/bin:$PATH

    然後修改Kernel的Makefile文件:

    # ARCH ?= (SUBARCH)

    # CROSS_COMPILE?=$(CONFIG_CROSS_COMPILE:"%"=%)
    修改爲:
    ARCH ?= arm
    CROSS_COMPILE ?= arm-eabi-

    爲了保證環境變量等的正確,用以下命令再配置下環境變量

    $ source build/envsetup.sh
    $ lunch full-eng

    這裏在編譯前要注意一個問題,如果想在Android Emulator裏面用insmod安裝Linux的內核模塊時會出現錯誤,因爲Android SDK的自帶kernel中沒有把LKM功能打開,所以如果要開發內核模塊需要打開內核LKM功能並重新編譯,否則會出現以下錯誤(如果不想用LKM可以跳過此步)

    error: variable '__this_module' has initializer but incomplete type


    要解決這個問題需要配置內核選項,首先執行 

    $ make ARCH=arm CROSS_COMPILE=arm-eabi- menuconfig  

    進入內核配置界面,勾選下列選項
    [*] Enable loadable module support ---> (選中這一項,按空格即可)     
       [*] Forced module loading (選中上述一項,按回車即可看到此項)      
       [*] Module unloading 
            [*] Forced module unloading 





    保存內核配置後就可以用如下命令開始編譯
    $ make -j4
    如果編譯成功,最後編譯出來的內核會存在內核源下的/arch/arm/boot/中,名爲zImage。
    這時候就需要先配置一下環境變量來指定源碼,否則會出現如下錯誤:

    emulator: ERROR: You did not specify a virtual device name, and the system

    directory could not be found.

    爲了解決這個問題,我們需要配置兩個環境變量加入.bash_profile中:

    export ANDROID_BUILD_TOP=/Users/keenite/Android/Source
    export ANDROID_PRODUCT_OUT=/Users/keenite/Android/Source/out/target/product/generic

    然後使用$source ~/.bash_profile來更新環境變量,完成後我們就可以用如下命令來啓動模擬器並加載指定內核:

    $ emulator -kernel /Users/keenite/Android/GoldFish_Source/goldfish/arch/arm/boot/zImage

    啓動後可以從About Phone中看到內核信息:


    Section4: 加載內核模塊

    本部分主要參考:http://www.linuxidc.com/Linux/2011-05/35740.htm

    注意,爲了要加載內核模塊,必須要對我們的內核進行Section3中2部分的內核配置,打開LKM

    1. 編譯內核模塊

    先建立一個文件夾用於放代碼:

    $mkdir TestCode

    $cd TestCode

    然後Makefile與hello.c文件內容分別如下所示:

    Makefile

    KERNELDIR:=/Users/keenite/Android/GoldFish_Source/goldfish
    PWD:=$(shell pwd)
    ARCH=arm
    CROSS_COMPILE=/Users/keenite/Android/Source/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.6/bin/arm-eabi-
    CC=$(CROSS_COMPILE)gcc
    LD=$(CROSS_COMPILE)ld
    obj-m:=hello.o
    modules:
            $(MAKE) -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
    clean:
            rm *.o *.ko *.mod.c *.markers *.order *.symvers

    hello.c

    #include<linux/init.h>
    #include<linux/module.h>
    MODULE_LICENSE("Dual BSD/GPL");
    static int hello_init(void)
    {
            printk(KERN_ALERT "Hello World----------->\n");
            return 0;
    }
    static void hello_exit(void)
    {
            printk(KERN_ALERT "Good bye World.-------<\n");
    }
    module_init(hello_init);
    module_exit(hello_exit);
    然後在此文件夾中就可以使用make 命令來編譯模塊,不過這時要注意在Mac OS X中編譯會遇到以下錯誤:

    HOSTCC  scripts/mod/mk_elfconfig
    scripts/mod/mk_elfconfig.c:4:17: error: elf.h: No such file or directory

    因爲Mac的include文件少了一個elf.h
    從 http://download.csdn.net/detail/keenite/5830705中下載,放在scripts/mod目錄中, 然後再進行編譯即可。

    編譯完成後的hello.ko文件便是我們的內核模塊文件


    2. 將hello.ko放入手機中並加載

    使用命令:

    $adb push hello.ko /data/ 
    將模塊放入手機中的/data/文件夾下,若此時adb警告

    failed to copy 'hello.ko' to '/data/hello.ko': Read-only file system

    則使用adb remount後再push一次文件即可

    這時候使用:

    $adb shell

    命令進入模擬器控制檯,然後使用如下命令加載模塊

    #cd data

    #insmod hello.ko

    這時候我們可以用dmesg命令來查看當前手機中的內核打印信息,這時候能夠看到我們代碼中的打印信息


    用lsmod命令可以查看當前加載的模塊狀態,rmmod命令移除模塊

    當我們用

    #rmmod hello

    移除模塊後,用dmesg命令查看內核信息,可以看到模塊的移除信息



    In the case of Ubuntu12.04LTS the packages need to be installed are:

    $ sudo apt-get install git gnupg flex bison gperf build-essential \
      zip curl libc6-dev libncurses5-dev x11proto-core-dev \
      libx11-dev:i386 libreadline6-dev:i386 \
      libgl1-mesa-dev g++-multilib mingw32 tofrodos \
      python-markdown libxml2-utils xsltproc zlib1g-dev:i386
    Using libgl1-mesa-glx-lts-quantal:i386 in place of libgl1-mesa-glx:i386 

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