贝博恩创新科技网

Recovery Ramdisk教程如何制作与使用?

目录

  1. 第一部分:基础概念

    Recovery Ramdisk教程如何制作与使用?-图1
    (图片来源网络,侵删)
    • 什么是 Recovery Ramdisk?
    • 它与完整的 Recovery Image 有什么区别?
    • 为什么需要制作自定义 Recovery Ramdisk?
  2. 第二部分:准备工作

    • 硬件要求
    • 软件与环境
    • 知识储备
  3. 第三部分:制作 Recovery Ramdisk (以 AOSP 为例)

    • 步骤 1: 获取 AOSP 源码
    • 步骤 2: 编译 Recovery 源码
    • 步骤 3: 打包 Recovery Ramdisk
    • 步骤 4: 编译完整的 Recovery Image (可选,但推荐)
  4. 第四部分:刷入与测试

    • 如何刷入 Recovery Ramdisk
    • 如何在 Recovery 模式下验证 Ramdisk
  5. 第五部分:高级用法与技巧

    Recovery Ramdisk教程如何制作与使用?-图2
    (图片来源网络,侵删)
    • 修改 recovery.fstab 挂载点
    • 添加自定义脚本或二进制文件
    • 制作支持 adb sideload 的 Ramdisk
    • 调试技巧
  6. 第六部分:常见问题与故障排除

    • mkbootfsmkbootimg 找不到
    • 编译失败
    • 刷入后无法进入 Recovery

第一部分:基础概念

什么是 Recovery Ramdisk?

Recovery Ramdisk 是 Android 启动过程中的一个关键组件,它是一个被压缩的内存文件系统(通常为 cpio 格式),包含了使设备进入恢复模式 所需的最小化操作系统环境。

当你长按 电源键 + 音量上键(组合键因设备而异)时,设备的 Bootloader 会加载两个核心文件:

  1. Kernel (内核): 操作系统的核心,负责管理硬件资源。
  2. Ramdisk (内存盘): 一个临时的文件系统,包含了启动到特定模式(如 Recovery 或 System)所需的初始化脚本和工具。

对于 Recovery 这个 Ramdisk 就是我们所说的 Recovery Ramdisk,它内部包含了:

Recovery Ramdisk教程如何制作与使用?-图3
(图片来源网络,侵删)
  • init 可执行文件:Recovery 模式的“主进程”,负责挂载分区、启动服务等。
  • recovery.rcrecovery.fstab:定义了 Recovery 模式的行为和需要挂载的分区。
  • recovery-binary:执行恢复操作(如安装 OTA 包、Wipe 数据等)的核心程序。
  • 其他必要的工具,如 adbd (用于 ADB 调试)、busybox 等。

它与完整的 Recovery Image 有什么区别?

  • Recovery Ramdisk: 仅仅是恢复模式的内存盘部分,它是一个 ramdisk.cpio.gz 文件。
  • Recovery Image: 是一个完整的镜像文件,包含了 Kernel + Recovery Ramdisk,一个 recovery.img 文件就是使用 mkbootimg 工具将内核和 ramdisk 打包在一起的结果。

Recovery Image = Kernel + Recovery Ramdisk,我们通常刷入设备的都是 recovery.img,但制作它的第一步就是制作出 recovery_ramdisk.cpio.gz

为什么需要制作自定义 Recovery Ramdisk?

  1. 修复设备: 当设备无法开机或进入系统时,一个定制的 Recovery 可以用来修复分区表、恢复系统或重置设备。
  2. 添加功能: 你可以在 Recovery Ramdisk 中添加自定义脚本、工具或修改现有逻辑,
    • 自动备份 NVRAM 数据。
    • 添加特殊的安装选项(如只清除缓存)。
    • 集成高级的诊断工具。
  3. 适配硬件: 为新硬件或修改了分区表的设备创建一个能正确识别所有分区的 Recovery。
  4. 研究与学习: 深入理解 Android 的启动流程和 Recovery 的工作原理。

第二部分:准备工作

硬件要求

  • 一台可以正常运行的电脑(推荐 Linux,如 Ubuntu,因为 AOSP 编译环境在 Linux 下最稳定)。
  • 你的 Android 设备(需要已解锁 Bootloader,并获取 boot.img 以获取内核信息)。

软件与环境

  • 操作系统: Linux (强烈推荐 Ubuntu 20.04/22.04) 或 Windows (WSL2 亦可)。
  • AOSP 源码: 你需要下载对应设备或 Android 版本的 AOSP 源码。
  • 编译工具链: AOSP 自带的 makebuild/envsetup.sh 脚本会自动处理大部分依赖。
  • 工具:
    • git: 用于下载源码。
    • repo: AOSP 的代码管理工具。
    • python: 通常需要 Python 3。
    • unzip, lz4, zstd 等压缩工具。

