环境
设备 | rock5b 16g + nvme |
---|---|
系统 | armbian (需刷官网spi image) |
内核 | 5.10.110-legacy-rockchip-rk3588 |
Cuttlefish与redroid对比
得益于rock5b搭载的arm架构cpu rk3588强大的性能,我们可以在这块板子上直接刷入android系统运行,亦可采用redroid或cuttlefish等方案容器化/虚拟化宿主机资源来提供android运行环境。
不过cuttlefish与redroid有什么异同点呢?这里总结一下
redroid | cuttlefish | |
---|---|---|
类型 | 基于docker的容器 | 基于 crosvm /qemu 的虚拟机 |
虚拟化 | 不需要 | 需要 |
内核 | 系统内核,需要开启ashmem ,binder 等。同时应用进程运行在系统内核中可以直接对其进行一些操作 |
独立android内核,运行在虚拟机中,内部进程对系统内核不可见 |
指令集翻译 | 可以添加libhoudini.so |
未见支持理论可行 |
资源消耗 | 容器,内核部分共用节省资源 | 虚拟机,需要完整系统资源 |
AOSP | 修改过 | 原装 |
redroid安装
由于redroid使用系统内核,需要开启一些android需要的内核功能。
这里可以参考官方安装步骤,由于我的rock5b安装的是armbian没有预构建模块,需要重新编译内核。
内核编译安装步骤
下载系统使用内核版本的源码
1 | sudo apt install linux-source-5.10.110-legacy-rockchip-rk3588 |
安装完后在src目录下获得内核源码
1 | /usr/src |
解压内核并覆盖配置(也可以 zcat /proc/config.gz > .config
进行配置)
1 | cd ~ |
使用mrproper进行清理并手动配置开启需要的内核功能
1 | make mrproper |
进入 Device Drivers > Android
选中需要的特性(移动到位置空格选中)
Device Drivers > Staging drivers > Android
开启ashmem
选好之后切到save,保存完exit
构建并安装
1 | make -j8 |
我们要替换内核,所以需要将我们编译的内核模块也进行安装,回到编译目录
1 | sudo make modules_install |
由于我们是直接编译的当前内核源码,所以使用sudo make install
即可安装,下面的指令未更新initrd等数据,不建议使用,但提供在这方便手动调试等
手动替换文件安装内核(非必要不使用):
1 | cp arch/arm64/boot/Image /boot/vmlinuz-5.10.110 |
如果您是使用 make install
进行安装的,请在重启前单独执行下面的命令(重要,未建立正确映射关系会导致内核无法启动,需要SD卡启动修复链接)
1 | cd /boot |
docker安装
armbian按照官方介绍安装docker前执行
1 | update-alternatives --set iptables /usr/sbin/iptables-legacy |
然后按照官方教程安装
1 | sudo mkdir -m 0755 -p /etc/apt/keyrings |
运行redroid
1 | docker run -itd --rm --privileged \ |
由于这里使用的是armbian(ubuntu 22.04),会发现启动异常。查看日志lmkd反复退出android lmk服务异常。
经SeeFlowerX大佬提示Ubuntu22.04使用cgroup v2,不满足redroid需求,需要开启cgroup v1
开启cgroup v1
在文件 /boot/armbianEnv.txt
中加入一行(插入内核cmdline systemd.unified_cgroup_hierarchy=0
)
1 | extraargs=systemd.unified_cgroup_hierarchy=0 |
重启即可生效
连接
前面运行的时候暴漏了adb 5555端口,adb connect ip:5555
即可,scrcpy可以操作亦可参照官方的使用其他方式查看视频流。
cuttlefish安装
1 | sudo apt install -y git devscripts config-package-dev debhelper-compat golang curl |
下一步前因为网络环境问题建议做两件事
1.修改 frontend/src/goutil
中的goproxy地址
当然你也可以把他拿出if里面,go低于1.15不设置这个环境变量的话网络环境不好本身也直连不上。
2.修改frontend/setup-nodejs-env.sh
中nodejs下载地址
1 | sudo vim frontend/setup-nodejs-env.sh |
构建deb
1 | for dir in base frontend; do |
安装deb
1 | sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f |
下载cuttlefish使用的镜像
在 ci.android.com 选择cf的的镜像跟工具下载
1 | mkdir cf |
别怪我把文件解压的乱七八糟,官方guide教的
启动
1 | HOME=$PWD ./bin/launch_cvd --daemon |
如果您启动时遇到Address family not supported by protocol
经排查是cuttlefish在绑定vsock时出错,参照文档发现其需要内核开启VSOCK,而guide在debian环境下,经查debian默认开启了该特性,所以我们需要在armbian的内核上开启VSOCK支持,开启过程参照内核编译安装步骤,需要开启的选项参照 https://github.com/radxa/kernel/commit/8f044dffd16fd667ff2272ee626e3ce0355c7eaa (感谢非虫大佬 https://zhuanlan.zhihu.com/p/609085533)
关闭
1 | ./bin/launch_cvd |
GPU加速
暂不支持
由于Cuttlefish的arm host package使用bionic运行时,测试发现其在加载glibc编译的gl库时出现崩溃,目前并没有去探究崩溃的原因但由于这是一个兼容性问题,大可从三方面解决
- 编译bionic运行时下的gl库 (mesa)
- 修改aosp构建系统配置,构建arm glibc cvd host package
- 为具有gpu加速的android docker补充cvd需要的主机文件,使其在android docker内运行(测试可正常调用gl库,但缺少android-cuttlefish下安装的东西)
文档
请查看 https://source.android.com/docs/setup/create/cuttlefish?hl=zh-cn 或在cuttlefish代码页查看readme(内容一致,网页机翻可切英文)
内核无法启动排查与修复
我所使用的armbian boot分区结构如下
1 | drwxr-xr-x 4 root root 4096 Feb 27 15:13 ./ |
当上电5b蓝灯常亮时基本可以确认内核无法正确启动,您可以使用sd卡引导或拆卸硬盘在可运行的系统上挂载boot分区
比较重要的几个文件
vmlinuz
1 | dia@rock-5b:/boot$ file vmlinuz |
内核二进制文件,在这里的链接并不合理。经测试不使用该文件
initrd.img
initramfs,如果您使用make install安装内核会自动打包该文件,无法启动也请检查符号链接
uInitrd
uboot所用,make install
时生成
Image
经测试armbian实际通过该文件启动内核,请确认该文件正确链接到内核二进制文件(同上面的vmlinuz)上
启动进入initramfs shell
如果您exit提示找不到启动设备,可能是在编译时使用了错误的配置/配置文件导致nvme加载出错。请恢复原内核重新配置编译