如何编译Android AOSP内核并在Android模拟器上测试?

56

有人成功编译过Android内核并在Android模拟器上进行了测试吗?如果有,是否需要特别注意什么?

SDK的文档非常好,但对于编译内核和在模拟器中设置自定义机器的文档对我来说很难找到。

8个回答

58
自2009年8月起,内核不再是Android开源项目中标准仓库清单的一部分。如果您按照下载Android开源项目源代码的说明进行操作,则需要以下步骤才能成功下载、构建和在模拟器上运行特定的内核:
- 获取Android内核,可以通过将其添加到您的仓库清单或手动运行以下命令来完成:
git clone https://android.googlesource.com/kernel/goldfish.git - 检出正确的分支以与模拟器配合工作,即goldfish:
git checkout -t origin/android-goldfish-2.6.29 -b goldfish - 生成模拟器配置(qemu模拟器运行arm代码,即arm配置):
make ARCH=arm goldfish_defconfig
如果不起作用,请尝试make ARCH=arm goldfish_armv7_defconfig - 现在使用开源项目分发的交叉编译工具构建内核:
make ARCH=arm CROSS_COMPILE=mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- - 以这种方式构建的内核应该位于内核树的arch/arm/boot文件夹中(您从git clone获取的代码所在的位置) - 要使用您的内核运行模拟器,有两个选择:要么将其复制到开源项目的预构建内核文件夹中以替换标准内核,要么使用设置内核选项启动模拟器:
emulator -kernel mydroid/kernel/common/arch/arm/boot/zImage 请注意,上述说明中我使用了默认路径,您需要将其更改为适用于您的设置。自上次测试以来已经过了一段时间,但我认为它应该可以工作。
一些额外信息: 在标准的Android开源分发版本中,内核作为预构建的二进制文件分布在mydroid/prebuilt/android-arm/kernel文件夹中,不包括源代码。据我所知,内核源代码从默认清单中删除有两个原因。一是它占用了大量带宽和磁盘空间,而大多数人不会与平台组件一起使用。另一个原因是由于内核是使用内核构建系统而不是作为aosp构建系统的一部分而构建的,因此将其保持分离是有意义的。内核的常见分支是模拟器使用的分支。还有实验、msm(高通平台)和Omap(TI平台)等分支,如果您想使用Android内核与硬件配合使用,则可能更有趣。

2
感谢提供额外的信息!由于大部分Android文档都是以Google群组讨论的形式存在,像这样的帖子非常有帮助。 - Mr. Shickadance
当我尝试下载内核源代码时,它给了我以下错误: “android.git.kernel.org[0: 149.20.4.77]: errno=Connection refused fatal: unable to connect a socket (Connection refused)”你能建议我下载源代码的替代路径吗? - CoDe
模拟器内核的位置在kernel.org宕机后移动到android.googlesource.com。我已经更新了帖子以确保正确性。 - BMB

20

仅纠正BMB帖子中的一些错误(对我非常有用,它拯救了我的项目):

  • git clone git://android.git.kernel.org/kernel/common.git(内核遗漏);
  • git checkout -t origin/android-goldfish-2.6.29 -b goldfish(相同);
  • make ARCH=arm goldfish_defconfig(相同);
  • make ARCH=arm CROSS_COMPILE=mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-(相同)
  • emulator -avd my_avd -kernel mydroid/kernel/common/arch/arm/boot/zImage(这里我在命令中添加了一个avd,否则对我无效)。


2
谢谢您提供额外的信息。我编辑了我的帖子,包括正确的内核路径,对此我很抱歉。 - BMB
如何使用预构建的/devtools/tools/android脚本添加多个AVD?它会出现错误“ava.lang.ClassNotFoundException: com.android.sdklib.repository.SdkRepoConstants”。 - Toral

17

在Ubuntu 17.10主机上完全自动化的Android 8.1客户端

# Download the source. Takes several minutes.
curl https://storage.googleapis.com/git-repo-downloads/repo >repo
chmod a+x repo
./repo init -b android-8.1.0_r1 --depth 1 -u https://android.googlesource.com/platform/manifest
./repo sync -c  -j $(($(nproc) - 2)) --no-tags --no-clone-bundle

# Do the actual build. Takes minutes / hours.
. build/envsetup.sh
lunch aosp_x86_64-eng
USE_CCACHE=1 CCACHE_DIR=ccache make -j $(($(nproc) - 2))

# Run the emulator.
emulator -show-kernel

out/目录占用约90GB,其余文件夹大约40GB(不包括CCACHE)。

开启模拟器后大约1-2分钟,主屏幕会显示:

如果在启动Android的主机终端上按回车键,则可以进入主机终端上的Android系统shell:

enter image description here

注意:

  • ./repo init -b必须指向一个标记。master分支总是出现问题,而-release分支也一样。

    标记的列表可以在此处找到:https://android.googlesource.com/platform/manifest,或通过克隆该仓库进行查找。

    分支总是出现问题可能有两个原因:

    • Android在“封闭门”之后进行开发,并且代码已公开发布。因此,Google和OEM开发人员已经在公共的“master”之上添加了许多补丁,并已经解决了这个问题。

      出于同样的原因,尝试在master上报告任何构建错误可能是无用的:它们已经被报告并修复。此外,我敢你找到正确的官方报告构建失败的地方。

    • repo sync只是拉取给定分支AOSP所组成的所有650个git存储库的最新版本,而不像子模块那样进行同步。因此,不能保证它们兼容。但标记将获取所有存储库的特定标记。

  • --depth 1sync -c --no-tags --no-clone-bundle旨在加快缓慢的克隆速度。不确定是否成功。另请参见:AOSP repo sync takes too long

  • 我们使用lunch aosp_x86_64-eng而不是ARM,因为它运行更快,因为它具有主机x86虚拟化扩展,包括KVM

    如果要构建ARM版本,请改用lunch aosp_arm-eng