知识储备

  • 基本的 Linux 命令行操作cd, ls, cp, mv, mkdir, chmod 等。
  • 了解 Android 目录结构:知道 system, bootloader, recovery 等分区的作用。
  • 了解 AOSP 编译流程:知道如何使用 lunch, make 等命令。

第三部分:制作 Recovery Ramdisk (以 AOSP 为例)

我们将以编译 AOSP 官方 Recovery 为例,这个过程适用于大多数基于 AOSP 的设备。

步骤 1: 获取 AOSP 源码

在你的电脑上设置好 AOSP 编译环境,打开终端,执行以下命令:

# 创建一个目录存放源码
mkdir aosp-recovery
cd aosp-recovery
# 初始化 repo
repo init -u https://android.googlesource.com/platform/manifest -b main
# 同步源码 (这步会很久,请耐心等待或使用 -j 参数加速)
repo sync -j4

注意: main 分支对应最新的 Android 14,如果你需要编译其他版本,请使用对应的分支名,如 android-13.0.0_r1

步骤 2: 编译 Recovery 源码

AOSP 的 Recovery 源码位于 bootable/recovery 目录,我们需要编译它来生成二进制文件和资源。

# 加载编译环境
source build/envsetup.sh
# 选择一个编译目标 (这里以 aosp_cf_x86_64-userdebug 为例,是一个模拟器目标)
# 对于真机,你需要使用你设备的 lunch combo,astra-userdebug
lunch aosp_cf_x86_64-userdebug
# 开始编译 Recovery
# 这会编译 recovery 模块,生成 recovery 可执行文件和相关资源
make -j$(nproc) recoveryimage

说明:

  • lunch 命令用于配置编译目标。userdebug 是一个适合开发和调试的版本。
  • make recoveryimage 会编译整个 Recovery Image,如果你只想编译 recovery 二进制本身,可以用 make recovery,但前者更完整。
  • -j$(nproc) 会使用你电脑的所有 CPU核心来加速编译。

编译成功后,你会在 out/target/product/<设备名>/ 目录下找到生成的文件。

步骤 3: 打包 Recovery Ramdisk

我们从编译好的 Recovery Image 中提取出 Ramdisk,AOSP 已经提供了工具。

# 进入输出目录
cd out/target/product/aosp_cf_x86_64/
# 使用 AOSP 自带的工具解包 recovery.img
# 这个脚本会解包出 kernel, ramdisk 等
./../../../../../system/core/mkbootimg/unpack_bootimg.py --input recovery.img

执行后,你会得到一个 recovery.img-ramdisk 目录,里面就是解压出来的 Ramdisk 内容。

如果你想修改 Ramdisk 内容,现在就是最佳时机:

  1. 解压 Ramdisk:

    # 进入 ramdisk 目录
    cd recovery.img-ramdisk
    # 解压 cpio 文件
    cpio -i -d < ramdisk.cpio

    ramdisk 目录下就是 Recovery Ramdisk 的所有文件和文件夹了。

  2. 进行修改:

    • 修改 recovery.fstab 以适配你的分区。
    • sbin 目录下放入你自己的二进制文件。
    • etcinit.rc 中添加启动脚本。
    • 修改 default.prop 更改默认属性。
  3. 重新打包 Ramdisk:

    # 回到 ramdisk 目录
    cd ramdisk
    # 重新打包成 cpio
    find . | cpio -o -H newc -O ../ramdisk_new.cpio
    # 回到上一级目录
    cd ..
    # 重新压缩成 gz
    gzip -f ramdisk_new.cpio

    你就有了一个新的、修改过的 Ramdisk 文件:ramdisk_new.cpio.gz

步骤 4: 编译完整的 Recovery Image (可选,但推荐)

如果你修改了 Ramdisk,你需要用新的 Ramdisk 和原来的内核重新打包成一个完整的 recovery.img 才能刷入。

你需要从原始的 boot.imgrecovery.img 中获取内核信息,可以使用 unpack_bootimg.py 来获取。

假设你已经知道了内核信息:

  • kernel: 内核文件路径
  • ramdisk: 新的 Ramdisk 路径 (ramdisk_new.cpio.gz)
  • base: 通常为 0x10000000
  • cmdline: 内核启动参数
  • pagesize: 分页大小 (2048)
  • ramdisk_offset: ramdisk 在镜像中的偏移量
  • tags_offset: tags 在镜像中的偏移量

使用 mkbootimg 工具打包:

# 确保你在 out/target/product/<设备名>/ 目录下
# 使用你自己的参数替换下面的占位符
mkbootimg \
    --kernel <path_to_kernel> \
    --ramdisk ramdisk_new.cpio.gz \
    --base <base_address> \
    --cmdline "<kernel_command_line>" \
    --pagesize <page_size> \
    --ramdisk_offset <ramdisk_offset> \
    --tags_offset <tags_offset> \
    --output recovery_custom.img

