Android系统基础(04) Android系统源码 编译&烧写

该系列文章总纲链接:专题分纲目录 Android系统基础


1 Android 原生源码编译

1.1 源码编译

@1 设置环境变量 并选择自己需要的目标版本

source build/envsetup.sh    //用来设置android的编译环境
lunch aosp_arm-eng          //选择产品线上的产品,这里选的是模拟器版本

该命令表示针对模拟器进行完整编译,且所有调试功能均启用。如果没有提供任何参数就运行命令,lunch 将提示从菜单中选择一个目标。这里所有的编译目标都采用 BUILD-BUILDTYPE 形式,其中 BUILD 是表示特定功能组合的代号。BUILDTYPE 是以下类型之一:

google pixel设备编译时对应的编译配置表如下所示:

设备代号编译配置
Pixel 3a XLbonitoaosp_bonito-userdebug
Pixel 3asargoaosp_sargo-userdebug
Pixel 3 XLcrosshatchaosp_crosshatch-userdebug
Pixel 3bluelineaosp_blueline-userdebug
Pixel 2 XLtaimenaosp_taimen-userdebug
Pixel 2walleyeaosp_walleye-userdebug
Pixel XLmarlinaosp_marlin-userdebug
Pixelsailfishaosp_sailfish-userdebug

@2 编译代码:make操作

Android源码编译是可以使用 make 编译任何代码的。GNU Make 可以借助 -jN 参数处理并行任务,通常使用的任务数 N 介于编译时所用计算机上硬件线程数的 1-2 倍之间。例如,在一台双核 E5520 计算机(2 个 CPU,每个 CPU 4 个内核,每个内核 2 个线程)上,要实现最快的编译速度,可以使用介于 make -j16 到 make -j32 之间的命令。常见操作如下:

make -j4

常见的一些make编译命令如下所示:

make          //编译整个工程,整体编译时间较长
make module   //对单个模块进行编译,对其所依赖的模块也进行编译,整体编译时间较长
mm            //先进入子目录,对其目录对应的模块进行编译,编译时间短
mmm           //编译制定目录下的模块,不编译其所依赖的其他模块,第一次一般都会报错,编译时间短

make生成镜像文件:

make bootimage     //生成boot.img文件
make snod          //重新打包生成system.img文件
make userdataimage //生成userdata.img文件
make adb           //编译出对应版本的adb命令文件
make fastboot      //编译出对应版本的fastboot刷机工具

@3 关于运行

可以在模拟器上运行自己的版本,也可以将其刷到设备上。(注意:因为之前已使用 lunch 选择编译目标,因此很可能无法在编译目标之外的目标上运行已编译的版本)如果是前者,编译流程会自动将模拟器添加到您的路径中。要运行模拟器,输入以下命令:

emulator

即可。如果是设备,则需要使用 fastboot来刷机(编译成功后,会包含在out对应的的路径中)

@4 编译Android Studio中用到的SDK android.jar

说明:在Android 进行系统源码修改后,比如新API添加、新Service添加等,此时如果 开发APP的 合作伙伴 想要获得 新的API或者Service,那么就可以通过该方法 替换android.jar实现 Android Studio中 可以使用自定义API和Service的功能。

步骤如下:

source build/envsetup.sh //用来设置android的编译环境
lunch sdk-eng            //注意:虽然列表中没有该选项,但依然支持
make update-api          // 更新API版本
make                     //编译过完整的ROM
make sdk                 //开始编译SDK 最后生成android.jar

编译出来的 android.jar 在out目录下,通过find命令查找即可。找到后拷贝出来 替换掉Android Studio中的 android.jar。找到对应路径拷贝即可。

  • 在MAC电脑上的位置:/Users/$用户名$/Library/Android/sdk/platforms/android-XX/android.jar
  • 在Windows上位置是:D:\Sdk\platforms\android-XX\android.jar(说明:这也和安装位置有关,该路径仅参考)

1.2 排查编译错误

@1 JDK匹配问题

如果尝试编译的 Android 版本与自己的 Java 版本不一致,make 将会终止并显示诸如以下消息:

************************************************************
You are attempting to build with the incorrect version
of java.

Your version is: WRONG_VERSION.
The correct version is: RIGHT_VERSION.

Please follow the machine setup instructions at
    https://source.android.com/source/initializing.html
************************************************************

这可能是由以下原因引起的:

