执行环境:Ubuntu 20.04 LTS,Python 3.8.2
参照文档:https://blog.csdn.net/zz531987464/article/details/94163954
目的:并不是要 ROM 本身,而是期望创建一个比 NDK 更强的 native 开发环境
1. 下载 repo
1 2 3 4 5 6 |
mkdir ~/bin PATH=~/bin:$PATH cd ~/bin curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo chmod +x repo export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/' |
2. 在 Google 官方网站(https://source.android.com/setup/start/build-numbers)上找 Pixel XL 所对应的 Android 版本标记
手持一台已经解锁 bootloader 且系统为 Android 10 的 Pixel XL,在上述网址表内的 Build 栏找到对应的源码版本是 QP1A.191005.007.A1,源码 Tag 为 android-10.0.0_r5,此 Tag 在下载 AOSP 源码时要用到。
3. 下载 AOSP 源码
在合适的位置新建目录用于存放源码并下载。
1 2 3 4 |
mkdir android-10.0.0_r5-marlin cd android-10.0.0_r5-marlin repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-10.0.0_r5 repo sync -j4 |
sync 并发数量镜像站有说明,不宜太高,不然有可能出现 sync 报错的情况,这里建议选择 -j4。后面出现需要选 y/N 时,选择 y 即可。然后耐心等待,出错退出的话再执行上述最后一条命令直到成功即可。
4. 下载对应版本的 Binary Drive(地址:https://developers.google.com/android/drivers#marlinqp1a.191005.007.a1)
下载 Binary Drive 需要知道对应的细分版本号,也即上面的 QP1A.191005.007.A1
,它也可用 cat build/core/build_id.mk
命令看到。
点击 Link 会下载到两个 .tgz 压缩包,解压后是两个 .sh 脚本,extract-google_devices-marlin.sh
和 extract-qcom-marlin.sh
。将其放到源代码根目录下并执行,看完许可协议后按照要求输入:I ACCEPT,最终 binary 会自动下载到 vendor 目录,至此所有的 AOSP 代码下载完成。
4. 编译 AOSP 源码
4.1 编译环境搭建
因为本机之前已经有部分编译需要的工具安装于其上(ccache
、curl
、git
、gnupg
、m4
、zip
、unzip
、build-essential
、bison
、flex
、gperf
、xsltproc
、dpkg-dev
、gcc-multilib
、g++-multilib
、lib32ncurses5-dev
、lib32z-dev
、libc6-dev-i386
、libgl1-mesa-dev
、libx11-dev
、libxml2-utils
、x11proto-core-dev
、zlib1g-dev
),因此只执行了以下组件的安装:
1 2 |
sudo apt install -y python-markdown tofrodos libncurses5-dev:i386 libreadline6-dev:i386 libsdl1.2-dev libx11-dev:i386 zlib1g-dev:i386 sudo apt install -y libesd0-dev |
其中 libesd0-dev
在 Ubuntu 20.04 LTS 的默认仓库里没有,需要把 deb http://cn.archive.ubuntu.com/ubuntu/ xenial main universe
添加到 apt 的源文件里,update 后再安装。
4.2 安装 OpenJDK
本机已经安装了 Oracle 的 JDK 8,因此略过未执行。
1 |
sudo apt install openjdk-8-jdk |
安装完以后,执行 sudo vi /etc/profile
添加 JAVA_HOME
相关配置。在打开的 profile 文件的末尾添加下面的内容:
1 2 3 4 |
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH |
使用 source /etc/profile
使环境变量配置立即生效。
使用 java -version
检查是否 JDK 已生效,检测到版本说明安装成功,接下来可以开始编译代码了。
4.3 编译代码
根据其它零散文档,预防性执行了 sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
和 export LC_ALL=C
。然后,
1 2 3 |
source build/envsetup.sh lunch # 选择 15. aosp_marlin-userdebug make -j4 |
第一次编译从晚上 11:40 分左右开始,历时 7 时 6 分后出错、失败、退出。出错步骤为 failed //frameworks/base:system-api-stubs-docs Metalava [common]
。光看信息没有头绪,搜索到了 https://stackoverflow.com/questions/58886407/aosp-ninja-build-stopped-subcommand-failed,参考后把开着的 Firefox 和 Chrome 都退出,再次执行 make
,把 -j4
调整为 -j2
,这第二次编译历时 1 小时后成功。
》当前进度至此《
5. 拉取 kernel 代码并编译
根据前面的方法拉取编译的 AOSP 代码中是不包含 kernel 源码的,而是一个已经编译好的内核镜像文件。如果需要修改编译 kernel 源码,需要单独拉取 kernel 的代码进行编译。
地址:https://source.android.com/setup/build/building-kernels#id-version
从上表中我们可以看到,Pixel XL 的 kernel 镜像在 AOSP 的目录为 device/google/marlin-kernel
,同时可以看到分支名称为 android-msm-marlin-3.18-pie-qpr2
。
拉取代码的命令为:
1 2 3 |
git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git cd msm git checkout remotes/origin/android-msm-marlin-3.18-pie-qpr2 |
5.1 编译 kernel 源码
首先在 AOSP 源码目录下 source build/envsetup.sh
,lunch aosp_marlin-userdebug
一下,用于启动一些编译时所需要的环境变量,例如:交叉编译工具等。
然后修改 kernel 源码根目录下的 Makefile。git diff
记录如下:
1 2 3 4 5 6 7 |
-ARCH ?= $(SUBARCH) -CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) +#ARCH ?= $(SUBARCH) +#CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) +ARCH ?= arm64 +CROSS_COMPILE ?= aarch64-linux-android- +CROSS_COMPILE_ARM32 ?= arm-linux-androideabi- |
编译命令:
1 2 |
make marlin_defconfig make -j4 |
如果有编译报错,则安装如下工具 sudo apt-get install liblz4-tool
。最终在 arch/arm64/boot
下生成了 Image.lz4-dtb
内核镜像文件。
5.2 整合 Image.lz4-dtb 文件到 AOSP 目录下
将 arch/arm64/boot/Image.lz4-dtb
文件复制到 AOSP 的 device/google/marlin-kernel
目录下,然后在 AOSP 源码根目录下执行 make bootimage
生成最终的 boot.img
即可。
注:[100% 2/2] Target boot image from recovery: out/target/product/marlin/boot.img
cp: 无法获取 ‘out/target/product/marlin/root/init.recovery.*.rc’ 的文件状态(stat): 没有那个文件或目录
编译报错可以忽略,没什么大的关系。
6. 刷机烧录镜像
解锁指导:https://source.android.com/setup/build/running#unlocking-the-bootloader。
重启到 bootloader:adb reboot bootloader
;然后解锁手机:fastboot flashing unlock
。
刷入镜像前先双清一下:
1 2 |
fastboot erase cache fastboot erase userdata |
刷入编译的所有镜像:fastboot flashall -w
。其具体刷入的流程日志为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
Sending 'boot_a' (31137 KB)... OKAY [ 1.051s] Writing 'boot_a'... OKAY [ 0.269s] Erasing 'system_a'... OKAY [ 0.344s] Sending sparse 'system_a' 1/2 (524284 KB)... OKAY [ 16.351s] Writing 'system_a' 1/2... OKAY [ 3.407s] Sending sparse 'system_a' 2/2 (516084 KB)... OKAY [ 16.652s] Writing 'system_a' 2/2... OKAY [ 3.349s] Erasing 'system_b'... OKAY [ 0.252s] Sending 'system_b' (74524 KB)... OKAY [ 2.446s] Writing 'system_b'... OKAY [ 0.565s] Erasing 'vendor_a'... OKAY [ 0.103s] Sending 'vendor_a' (267100 KB)... OKAY [ 8.553s] Writing 'vendor_a'... OKAY [ 1.750s] Setting current slot to 'a'... OKAY [ 0.087s] Erasing 'userdata'... OKAY [ 1.708s] Sending 'userdata' (4316 KB)... OKAY [ 0.238s] Writing 'userdata'... OKAY [ 0.110s] Rebooting... |
单独刷入某个 img:
1 2 3 4 5 6 7 |
cd out/target/product/marlin fastboot flash boot_a boot.img fastboot flash boot_b boot.img fastboot flash system system.img fastboot flash system_b system_other.img fastboot flash vendor vendor.img fastboot flash userdata userdata.img |
刷入完后执行 fastboot reboot
重启手机即可。
打开 Settings,查看“关于手机”,显示的版本号和内核版本号都是我们自己编译出来的:
7. 链接
- Google 设备官方代号标记和细分版本:https://source.android.com/setup/start/build-numbers
- Google 设备 Binary Drive 下载地址:https://developers.google.com/android/drivers
- AOSP 清华镜像站地址:https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/
- Android kernel 地址:https://source.android.com/setup/build/building-kernels#id-version
根据国情,首选从清华镜像站上下载 Android 源代码。Google 官网即使有梯子也很慢,清华镜像站下载速度还是很快的。
永久链接
源码编译过程中的那个退出,网上有其他人也遇到了,不知是谁,反正把一份一模一样的记录放到了 pastebin 上:https://pastebin.com/kb7HzMzc。