如何預編譯 Android 模擬器專用核心

weixin_34041003發表於2017-09-30

I. 輔助指令碼

我們現在提供了一個輔助指令碼來重新構建核心,其位於 $AOSP/prebuilts/qemu-kernel/build-kernel.sh

請確保使用了 aosp/master 的 checkout,而不是 aosp/studio-XXX 中的一個,後者不包含重新構建核心所需的預編譯目標工具鏈二進位制檔案。

你需要位於 android.googlesource.com/kernel/goldfish.git 的原始檔的分支 origin/android-goldfish-<version>,其中 <version> 為應用於你的系統映象的核心版本。

大致說來:

2.6.27 -> 任何 Gingerbread 之前的版本。(<= Android 2.2)
2.6.29 -> Gingerbread (2.3) 直到 JellyBean MR2 (4.2.x)
3.4 -> KitKat (4.4.x) 和 Lollipop 32 位 (5.0/5.1)
3.10 -> Lollipop 64 位和 Marshmallow (6.0)
3.18 -> 當前的實驗性版本。

此外,你需要選擇正確的 'config',其對應於你想要支援的虛擬的板子。當前有兩個可以考慮:

  • 傳統的虛擬板子稱為 'goldfish',對應於由傳統的 QEMU1 程式碼庫所支援的虛擬硬體。

  • 最新的虛擬板子稱為 'ranchu',對應於由 QEMU2 程式碼庫所支援的虛擬硬體。

它們之間的主要差別在於 'goldfish' 支援已經廢棄的 goldfish 特有 NAND 和 eMMC 虛擬裝置,它們在 QEMU2 中已經被 virtio-block 替代(為了好得多的效能和可靠性)。更多細節,請參考 android/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT

通過 --arch=<name> 選項來指定要為哪個架構編譯,其中 <name> 為模擬器的 CPU 架構名稱(比如 'arm','mips','x86','x86_64','arm64' 和 'mips64')中的一個。

每個架構都有預設的配置(典型的為 'goldfish'),你可以通過 --config=<name> 選項覆蓋它,其中 <name> 是位於 $KERNEL/arch/*/configs/ 下的子目錄的名字。

預設的輸出目錄將是 /tmp/kernel-qemu/<arch>-<kernel_version>/,但這可以通過 --out=<dir> 選項覆蓋。

預設情況下,指令碼將試圖從 $AOSP/prebuilts/gcc/ 找到一個適當的工具鏈,但是你可以使用 --cross=<prefix> 選項指定一個不同的。

檢視 build-kernel.sh --help 來了解更多選項和細節。

這裡是重新構建流行的核心配置的選項的列表:

Goldfish:

     32-bit ARMv7-A     --arch=arm
     32-bit i386        --arch=x86
     32-bit MIPS        --arch=mips
     64-bit x86_64      --arch=x86_64

Ranchu:

     32-bit ARMv7-A     --arch=arm --config=ranchu
     32-bit i386        --arch=x86 --config=i386_ranchu
     32-bit MIPS        --arch=mips --config=ranchu
     64-bit ARMv8       --arch=arm64
     64-bit x86_64      --arch=x86_64 --config=x86_64_ranchu
     64-bit MIPS        --arch=mip64 --config=ranchu

指令碼將在它的輸出目錄生成如下的檔案:

kernel-qemu            與 QEMU 一起使用的核心映象,使用模擬器的 '-kernel <file>' 選項來使用它,其中 `<file>` 為該檔案的路徑。

vmlinux-qemu           用於以 GDB 除錯核心的符號檔案(參考下文)。

LINUX_KERNEL_COPYING   核心的許可檔案,必須與二進位制檔案的每份拷貝一起提供。

README                 解釋如何編譯的小 README 檔案。、

II. 以 QEMU 除錯核心

在你需要除錯核心的情況下(比如檢查核心 panics),你可以執行下面的過程:

  1. 從原始碼重新構建核心(參考前面的小節)。

  2. 以特殊的選項啟動模擬器來使用新核心映象,啟動核心除錯,且不要啟動 vCPU 來等待 GDB:

         emulator -kernel /path/to/kernel-qemu \
                  <other-options> \
                  -qemu -s -S
  1. 在另一個終端裡,啟動一個 GDB 客戶端,它將 attach 到模擬器程式,讀取核心符號檔案之後:
         $AOSP/prebuilts/gdb/linux-x86/bin/gdb
         file /path/to/vmlinux-qemu
         target remote :1234
         b panic
         c

注意:位於 $AOSP/prebuilts/ 下的 gdb 版本支援所有的 Android 目標架構。你的 'host' gdb 可能只支援 x86/x86_64。

注意:你可以在使用 'c' 命令啟動執行之前用 'b' 命令打任意多個斷點。

一旦你命中了斷點,使用 'bt' 來列印棧追蹤。參考 GDB 手冊來了解更多資訊。

III. 從頭開始重新構建

如果你不想,或不能使用指令碼,這裡有一份手動的直到:

你需要在你的 path 中有一份適當的交叉工具鏈(比如,'arm-eabi-gcc --version' 必須能夠工作)

然後(對於版本2.6.29):

git clone https://android.googlesource.com/kernel/goldfish.git kernel-goldfish
cd kernel-goldfish
git checkout origin/android-goldfish-2.6.29

export CROSS_COMPILE=arm-eabi-
export ARCH=arm
export SUBARCH=arm
make goldfish_defconfig    # configure the kernel
make -j2                   # build it

=> 這將產生名為 arch/arm/boot/zImage 的檔案

注意:分支 android-goldfish-2.6.27 現在已經廢棄。不要使用它。

現在你可以這樣使用它:

  emulator -kernel path/to/your/new/zImage <other-options>

你可以通過在上面的指示中使用 goldfish_armv7_defconfig (而不是 goldfish_defconfig)來構建一個 ARMv7 相容的核心映象。注意,你將需要通過使用 -cpu cortex-a8 選項啟用 ARMv7 模擬,如下:

  emulator -kernel path/to/your/new/zImage <other-options> -qemu -cpu cortex-a8

如果你的核心映象的名字以 -armv7 結尾,則模擬器二進位制檔案將自動地為你啟用 ARMv7 模擬,因此執行下面的命令應該是等價的:

  emulator -kernel path/to/your/kernel-armv7 <other-options>

Voila !

原文 $QEMU/android/docs/ANDROID-KERNEL.TXT

相關文章