未能安装 JDK要求中指定的正确 JDK。关于指定定JDK要求:

  • Android 7.0 (Nougat) - Android 10.0 (Q):Ubuntu - OpenJDK 8
  • Android 5.x (Lollipop) - Android 6.0 (Marshmallow):Ubuntu - OpenJDK 7
  • Android 2.3.x (Gingerbread) - Android 4.4.x (KitKat):Ubuntu - Java JDK 6
  • Android 1.5 (Cupcake) - Android 2.2.x (Froyo):Ubuntu - Java JDK 5

或者是 之前安装的另一个 JDK 出现在您的路径中。将正确的 JDK 附加到路径开头,或者移除有问题的 JDK。

@2 Python版本问题

Repo 是基于 Python 2.x 中的特定功能构建的,但遗憾的是与 Python 3 不兼容。要使用 Repo,请安装 Python 2.x:

$sudo apt-get install python

@3 没有USB权限

如果 adb 已在运行,并且在这些规则设置完成后无法连接到设备,您可以使用 adb kill-server 将其终止。这将使 adb 采用新的配置重启。 


3 通用Android fastboot镜像烧写流程

说明:一般都要先获取root权限,然后执行相关命令。

3.1 启动fastboot模式

Fastboot 是一种引导加载程序模式,可以在该模式下刷写设备。在设备冷启动过程中,可使用以下组合键进入 fastboot 模式,这里以google的pixel系列手机为例进行说明(Nexus版本太多了,命名规范也。。。都绕晕了,但是大体上类似):

Pixel XLmarlin按住音量调低键,然后按住电源键。
Pixelsailfish按住音量调低键,然后按住电源键。

当然也可以使用命令 adb reboot bootloader 直接在 Android 系统中重新启动进入引导加载程序,而无需使用任何组合键。

3.2 解锁引导加载程序

只有在引导加载程序允许的情况下,您才可以刷写定制系统,而引导加载程序默认处于锁定状态。您可以解锁引导加载程序,但这样做会导致系统出于隐私原因而删除用户数据。(注意:解锁之后,系统会清空设备上的所有数据,即应用中的个人数据以及可通过 USB 访问的共享数据(包括照片和影片)。请先备份设备上的所有重要文件,然后再尝试解锁引导加载程序)

只需解锁引导加载程序一次,并可视需要将其重新锁定。

解锁新款设备:自2014 年以来发布的所有 Nexus 和 Pixel 设备(从 Nexus 6 和 Nexus 9 开始)都内置有恢复出厂设置保护功能,需要执行多个步骤才能解锁引导加载程序。

  1. 如需在设备上启用 OEM 解锁功能,请执行以下操作:
    1. 在“设置”中,点按关于手机,然后点按版本号七 (7) 次。
    2. 当看到“您已处于开发者模式”这条消息后,点按返回按钮。
    3. 点按开发者选项,然后启用 OEM 解锁和 USB 调试(如果 OEM 解锁处于停用状态,请连接到互联网,以便设备可以至少检入一次。如果“OEM 解锁”仍处于停用状态,则说明设备可能已被运营商锁定 SIM 卡,系统无法解锁引导加载程序)。
  2. 重新启动进入引导加载程序,然后使用 fastboot 解锁。
    • 对于新款设备(2015 年及之后发布的设备):
      fastboot flashing unlock
      fastboot flashing lock  //如果需要重新锁定
    •  对于老款设备(2014 年及之前发布的设备):
      fastboot oem unlock
      fastboot oem lock  //如果需要重新锁定
  3. 在屏幕上通过音量键 上下,电源键确认 来解锁即可。

3.3 使用刷写锁定状态

getFlashLockState() 系统 API 会传输引导加载程序状态,PersistentDataBlockManager.getFlashLockState() 系统 API 会返回兼容设备上引导加载程序的锁定状态。

返回值条件
FLASH_LOCK_UNKNOWN仅升级到 Android 7.x 或更高版本且符合以下条件的设备会返回此值:设备支持刷写锁定/解锁功能,但之前不支持获取刷写锁定状态所需的引导加载程序变更。
  • 运行 Android 7.x 或更高版本的新设备必须处于 FLASH_LOCK_LOCKED 或 FLASH_LOCK_UNLOCKED 状态。
  • 升级到 Android 7.x 或更高版本且不支持刷写解锁/锁定功能的设备应返回 FLASH_LOCK_LOCKED 状态。
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

3.4 刷机流程

使用fastboot命令 可以刷写整个 Android 系统;这样做可验证并确保正在被刷写的系统与已安装的引导加载程序和无线驱动程序兼容,还可以将启动、恢复和系统分区一起写入,然后重新启动系统。与 fastboot oem unlock 类似,刷写设备也会清空所有用户数据。

在设备处于 fastboot 模式后,可以运行以下命令进行相关的初始化:

