Ubuntu上搭建Android编译环境(3)
https://source.android.com/setup/build/running
运行版本
本页提供了关于在特定设备上运行编译系统的详细信息,是对编译准备工作部分的补充。
编译 fastboot 和 adb
如果您还没有 fastboot
和 adb
,则可以使用常规编译系统来编译。请按照编译准备工作中的说明操作,将主 make
命令替换为以下命令:
make fastboot adb
启动进入 fastboot 模式
Fastboot
是一种引导加载程序模式,您可以在该模式下刷写设备。 在设备冷启动过程中,可使用以下组合键进入 fastboot
模式:
设备 | 代号 | 组合键 |
---|---|---|
Pixel XL | marlin | 按住音量调低键,然后按住电源键。 |
Pixel | sailfish | 按住音量调低键,然后按住电源键。 |
hikey | hikey | 连接 J15 的引脚 1-2 和 5-6。 |
Nexus 6P | angler | 按住音量调低键,然后按住电源键。 |
Nexus 5X | bullhead | 按住音量调低键,然后按住电源键。 |
Nexus 6 | shamu | 按住音量调低键,然后按住电源键。 |
Nexus Player | fugu | 按住电源键。 |
Nexus 9 | volantis | 按住音量调低键,然后按住电源键。 |
Nexus 5 | hammerhead | 同时按住音量调高键和音量调低键,然后按住电源键。 |
Nexus 7 | flo | 按住音量调低键,然后按住电源键。 |
Nexus 7 3G | deb | 按住音量调低键,然后按住电源键。 |
Nexus 10 | manta | 同时按住音量调高键和音量调低键,然后按住电源键。 |
Nexus 4 | mako | 按住音量调低键,然后按住电源键。 |
Nexus 7 (2012) | grouper | 按住音量调低键,然后按住电源键。 |
Nexus 7 3G (2012) | tilapia | 按住音量调低键,然后按住电源键。 |
Nexus Q | phantasm | 启动设备,然后在 LED 指示灯亮起后用一只手盖住设备,直至指示灯变成红色。 |
Galaxy Nexus GSM | maguro | 同时按住音量调高键和音量调低键,然后按住电源键。 |
Galaxy Nexus (Verizon) | toro | 同时按住音量调高键和音量调低键,然后按住电源键。 |
Galaxy Nexus (Sprint) | toroplus | 同时按住音量调高键和音量调低键,然后按住电源键。 |
Motorola Xoom | wingray | 按住音量调低键,然后按住电源键。 |
Nexus S | crespo | 按住音量调高键,然后按住电源键。 |
Nexus SG | crespo4g | 按住音量调高键,然后按住电源键。 |
您还可以使用命令 adb reboot bootloader
直接在 Android 系统中重新启动进入引导加载程序,而无需使用任何组合键。
解锁引导加载程序
只有在引导加载程序允许的情况下,您才可以刷写定制系统,而引导加载程序默认处于锁定状态。您可以解锁引导加载程序,但这样做会导致系统出于保护隐私方面的考虑而删除用户数据。解锁之后,系统会清空设备上的所有数据,即应用中的个人数据以及可通过 USB 访问的共享数据(包括照片和影片)。请务必先备份设备上的所有重要文件,然后再尝试解锁引导加载程序。
您只需解锁引导加载程序一次即可,并可视需要将其重新锁定。
解锁新款设备
自 2014 年以来发布的所有 Nexus 和 Pixel 设备(从 Nexus 6 和 Nexus 9 开始)都内置有恢复出厂设置保护功能,需要通过多个步骤才能解锁引导加载程序。
- 要在设备上启用 OEM 解锁功能,请执行以下操作:
- 在“设置”中,点按关于手机,然后点按版本号七 (7) 次。
- 当看到“您已处于开发者模式”这条消息后,点按返回按钮。
- 点按开发者选项,然后启用 OEM 解锁和 USB 调试(如果 OEM 解锁处于停用状态,请连接到互联网,以便设备可以至少签到一次。如果 OEM 解锁仍处于停用状态,则说明您的设备可能已被运营商锁定 SIM 卡,系统无法解锁引导加载程序)。
- 重新启动进入引导加载程序,然后使用
fastboot
解锁。- 对于新款设备(2015 年及之后发布的设备):
fastboot flashing unlock - 对于老款设备(2014 年及之前发布的设备):
fastboot oem unlock
- 对于新款设备(2015 年及之后发布的设备):
- 在屏幕上确认解锁。
注意:在 Nexus 10 上,解锁引导加载程序后,内部存储空间仍将保持未格式化状态。您可以依次使用 fastboot format cache
和 fastboot format userdata
来格式化设备。
重新锁定引导加载程序
要重新锁定引导加载程序,请执行以下命令:
- 对于新款设备(2015 年及之后发布的设备):
fastboot flashing lock - 对于老款设备(2014 年及之前发布的设备):
fastboot oem lock
注意:在 Motorola Xoom 上重新锁定引导加载程序会清空用户数据(包括共享的 USB 数据)。
使用刷写解锁
getFlashLockState()
系统 API 会传输引导加载程序状态,PersistentDataBlockManager.getFlashLockState()
系统 API 会返回兼容设备上引导加载程序的锁定状态。
返回的值 | 条件 |
---|---|
FLASH_LOCK_UNKNOWN | 仅升级到 Android 7.x 或更高版本的符合以下条件的设备会返回此值:设备支持刷写锁定/解锁功能,但之前不支持获取刷写锁定状态所需的引导加载程序变更。
|
FLASH_LOCK_LOCKED | 不支持刷写锁定/解锁的设备(即设备始终处于锁定状态)或支持刷写锁定/解锁且处于锁定状态的设备应该会返回此值。 |
FLASH_LOCK_UNLOCKED | 支持刷写锁定/解锁且当前处于已解锁状态的设备会返回此值。 |
制造商应测试由已锁定/解锁引导加载程序的设备返回的值。例如,Android 开源项目 (AOSP) 包含根据 ro.boot.flash.locked
启动属性返回值的参考实现。示例代码位于以下目录中:
frameworks/base/services/core/java/com/android/server/PersistentDataBlockService.java
frameworks/base/core/java/android/service/persistentdata/PersistentDataBlockManager.java
选择设备编译系统
lunch
菜单中提供了建议的设备编译系统,在不使用任何参数的情况下运行 lunch
命令即可查看。 您可以从 developers.google.com 下载 Nexus 设备的出厂映像和二进制文件。请参阅设备二进制文件进行下载。有关详情以及其他资源,请参阅下载专有二进制文件。
设备 | 代号 | 编译配置 |
---|---|---|
Pixel XL | marlin | aosp_marlin-userdebug |
Pixel | sailfish | aosp_sailfish-userdebug |
HiKey | hikey | hikey-userdebug |
Nexus 6P | angler | aosp_angler-userdebug |
Nexus 5X | bullhead | aosp_bullhead-userdebug |
Nexus 6 | shamu | aosp_shamu-userdebug |
Nexus Player | fugu | aosp_fugu-userdebug |
Nexus 9 | volantis (flounder) | aosp_flounder-userdebug |
Nexus 5 (GSM/LTE) | hammerhead | aosp_hammerhead-userdebug |
Nexus 7 (WLAN) | razor (flo) | aosp_flo-userdebug |
Nexus 7(移动版) | razorg (deb) | aosp_deb-userdebug |
Nexus 10 | mantaray (manta) | full_manta-userdebug |
Nexus 4 | occam (mako) | full_mako-userdebug |
Nexus 7 (WLAN) | nakasi (grouper) | full_grouper-userdebug |
Nexus 7(移动版) | nakasig (tilapia) | full_tilapia-userdebug |
Galaxy Nexus (GSM/HSPA+) | yakju (maguro) | full_maguro-userdebug |
Galaxy Nexus (Verizon) | mysid (toro) | aosp_toro-userdebug |
Galaxy Nexus(试验版) | mysidspr (toroplus) | aosp_toroplus-userdebug |
Motorola Xoom(美国 WLAN 版) | wingray | full_wingray-userdebug |
Nexus S | soju (crespo) | full_crespo-userdebug |
Nexus S 4G | sojus (crespo4g) | full_crespo4g-userdebug |
注意:请不要在原本搭载 Android 4.1.2 或更高版本的 Nexus 7 上使用 Android 4.1.1。
刷写设备
您可以通过运行一个命令来刷写整个 Android 系统;这样做可验证正在刷写的系统与已安装的引导加载程序和无线通信模块的驱动程序是否兼容,还可以将启动、恢复和系统分区一起写入,然后重新启动系统。与 fastboot oem unlock
类似,刷写设备也会清空所有用户数据。
要刷写设备,请执行以下操作:
- 在启动时按住相应的组合键或使用以下命令使设备进入
fastboot
模式:
adb reboot bootloader - 在设备处于 fastboot 模式后,运行以下命令:
fastboot flashall -w-w
选项会清除设备上的/data
分区;该选项在您第一次刷写特定设备时非常有用,但在其他情况下则没必要使用。
注意:在 Motorola Xoom 上通过 fastboot
创建的文件系统无法发挥最佳作用。建议您使用 $ adb reboot recovery
命令通过恢复功能来重新创建文件系统。在执行恢复操作时,打开菜单(同时按电源键和音量调高键),擦除缓存分区,然后擦除数据。
将设备恢复到出厂状态
您可以在 Nexus 和 Pixel 设备的出厂映像上查看 Google 设备的出厂映像。Motorola Xoom 的出厂映像由 Motorola 直接提供。
https://source.android.com/setup/build/building-kernels
编译内核
本页详细介绍了如何仅编译内核。以下说明假设您尚未下载整个 AOSP;如果您已完成下载,则可以跳过 git clone
对应的步骤,但下载内核源代码的步骤除外。
本部分中的所有示例均使用 hikey 内核。
选择内核
此表列出了内核源代码和二进制文件的名称及所在位置:
设备 | 二进制文件所在的位置 | 源代码所在的位置 | 编译配置 |
---|---|---|---|
taimen | device/google/wahoo-kernel | kernel/msm | wahoo_defconfig |
walleye | device/google/wahoo-kernel | kernel/msm | wahoo_defconfig |
easel | N/A | kernel/arm64 | mnh_prod_defconfig |
marlin | device/google/marlin-kernel | kernel/msm | marlin_defconfig |
sailfish | device/google/marlin-kernel | kernel/msm | marlin_defconfig |
hikey | device/linaro/hikey-kernel | kernel/hikey-linaro | hikey_defconfig |
angler | device/huawei/angler-kernel | kernel/msm | angler_defconfig |
bullhead | device/lge/bullhead-kernel | kernel/msm | bullhead_defconfig |
shamu | device/moto/shamu-kernel | kernel/msm | shamu_defconfig |
fugu | device/asus/fugu-kernel | kernel/x86_64 | fugu_defconfig |
volantis | device/htc/flounder-kernel | kernel/tegra | flounder_defconfig |
hammerhead | device/lge/hammerhead-kernel | kernel/msm | hammerhead_defconfig |
flo | device/asus/flo-kernel/kernel | kernel/msm | flo_defconfig |
deb | device/asus/flo-kernel/kernel | kernel/msm | flo_defconfig |
manta | device/samsung/manta/kernel | kernel/exynos | manta_defconfig |
mako | device/lge/mako-kernel/kernel | kernel/msm | mako_defconfig |
grouper | device/asus/grouper/kernel | kernel/tegra | tegra3_android_defconfig |
tilapia | device/asus/grouper/kernel | kernel/tegra | tegra3_android_defconfig |
maguro | device/samsung/tuna/kernel | kernel/omap | tuna_defconfig |
toro | device/samsung/tuna/kernel | kernel/omap | tuna_defconfig |
panda | device/ti/panda/kernel | kernel/omap | panda_defconfig |
stingray | device/moto/wingray/kernel | kernel/tegra | stingray_defconfig |
wingray | device/moto/wingray/kernel | kernel/tegra | stingray_defconfig |
crespo | device/samsung/crespo/kernel | kernel/samsung | herring_defconfig |
crespo4g | device/samsung/crespo/kernel | kernel/samsung | herring_defconfig |
确定要使用的设备项目之后,请查看内核二进制文件的 Git 日志。设备项目采用 device/VENDOR/NAME
形式。
git clone https://android.googlesource.com/kernel/hikey-linaro
cd hikey-linaro
git log --max-count=1 kernel
内核二进制文件的提交消息中包含用于编译二进制文件的内核源代码的部分 Git 日志。该日志中的第一个条目是最新内容(也即用于编译内核的条目)。请记下提交消息,因为您在后续步骤中会用到该消息。
确定内核版本
要确定系统映像中使用的内核版本,请对内核文件运行以下命令:
dd if=kernel bs=1 skip=$(LC_ALL=C grep -a -b -o $'\x1f\x8b\x08\x00\x00\x00\x00\x00' kernel | cut -d ':' -f 1) | zgrep -a 'Linux version'
对于 Nexus 5 (hammerhead),请运行以下命令:
dd if=zImage-dtb bs=1 skip=$(LC_ALL=C od -Ad -x -w2 zImage-dtb | grep 8b1f | cut -d ' ' -f1 | head -1) | zgrep -a 'Linux version'
下载源代码
使用适当的 git clone
命令,下载您要编译的内核的源代码。例如,以下命令会克隆 common
内核(一种可自定义的通用内核):
git clone https://android.googlesource.com/kernel/common
内核项目的完整列表在 Kernel 目录下。以下是一些常用内核及其各自的 git clone
命令。
exynos
项目包含适用于 Nexus 10 的内核源代码,可用作在 Samsung Exynos 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/exynos
goldfish
项目包含适用于所模拟的平台的内核源代码。
git clone https://android.googlesource.com/kernel/goldfish
hikey-linaro
项目用于 HiKey 参考板,可用作在 HiSilicon 620 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/hikey-linaro
msm
项目包含适用于 ADP1、ADP2、Nexus One、Nexus 4、Nexus 5、Nexus 6、Nexus 5X、Nexus 6P、Nexus 7 (2013)、Pixel 和 Pixel XL 的源代码,可用作在 Qualcomm MSM 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/msm
omap
项目用于 PandaBoard 和 Galaxy Nexus,可用作在 TI OMAP 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/omap
samsung
项目用于 Nexus S,可用作在 Samsung Hummingbird 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/samsung
tegra
项目用于 Xoom、Nexus 7 (2012)、Nexus 9,可用作在 NVIDIA Tegra 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/tegra
x86_64
项目包含适用于 Nexus Player 的内核源代码,可用作在 Intel x86_64 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/x86_64
编译内核
当您了解了内核的最后一条提交消息并已成功下载内核源代码和预编译的 gcc 后,就可以编译内核了。以下编译命令使用了 hikey 内核:
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-android-
cd hikey-linaro
git checkout -b android-hikey-linaro-4.1 origin/android-hikey-linaro-4.1
make hikey_defconfig
make
要编译不同的内核,只需将 hikey-linaro
替换为您要编译的内核的名称即可。
映像会输出到 arch/arm64/boot/Image
目录;内核二进制文件会输出到 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dtb
文件。请将 Image
目录和 hi6220-hikey.dtb
文件复制到 hikey-kernel
目录。
或者,您可以在使用 make bootimage
(或编译启动映像的任何其他 make
命令行)时添加 TARGET_PREBUILT_KERNEL
变量。所有设备均支持该变量,因为它是通过 device/common/populate-new-device.sh
进行设置的。例如:
export TARGET_PREBUILT_KERNEL=$your_kernel_path/arch/arm/boot/zImage-dtb
已知问题
https://source.android.com/setup/build/known-issues
源代码同步问题
尽管我们一直万分谨慎,但 Android 源代码有时还是会出现一些小问题。本页详细介绍了您在尝试同步 Android 源代码时可能会遇到的一些已知问题。
同步源代码时遇到的问题(代理问题)
症状:repo init
或 repo sync
失败,并显示 HTTP 错误,通常为 403 或 500。
原因:有很多可能的原因,大多数情况下都与 HTTP 代理有关,这些代理无法顺利传输大量数据。
解决方法:虽然还没有通用的解决方法,但有人报告说使用 Python 2.7 以及明确使用 repo sync -j1
可以改善某些用户的情况。
同步源代码树时遇到的问题(DNS 问题)
症状:在运行 repo sync
时进程失败,并显示与无法识别主机名相关的各种错误。其中一种错误是 <urlopen error [Errno -2] Name or service not known>
。
原因:有些 DNS 系统难以应对同步源代码树时涉及的大量查询(在最糟糕的情况下,可能会有数百条查询请求)。
解决方法:手动解析相关主机名,并在本地对解析结果进行硬编码。
您可以使用 nslookup
命令解析主机名,该命令将为每个主机名指定一个数字 IP 地址(通常是在输出的“Address”(地址)部分)。
nslookup googlesource.com
nslookup android.googlesource.com
然后,您可以在本地对它们进行硬编码,方法是修改 /etc/hosts
,在该文件中添加两行内容,形式如下:
aaa.bbb.ccc.ddd googlesource.com eee.fff.ggg.hhh android.googlesource.com
请注意,这种方法只适用于服务器的地址不会更改的情况;如果服务器的地址发生更改,导致您无法连接,那么您必须重新解析这些主机名,并相应地修改 etc/hosts
。
同步源代码树时遇到的问题(TCP 问题)
症状:在同步时 repo sync
挂起,通常是在同步操作完成 99% 时出现这种情况。
原因:TCP/IP 堆栈中的某些设置在有些网络环境中会导致出现问题,使得 repo sync
既无法完成,也不会失败。
解决方法:在 Linux 中,请输入以下命令:
sysctl -w net.ipv4.tcp_window_scaling=0
在 MacOS 中,请在网络设置部分停用 rfc1323 扩展程序。