这个设备树目录同时包含两部分信息:
emu64a目标的设备树内容- 在 macOS 上用裸 QEMU 启动 TWRP recovery 的最小方法
当前主线已经不是 AVD / emulator 出图,而是裸 QEMU:
qemu-system-aarch64
+ android-33 kernel-ranchu
+ ramdisk-recovery.cpio
+ virtio-gpu-pci
+ 当前设备树里的 recovery root overlay
在编写新的 REC 的过程中,我的设备长期处于 rec 模式,无法接收消息,也无法正常使用
所以需要一个不依赖物理设备的调试环境
而 android_device_emulator_twrp 的最后一次更新是在十年前
当前设备树对应的是 Google emu64a,产品名是:
twrp_emu64a
构建后的运行目标不是实体手机,而是基于 goldfish/ranchu 的 arm64 模拟环境。
这套设备树更适合放进标准的 TWRP / AOSP 源码树里构建。典型目录应是:
device/google/emu64a
如果你是本地在 macOS 改设备树、远端 Linux 编译,当前目录自带的 sync.sh 可以把它同步到远端源码树。这个脚本只是个人工作流辅助,不是启动 QEMU 的必要条件。
当前脚本默认同步到:
/home/laurie/twrp/device/google/emu64a/
下面是一个最小化的初始化流程,重点是把当前设备树放到 device/google/emu64a:
mkdir twrp-work && cd twrp-work
repo init --depth=1 -u https://github.com/TWRP-Test/platform_manifest_twrp_aosp.git -b twrp-16.0
repo sync
mkdir -p device/google然后把这个设备树放进去:
device/google/emu64a
如果你已经有自己的源码树路径,直接把本目录内容拷过去即可,不需要照搬这里的远端路径。
进入源码树后执行:
source build/envsetup.sh
lunch twrp_emu64a
m recoveryimage编译完成后,常用产物在:
out/target/product/emu64a/recovery.img
out/target/product/emu64a/ramdisk-recovery.cpio
对当前这条 QEMU 启动链来说,真正会被 launch_qemu.sh 直接使用的是:
out/target/product/emu64a/ramdisk-recovery.cpio
推荐做法是把它放到下面两个位置之一:
device_tree/twrp_device_google_emu64a/ramdisk-recovery.cpio
device_tree/twrp_device_google_emu64a/artifacts/ramdisk-recovery.cpio
需要准备:
- macOS
qemu-system-aarch64- Android SDK 的 android-33 arm64 system image
- 已经构建或拉回来的
ramdisk-recovery.cpio
brew install qemu默认脚本使用:
$HOME/Library/Android/sdk/system-images/android-33/default/arm64-v8a
其中必须存在:
kernel-ranchu
ramdisk.img
当前启动脚本默认使用这个目录下的本地产物:
./artifacts/ramdisk-recovery.cpio
运行时文件也默认放到:
./artifacts/qemu_userdata.img
./artifacts/qemu_boot.log
也就是说,最小可运行集合是:
- 当前设备树目录
- Android SDK 的
kernel-ranchu和ramdisk.img - 当前目录或
artifacts目录里的ramdisk-recovery.cpio
进入设备树目录后,直接运行:
cd device_tree/twrp_device_google_emu64a
bash launch_qemu.sh twrp这会启动:
kernel-ranchu- 当前目录或
artifacts目录下的ramdisk-recovery.cpio - 当前目录下
artifacts里的qemu_userdata.img
如果 qemu_userdata.img 不存在,脚本会自动创建一个 8G 的 raw 数据盘。
在 Apple Silicon macOS 上,当前脚本会优先使用 hvf 硬件加速;只有不可用时才回退到 tcg。如果落到 tcg,TWRP 的整体响应会明显变慢。
如果只是验证 QEMU + 内核 + 显示链,不启动 TWRP,可以运行:
cd device_tree/twrp_device_google_emu64a
bash launch_qemu.sh这时会使用 SDK 自带的 ramdisk.img。
当前脚本固定使用:
-machine virt- 优先
-accel hvf,否则回退tcg -device virtio-gpu-pci,edid=on,xres=1280,yres=720-device virtio-net-pcihostfwd=tcp::5556-:5555-display cocoa,show-cursor=on
也就是说,宿主机上 ADB 应连接:
adb connect 127.0.0.1:5556
adb -s 127.0.0.1:5556 get-state当前 launch_qemu.sh 默认把串口写到:
artifacts/qemu_boot.log
如果需要可交互串口调试,可以临时把脚本里的串口参数改成:
-serial tcp:127.0.0.1:5557,server,nowait
然后在宿主机上连接:
nc 127.0.0.1 5557连上后会看到:
console:/ $
这时可以直接执行:
getprop sys.usb.config
getprop init.svc.adbd
ifconfig eth0
ls /dev/socket
cat /tmp/recovery.log
如果只想一次性发几条命令:
{
printf '\r\ngetprop sys.usb.config\r\n'
printf 'getprop init.svc.adbd\r\n'
printf 'ifconfig eth0\r\n'
sleep 2
} | nc 127.0.0.1 5557当前设备树里已经收敛了这些关键修复:
- recovery root overlay 直接放在设备树里
- 所需
.ko已直接放进recovery/root/lib/modules init.recovery.ranchu.rc已收敛到 QEMU 路线可用版本- ADB 通过
5556 -> guest 5555工作 sys.usb.config会被强制收敛回adbeth0会在sys.usb.config=adb时由 init 负责配置
如果默认路径不符合本地环境,可以在启动前覆盖:
SDK_DIR=/your/sdk/path \
RAMDISK=/your/ramdisk-recovery.cpio \
DATA_IMG=/your/qemu_userdata.img \
LOG=/your/qemu_boot.log \
QEMU_ACCEL=tcg \
CPU_MODEL=max \
bash launch_qemu.sh twrp如果别人只拿到这个目录,离“直接跑起来”还需要补齐的只有这些外部条件:
- 本机安装
qemu-system-aarch64 - 本机有 Android 33 arm64 的 SDK system image
- 手里有编译出来的
ramdisk-recovery.cpio
除了这三项,当前启动脚本已经不再要求依赖仓库根目录下的运行文件。