提示: mkbootimg 工具通常在 out/host/linux-x86/bin/ 目录下,你可以把它加入 PATH 或者使用绝对路径。


第四部分:刷入与测试

如何刷入 Recovery Ramdisk

你刷入的应该是我们刚刚生成的 recovery_custom.img (或者 recovery.img 如果你没有修改)。

  1. recovery_custom.img 传输到设备:可以通过 adb push 或存入 SD 卡。
  2. 重启到 Bootloader 模式:
    adb reboot bootloader
  3. 使用 fastboot 刷入:
    fastboot flash recovery recovery_custom.img
    fastboot reboot recovery
    • fastboot flash recovery: 将镜像刷入 recovery 分区。
    • fastboot reboot recovery: 重启并进入 Recovery 模式。

如何在 Recovery 模式下验证 Ramdisk

进入 Recovery 后,你可以进行以下验证:

  1. 检查挂载点: 进入 Advanced -> Partition Menu,看看是否能正确识别和挂载 /system, /data, /cache 等分区。
  2. 检查 ADB: 如果你的 Ramdisk 包含了 adbd,在 Recovery 界面应该可以通过 adb devices 看到设备,并使用 adb sideload 功能。
  3. 运行自定义脚本: 如果你添加了自定义脚本,检查它是否按预期执行。

第五部分:高级用法与技巧

修改 recovery.fstab

这是最常见的需求。recovery.fstab 定义了 Recovery 模式下需要挂载的分区。

  • 表示该分区是可移动的(如 SD 卡)。
  • /system 是系统分区。
  • /data 是用户数据分区。
  • /cache 是缓存分区。
  • mnt 是一个通用挂载点。

修改后,确保你的设备分区名称和路径与 fstab 中定义的一致。

添加自定义脚本或二进制文件

  • 脚本: 将你的 Shell 脚本(post-install.sh)放入 ramdisk/etc 目录,并确保它有执行权限 (chmod +x),然后在 init.rc 中通过 execservice 调用它。
  • 二进制文件: 将编译好的二进制文件(如 magisk, twrp 的工具)放入 ramdisk/sbin 目录,并同样赋予执行权限。

制作支持 adb sideload 的 Ramdisk

adb sideload 是一个非常有用的功能,允许你通过 ADB 直接从电脑推送和安装 ZIP 包。

  • 确保你的 Ramdisk 中包含 adbd (通常包含)。
  • init.rc 中,需要有一个 service 来启动 adbd,并且设置 seclabelu:r:adbd:s0 (根据 SELinux 策略可能不同)。
  • 在 Recovery 的主界面(通常是文本界面),按菜单键(或物理按键)应该能看到 "Apply update from ADB" 的选项。

调试技巧

  • 开启详细日志: 在 default.prop 中添加 ro.secure=0ro.debuggable=1 可以开启更多调试信息。
  • 使用 logcat: 在 Recovery 模式下连接 ADB,运行 adb logcat -b main -b system -b crash 可以查看 Recovery 的详细日志输出,对排查问题非常有帮助。
  • Ramdisk 模拟: 你可以在电脑上使用 chroot 进入之前解压出来的 ramdisk 目录,模拟运行环境来测试你的脚本和修改。

第六部分:常见问题与故障排除

mkbootfsmkbootimg 找不到

这些工具是 AOSP 编译过程的一部分,确保你已经成功执行了 source build/envsetup.shlunch 命令,并且当前在 AOSP 源码的根目录下编译,如果还是找不到,检查 out/host/linux-x86/bin/ 目录是否存在。

编译失败

  • 检查依赖: 确保你的系统安装了所有必要的编译库和工具。
  • 清理环境: 有时候编译缓存会导致问题,尝试执行 make clobber 清理 out 目录后重新编译。
  • 查看错误信息: 编译器输出的最后几行通常包含最关键的错误信息,仔细阅读并搜索网络解决方案。

刷入后无法进入 Recovery

  • 分区表错误: 你刷入的 Recovery 可能与你设备的 Bootloader 不兼容,或者分区表被修改过,尝试从官方或社区提供的 Recovery 开始修改。
  • 内核不匹配: 确保你打包时使用的内核是从设备正确的 boot.imgrecovery.img 中提取的。
  • Ramdisk 损坏: 重新打包 Ramdisk 时可能出错,尝试用原始的 Ramdisk 打包,看是否能正常进入,如果能,问题就出在你修改的内容上。

最后提醒: 修改 Recovery Ramdisk 是一项高风险操作,操作不当可能导致设备变砖(无法启动)。请务必在操作前备份好所有重要数据,并确保你清楚每一步操作的含义。 对于普通用户,直接使用成熟的第三方 Recovery(如 TWRP)通常是更安全、更方便的选择,本教程主要面向开发者和希望深入理解 Android 底层原理的用户。

分享:
扫描分享到社交APP
上一篇
下一篇