0%

Android - AOSP源码编译和调试

前言

1.什么是AOSP?
https://source.android.com/

学习AOSP有什么用?

  • 解决问题
  • 个人提升

黑科技

  • Magisk

原理在系统boot时将其img挂载到自己的分区下,构建一个虚拟文件系统,和system分区无关,以不修改系统文件为前提,从而达到修改系统文件的效果;aosp编译的root镜像需要删除system/bin/su

  • Xposed

原理就是替换安卓系统的app_process文件(system/bin/app_process),从而实现对系统的接管,通过回调模块的方式来达到不用修改APK就能改变其表现行为的目的。用通俗的话来说就是在任意进程启动之前,能加载特定Xposed模块的代码,从而控制任意进程的行为。这些特定的Xposed模块,能在App进程启动之前执行特定代码。感兴趣的可以看 app_process启动进程

  • SuperSU

1.下载

网址:https://source.android.com/setup/downloading

源码下载

1.1 mac环境配置

  • 创建区分大小写的磁盘镜像

    1
    2
    3
    4
    5
    6
    7
    8
    #创建 最好200G 亲测构建+编译 180g
    hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 200g ~/android.dmg
    #修改
    hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage
    # 挂载 .zshrc/.bash_profile
    mountAndroid() { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }
    # 卸载
    umountAndroid() { hdiutil detach /Volumes/android; }
  • 更多细节查看 https://source.android.com/setup/initializing#setting-up-a-mac-os-x-build-environment

  • 有条件的最好用ubuntu,空间大,问题少,编译快

1.2 repo安装

repo是Google开发的用于管理Android版本库的一个工具。repo并不是用来取代Git,而是用Python对Git进行了一定的封装,简化了对多个Git版本库的管理。对应repo管理的任何一个版本库,都需要使用Git命令进行操作。类似高德的mk工具

https://gerrit.googlesource.com/git-repo

1
brew install repo

1.3 确定分支

分支地址:https://android.googlesource.com/platform/manifest

驱动地址:https://developers.google.com/android/drivers

1.3.1 驱动查询

地址:https://developers.google.com/android/drivers

下图为Pixel 4xl 对应的可选硬件设备img

机型:Pixel4xl Android版本:11 版本号:RQ2A.210305.006 Link:硬件img下载地址

1.3.2 分支查询

地址:https://android.googlesource.com/platform/manifest

打开页面后是一个Branch(tag)列表,打开每个分支查看Android版本号,如果正好和第一步中的版本号相同,那么此分支可以作为目标分支下载;
备注:选择分支时的一个技巧,可以根据选择驱动的顺序选择分支,如果驱动版本靠后,选择分支时也从高版本分支往前查看

1.4 下载

1.4.1 初始化

1
2
3
4
5
6
7
8
# 进入镜像目录
cd /Volumes/android
# 创建aosp根目录
mkdir aosp
# 进入aosp根目录
cd aosp
# 下载 manifest 文件
repo init -u https://android.googlesource.com/platform/manifest -b android-11.0.0_r32
  • revision:分支
  • path: 本地目录
  • name: 源端目录,会将源端name目录的revision分支映射到本地path目录

1.4.3 Sync

1
repo sync

2.驱动下载

2.1 下载驱动

2.2 下载完成

解压并复制到aosp根目录

2.3 驱动安装(可以等下载完成后编译阶段执行)

1
2
sh extract-gooxxx.sh
sh extract-qcomxxx.sh