$adb reboot bootloader                       //进入 fastboot 模式
$fastboot devices                            //查看设备是否连接成功

可以一次性刷机,命令如下:

#方法1
$fastboot update -w  google_img.zip //完整刷机,google_img.zip为完整刷机包

#方法2,进入到out目录,直接执行
$fastboot flashall -w

注意:-w 选项会擦除设备上的 /data 分区;该选项在第一次刷写特定设备时非常有用,但在其他情况下则没必要使用

刷机相关的命令如下(可以根据自己的需要刷写特定的部分):

$fastboot flash aboot emmc_appsboot.mbn      //烧写bootloader分区
$fastboot flash boot boot.img                //烧写kernel分区
$fastboot flash system system.img            //烧写system分区
$fastboot flash userdata userdata.img        //烧写userdata分区
$fastboot flash persist persist.img          //烧写persist分区
$fastboot flash cache cache.img              //烧写cache分区
$fastboot reboot                             //重启

说明:以下img或者其他文件有可能会根据项目不同导致烧写的方式不同,fastboot特殊分区烧写方式如下:

$adb reboot bootloader
$fastboot flash persist persist.img        //烧写persist分区
$fastboot flash cache cache.img            //烧写cache分区
$fastboot flash modem NON-HLOS.bin         //烧写modem分区
$fastboot flash tz tz.mbn            
$fastboot flash sbl1 sbl1.mbn            
$fastboot flash rpm rpm.mbn    

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: invoking make -j16 -l16 failed 的意思是“调用 make -j16 -l16 失败”。make 是一个常用的编译工具,-j16 表示使用 16 个线程进行编译,-l16 表示限制系统负载为 16。如果调用失败,可能是因为系统资源不足或者命令输入有误等原因。 ### 回答2: 当我们在使用make命令时,希望加快编译速度,就可以使用“-j”选项来指定并发编译的任务数。例如“-j16”表示同时开启16个任务进行编译。而“-l”选项则是用来设置系统负载的最大值,表示当系统负载达到该值时,make就会暂停一段时间等待系统负载下降再继续编译。例如“-l16”表示当系统负载达到16时,make就会暂停编译。 当执行“make -j16 -l16”命令时,如果出现“invoking make -j16 -l16 failed”的错误提示,说明并发编译系统负载控制失败,则需要进行一些排查和解决: 1. 检查系统资源是否足够,如CPU、内存、磁盘空间等是否充足。 2. 检查系统负载情况,使用“top”或“uptime”命令查看当前系统负载,如果负载已经很高,可以等待一段时间再执行make命令。 3. 如果系统资源足够,但仍出现错误,一般是由于并发编译任务之间的依赖关系没有明确指定或者存在竞争条件,可以尝试降低“-j”选项的值,如使用“-j8”或“-j4”等。 4. 如果仍然无法解决问题,则需要检查Makefile文件中的相关配置是否正确或者与所使用的编译器版本是否兼容等问题。 总之,在使用make命令时,需要根据实际情况选择合适的并发编译任务数和最大系统负载,并进行一些排查和调试,才能保证编译的成功。 ### 回答3: 在使用make命令执行编译任务时,可能会遇到“invoking make -j16 -l16 failed”这样的错误提示。这个错误通常是由于make命令执行时出现了问题,导致编译任务无法完成。 首先,我们需要了解make命令的作用。make命令是一个编译工具,可以自动化地执行编译任务,根据编译规则生成目标文件。通常在Linux下编译程序时,可以使用make命令进行自动化编译。 在这个错误提示中,-j16和-l16是make命令的参数。-j参数用于指定同时执行的任务数,这里指定是16个。-l参数用于限制make命令的负载,避免过度使用系统资源,这里指定是16。 如果make命令无法执行任务,就会出现“invoking make -j16 -l16 failed”这样的错误提示。这个错误的原因可能是多方面的,例如编译环境不全、依赖库缺失、语法错误等等。 为了解决这个错误,我们可以采取以下几个方法: 1.检查编译环境配置是否正确,例如编译器、makefile、环境变量等。 2.检查依赖库是否缺失,查看错误提示中是否有关于缺失库的信息。 3.检查代码语法是否正确,是否存在语法错误或语义错误。 4.尝试更改make命令的参数,例如降低-j参数和-l参数的值,以避免过度使用系统资源。 5.查阅相关资料,寻找解决该问题的方法或技巧。 总之,遇到“invoking make -j16 -l16 failed”这样的错误提示,需要我们认真分析错误原因,采取合适的解决方法,最终才能成功地完成程序的编译
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图王大胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值