此外,ARM映像可能存在缺陷,可能是由于速度过慢导致的?当GUI启动(如果你很幸运),它会显示“系统UI无响应”。另见:在Android模拟器中进程系统无响应

理论上,在Java / C ++本地API中执行的所有“通常的高级操作”在x86和ARM上都应该同样有效,因此除非你足够强大并手动触摸某些汇编代码,否则不应该有任何问题。

-show-kernel将终端连接到串口,即可以看到引导消息,并在最后获得一个shell,这对于调试非常有用。

type emulator显示它只是emulator的别名,没有任何参数。在Android模拟器上运行自定义ROM询问如何传递一些参数以显式选择您的ROM。

令人惊讶的是,模拟器-help目标的见解:

emulator -help
emulator -help-build-images
emulator -help-disk-images

您可以通过以下方式确定给定的QEMU命令行参数:

emulator -verbose | grep 'emulator: argv'

如下所述:如何在启动Android模拟器时显示传递给QEMU的选项?

这显示了一些自定义选项,例如-android-hw,因此它们必须已经分叉了QEMU:QEMU vs Android emulator: command line options。源代码每5分钟移动一次位置:修改Android模拟器源代码


1
@Gleichmut 我刚刚确认了,只有emulator在我的构建中有效,模拟器GUI出现了。你在运行emulator之前是否在shell上运行了. build/envsetup.shlunch aosp_x86_64-eng两个命令? - Ciro Santilli OurBigBook.com
是的,我做到了。我成功运行了ARM镜像,但x86仍然存在问题。 - Gleichmut
1
下载源代码。需要几分钟时间。在我的家庭连接上,镜像花费了将近2880分钟的时间 :-) - Olaf Dietsche
@OlafDietsche 嗯,那是在我家的38Mbps网络下,我很确定它没有超过一个小时。 - Ciro Santilli OurBigBook.com
我猜,区别在于下载整个镜像与仅使用“--depth=1”下载分支。 - Olaf Dietsche
显示剩余3条评论

8
截至2012年,在source.google.com上下载内核的方法已经得到了充分的记录,但是我发现编译需要尝试几次。以下是我用于为ARM模拟器构建内核的命令:
cd /kernel/source/root
make mrproper
adb pull /proc/config.gz # from the emulator
gunzip config
mv config .config  # now you have a (perhaps slightly outdated kernel .config)
make ARCH=arm silentoldconfig # update the .config - take the defaults if prompted
make ARCH=arm menuconfig # make any further changes
time make -j4 ARCH=arm CROSS_COMPILE=/path/to/android/source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- 2>&1 | tee ../../logs/$(date +%Y%m%d-%H%M)-make-kernel.log
emulator -kernel /kernel/source/root/kernel/goldfish/arch/arm/boot/zImage -avd myAVD &

感谢所有回答这个问题的人,我通过这个答案的一些片段得以完成它。Amaund的“你需要AVD”是最后一个让我困扰的地方。

非常感谢,那帮了我很多。不过你的代码中有一个小错别字。应该是 make ARCH=arm menuconfig 而不是 make ARCM=arm menuconfig。我是通过盲目复制粘贴发现这个问题的,结果得到了一个 x86 内核 ;-) - Diego Medaglia

8

这是对BMB和Arnaud LM答案的更新。
看起来金鱼分支的名称在2011/03/03发生了变化。 当检查金鱼分支时,请使用以下内容:

git checkout -t origin/archive/android-gldfish-2.6.29 -b goldfish 

请注意android-gldfish-2.6.29中缺少了一个'o'!希望这能为某些人节省时间。

6
那很简单。按照http://source.android.com/download上的说明获取和编译整个Android源代码。这需要一些时间,但并不复杂。
通过构建,您将在<android>/out目录中获得输出。除了ROM映像之外,还包括一堆工具,包括模拟器。我的模拟器位于<android>/out/host/linux-x86/bin/emulator。只需设置一个名为ANDROID_PRODUCT_OUT的环境变量为<android>/out/target/product/generic,然后运行模拟器而不带任何选项即可运行已编译的ROM。

我们不是在寻求编译模拟器,而是专门寻求编译Android内核,并将编译后的映像在模拟器中运行。 - Zyris Development Team
这是运行Android源代码编译后的镜像的方法。我每天都在做这个。你只需要编译Android源代码,就可以得到一个模拟器来运行它。 - Mostafa
2
正如我们之前所说的那样,我们不是在寻求编译模拟器的源代码。我们正在寻求编译ANDROID KERNEL(http://android.git.kernel.org/)。 - Zyris Development Team
这个回答仍然对我有帮助 :) - Sungwon Jeong

4
截至2012年5月,我发现您不能使用“goldfish_defconfig”来编译内核。您需要使用“goldfish_armv7_defconfig”。这就解释了为什么JonnyLambada从模拟器中提取配置(预先构建的内核)的方法有效且必要。
“goldfish_defconfig”将内核配置为在ARM 926处理器上运行,但模拟器配置为作为Coretex A8运行(这是一个ARM V7 CPU)。因此,如果您想让它工作(或者从模拟器中提取配置),则需要使用更新的defconfig。
仅供参考。

1

我编译的AOSP rom能够成功启动的方法是将编译生成的system.img复制到~/.android/avd/Froyo.avd/目录下。 但是,当我解压system.img并添加root权限的su和busybox之后,再重新创建system.img时,模拟器无法启动。我仍在努力解决这个问题 :S


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接