备注:执行sh,需要一直按enter键盘,最后输入I ACCEPT (8. e. //8小节中的e条款为最后一条)

2.编译

https://source.android.com/setup/building

环境:java_home,make ,xcode ,python

2.1 驱动安装

同上

2.2 设置环境

1
➜ . build/envsetup.sh 

向终端导出快捷指令(mm,mma,mmm,mmma,lunch等),类似配置环境变量的作用

2.3 选择编译类型

  • lunch

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    ➜  lunch

    You're building on Darwin

    Lunch menu... pick a combo:
    1. aosp_arm-eng
    2. aosp_arm64-eng
    14. aosp_coral-userdebug
    15. aosp_crosshatch-userdebug
    16. aosp_flame-userdebug
    17. aosp_marlin-userdebug
    18. aosp_sailfish-userdebug
    19. aosp_sargo-userdebug
    20. aosp_taimen-userdebug
    21. aosp_walleye-userdebug
    22. aosp_walleye_test-userdebug
    ...

    Which would you like? [aosp_arm-eng] //输入数字
  • 或者lunch aosp_coral-eng

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
➜  lunch aosp_coral_eng

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=10
TARGET_PRODUCT=aosp_coral
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv8-a
TARGET_2ND_CPU_VARIANT=generic
HOST_ARCH=x86_64
HOST_OS=darwin
HOST_OS_EXTRA=Darwin-20.3.0-x86_64-11.2.3
HOST_BUILD_TYPE=release
BUILD_ID=QQ2A.200405.005
OUT_DIR=out
PRODUCT_SOONG_NAMESPACES=hardware/google/av hardware/google/interfaces hardware/google/pixel device/google/coral hardware/qcom/sm8150 hardware/qcom/sm8150/display vendor/google/airbrush/floral vendor/google/biometrics/face vendor/google/camera vendor/google/darwinn vendor/qcom/sm8150 vendor/qcom/sm8150/codeaurora/telephony/ims vendor/qcom/sm8150/proprietary/qcril-data-hal/qdp vendor/qcom/sm8150/proprietary/qcril-data-hal/util vendor/qcom/sm8150/proprietary/qcril-data-hal/datamodule vendor/qcom/sm8150/proprietary/qcril-hal vendor/google/interfaces
============================================
  • user,user-debug,eng 区别
模式 区别
user 权限受限;适用于生产环境
userdebug 与“user”类似,但具有 root 权限和可调试性;是进行调试时的首选编译类型
eng 具有额外调试工具的开发配置

2.4 编译

1
make  -j12
1
2
3
4
5
➜ sysctl hw | grep -E "logicalcpu|physicalcpu"
hw.logicalcpu: 12
hw.logicalcpu_max: 12
hw.physicalcpu: 6
hw.physicalcpu_max: 6

3.刷机

工具:adb,fastboot

3.1 配置环境变量

1
2
3
4
# /Volumes/android/aosp 为aosp下载目录      out/target/product/coral 为编译生成目录
export ANDROID_PRODUCT_OUT=/Volumes/android/aosp/out/target/product/coral
# 执行fastboot flashall 时需要指定 // Flash all partitions from $ANDROID_PRODUCT_OUT.
# 感兴趣的同学可以查看fastboot.cpp文件探究为什么必须设置(/aosp/system/core/fastboot/fastboot.cpp)

3.2 进入bootloader模式

1
2
➜  adb reboot bootloader
# adb reboot 源码 /aosp/system/core/adb/client/main.cpp -> commandline.cpp

3.3 一键刷机

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
➜  fastboot flashall -w
--------------------------------------------
Bootloader Version...: c2f2-0.3-6863466
Baseband Version.....: g8150-00075-201008-B-6891495
Serial Number........: 92JBA03129
--------------------------------------------
Checking 'product' OKAY [ 0.069s]
Setting current slot to 'a' OKAY [ 0.152s] // 当前是a/b分区的a slot
Sending 'boot_a' (65536 KB) OKAY [ 1.820s]
Writing 'boot_a' OKAY [ 0.392s]
Sending 'dtbo_a' (8192 KB) OKAY [ 0.320s]
Writing 'dtbo_a' OKAY [ 0.111s]
Sending 'vbmeta_a' (8 KB) OKAY [ 0.140s]
Writing 'vbmeta_a' OKAY [ 0.077s]
Sending 'vbmeta_system_a' (4 KB) OKAY [ 0.140s]
Writing 'vbmeta_system_a' OKAY [ 0.077s]
Rebooting into fastboot OKAY [ 0.070s]
< waiting for any device > // 手机重启阶段
Sending 'super' (4 KB) OKAY [ 0.002s]
Updating super partition OKAY [ 0.022s]
Resizing 'product_a' OKAY [ 0.003s]
Resizing 'system_a' OKAY [ 0.003s]
Resizing 'system_ext_a' OKAY [ 0.003s]
Resizing 'system_b' OKAY [ 0.005s]
Resizing 'vendor_a' OKAY [ 0.006s]
Resizing 'vendor_b' OKAY [ 0.003s]
Resizing 'product_a' OKAY [ 0.005s]
Sending 'product_a' (227844 KB) OKAY [ 5.806s]
Writing 'product_a' OKAY [ 1.205s]
Resizing 'system_a' OKAY [ 0.003s]
Sending sparse 'system_a' 1/3 (262140 KB) OKAY [ 6.763s]
Writing 'system_a' OKAY [ 1.322s]
Sending sparse 'system_a' 2/3 (262140 KB) OKAY [ 7.041s]
Writing 'system_a' OKAY [ 1.372s]
Sending sparse 'system_a' 3/3 (190736 KB) OKAY [ 5.174s]
Writing 'system_a' OKAY [ 1.018s]
Resizing 'system_ext_a' OKAY [ 0.005s]
Sending 'system_ext_a' (110584 KB) OKAY [ 2.884s]
Writing 'system_ext_a' OKAY [ 0.609s]
Resizing 'system_b' OKAY [ 0.005s]
Sending 'system_b' (60 KB) OKAY [ 0.003s]
Writing 'system_b' OKAY [ 0.030s]
Resizing 'vendor_a' OKAY [ 0.004s]
Sending sparse 'vendor_a' 1/4 (262140 KB) OKAY [ 6.994s]
Writing 'vendor_a' OKAY [ 1.324s]
Sending sparse 'vendor_a' 2/4 (262140 KB) OKAY [ 6.756s]
Writing 'vendor_a' OKAY [ 1.350s]
Sending sparse 'vendor_a' 3/4 (262140 KB) OKAY [ 7.118s]
Writing 'vendor_a' OKAY [ 1.329s]
Sending sparse 'vendor_a' 4/4 (98888 KB) OKAY [ 2.667s]
Writing 'vendor_a' OKAY [ 0.566s]
Erasing 'userdata' OKAY [ 17.670s]
Erase successful, but not automatically formatting.
File system type raw not supported.
Erasing 'metadata' OKAY [ 0.019s]
Erase successful, but not automatically formatting.
File system type raw not supported.
Rebooting OKAY [ 0.000s]
Finished. Total time: 101.982s

3.4 单步刷机

1
➜  fastboot flash boot_a boot.img

4.模块编译

4.1 aapt https://github.com/JuneLeo/aapt-modify-resource

1
2
3
4
➜  . build/envsetup.sh
➜ cd frameworks/base/tools/aapt
➜ mm
# 生成文件 out/host/(windows | linux)/bin/aapt mac生成(darwin/windows)aapt , linux生成(linux/windows)

4.2 framework (Android SDK)

1
2
3
4
➜  cd /framework/base  
➜ mm
# 生成文件 out/target/product/coral/system/framework/framework.jar
➜ adb push out/target/product/generic/system/framework/framework.jar /system/framework/

4.3 services (AMS,PMS,WMS等服务)

1
2
3
4
➜  cd /framework/base/services 
➜ mm
# 生成文件 out/target/product/coral/system/framework/services.jar
➜ adb push out/target/product/generic/system/framework/services.jar /system/framework/

4.4 framework-res (framework res和Manifest.xml)

1
2
3
➜  cd /frameworks/base/core/res  
➜ mm
➜ adb push out/target/product/coral/system/framework/framework-res.apk /system/framework/

4.5 launcher3

1
2
3
4
➜  cd packages/apps/Launcher3 
➜ mm
➜ adb install -r out/target/product/coral/obj/APPS/Launcher3QuickStep_intermediates/package.apk
# quick step是带 recent的

Launcher保留一组flavor,编译很快

5.调试

5.1 方式一

5.1.1 idegen.jar

1
2
➜  source build/envsetup.sh
➜ mmm development/tools/idegen/

5.1.2 android.iml 和 android.ipr

1
2
➜  sh development/tools/idegen/idegen.sh
# 一定要在根目录下执行 生成 android.ipr ,从下图中可以看出 ipr文件会被AS识别

5.1.3 源码导入AS和配置

直接打开android.ipr即可

导入项目

设置一个android sdk版本,有sdk才可构建android项目,灰色debug才可点击

删除jdk和sdk的路径,防止debug进入jdk和sdk源码中

点击下方+,导入需要建立索引的目录

注意断点如果进入JDK或者SDK源码中,请重新看上面三张图

5.1.4 调试

设置断点,调试开始

5.2 方式二

5.2.1使用idegen生成android项目或者直接打开aosp项目

5.2.2 打开AS - Edit Configuration - add Remote

5.2.3 打开Monitor 选中要调试的进程,debug后选中的进程后面会显示一个绿色的蜘蛛(图片来自网络)

5.2.4 在AS中Debug 5005端口调试(非 attach debugger to android process)

6.补充

6.1 Could not find a supported mac sdk: [“10.10” “10.11” “10.12” “10.13” “10.14”]

mac sdk 下载地址:https://github.com/phracker/MacOSX-SDKs/releases

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
➜  ~ xcode-select -p
/Library/Developer/CommandLineTools
#ios 有的是这个目录
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs

➜ ~ sudo ln -sfn MacOSX10.14.sdk/ MacOSX11.3.sdk
➜ ~ ls
lrwxr-xr-x 1 root wheel 15 5 14 10:53 MacOSX11.3.sdk -> MacOSX10.14.sdk

➜ ~ vim /Volumes/android/aosp/build/soong/cc/config/x86_darwin_host.go
# 修改为11.3,欺骗aosp构建,使用的 sdk还是 10.14
darwinSupportedSdkVersions = []string{
"10.10",
"10.11",
"10.12",
"10.13",
"10.14",
"11.3",
}

6.2 创建区分大小写的磁盘镜像

参考:https://source.android.com/setup/initializing#optimizing-a-build-environment

1
2
3
4
5
6
7
8
#创建
hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 200g ~/android.dmg
#修改
hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage
# 挂载 .zshrc/.bash_profile
mountAndroid() { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }
# 卸载
umountAndroid() { hdiutil detach /Volumes/android; }

6.3 too many open files error

1
ulimit -S -n 1024  //设置文件描述符数量上限

6.4 刷机找不到系统SHARE_LIBRARY中的 xxx.so

  • adb root / adb remount
  • adb push 我们可以将so push 到 system/lib system/lib64
  • so名称写入public.libraries.txt中 /system/etc/public.libraries.txt

6.5 system/core/base/cmsg.cpp:78:21: error: use of undeclared identifier ‘PAGE_SIZE’if (cmsg_space >= PAGE_SIZE)

6.6 mac 锁屏后是否可以继续编译?

6.7 fastboot -h

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
➜  fastboot -h
usage: fastboot [OPTION...] COMMAND...

flashing:
update ZIP Flash all partitions from an update.zip package. // 可以刷一个官方zip
flashall Flash all partitions from $ANDROID_PRODUCT_OUT. //这里也提示需要设置ANDROID_PRODUCT_OUT 环境变量
On A/B devices, flashed slot is set as active. //刷镜像的卡槽为当前我们使用的卡槽
Secondary images may be flashed to inactive slot.
flash PARTITION [FILENAME] Flash given partition, using the image from //单刷镜像 fastboot flash boot_a boot.img
$ANDROID_PRODUCT_OUT if no filename is given.

basics:
devices [-l] List devices in bootloader (-l: with device paths). //类似 adb devices
getvar NAME Display given bootloader variable.
reboot [bootloader] Reboot device. //类似 adb reboot bootloader

locking/unlocking:
flashing lock|unlock Lock/unlock partitions for flashing //解锁oem

options:
-w Wipe userdata. // 全清
--slot SLOT Use SLOT; 'all' for both slots, 'other' for
non-current slot (default: current active slot).
--set-active[=SLOT] Sets the active slot before rebooting. //切换分区(a/b)

6.8 编译问题

1
2
/bin/bash: line 1: 42907 Segmentation fault: 11  ( out/host/darwin-x86/bin/treble_sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/coral/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/coral/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -f out/target/product/coral/obj/ETC/product_file_contexts_intermediates/product_file_contexts -b out/target/product/coral/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/coral/obj/ETC/treble_sepolicy_tests_26.0_intermediates/26.0_mapping.combined.cil -o out/target/product/coral/obj/ETC/treble_sepolicy_tests_26.0_intermediates/built_26.0_plat_sepolicy -p out/target/product/coral/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/coral/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil )
14:00:03 ninja failed with: exit status 1

解决:https://blog.csdn.net/yao_zhuang/article/details/106910345

6.9 安装Magisk.apk 后制作新的boot.img,刷入新的boot,启动后显示简单到不属于magisk的su

原因:因为本身我们编译的rom就是root版,所有/system/xbin目录下存在su

解决:mv /system/xbin/su /system/xbin/su_backup ,然后重新打开Magisk

6.10 Factory Images(官方镜像)

区别于我们自己编译的镜像,它是google提供的官方完整镜像,体验好,bug少;官方镜像中有boot.img 可以安装magisk.img

https://developers.google.com/android/images

6.11 非A/B分区的可以刷recovery.img (TWRP) recovery模式中可以使用twrp可以刷Gapps zip包

6.12 android 源码根目录

目录 介绍
art Android Runtime,一种App运行模式,区别于传统的Dalvik虚拟机,旨在提高Android系统的流畅性
bionic 基础C库源代码,Android改造的C/C++库
bootable Android程序启动导引,适合各种bootloader的通用代码,包括一个recovery目录
build 存放系统编译规则及generic等基础开发包配置
cts Android兼容性测试套件标准
dalvik Android Dalvik虚拟机相关内容
developers Android开发者参考文档
development Android应用开发基础设施相关
device Android支持的各种设备及相关配置
external
frameworks 应用程序框架,Android系统核心部分,由Java和C++编写
hardware 硬件适配接口
kernel Linux Kernel,不过Android默认不提供,需要单独下载,只有一个tests目录
libcore Android Java核心类库
libnativehelper Android动态库,实现JNI库的基础
packages 应用程序包
pdk Plug Development Kit 的缩写,本地开发套件
platform_testing Android平台测试程序
prebuilts x86和arm架构下预编译的一些资源
sdk Android的Java层sdk
system Android底层文件系统库、应用和组件
test Android Vendor测试框架
toolchain Android工具链文件
tools Android工具文件

6.13 build目录

目录 介绍
blueprint 输入为.bp文件。输出为.ninja文件core 核心的编译规则makefile
kati kati is an experimental GNU make clone
make 以前的老的make系统
soong 新的Build系统
target AOSP自带的Target(模拟器)的一些makefile
tools 编译中使用的shell及python写的工具脚本
envsetup.sh 编译初始化脚本

6.14 framework目录

目录 介绍
av 多媒体相关的native层源码目录
base 一些基础库代码,各种解析类、工具类都在这个里面
compile 编译相关的内容
ex ex文件解析器
minikin Android原生字体
ml 机器学习
multidex multi dex Loader
native power、surface、input、binder等服务的native层实现源码目录
opt 一些基础软件,如:日历、网络、蓝牙
rs Render Script 可创建3D接口
wilhelm OpenSL ES/OpenMAX AL的audio