摘要
本文旨在为广大开发者提供一份在非官方推荐的 Ubuntu 24.04 系统上,成功为小米机器狗 CyberDog 2 进行刷机和交叉编译的终极解决方案。通过层层排查 setup.sh
依赖缺失、No devices to flash
以及交叉编译 Segmentation fault
等疑难杂症,我们发现根源在于宿主机系统版本与官方工具链的不兼容。最终,我们采用 Docker-in-Docker 的方式,构建了一个纯净、兼容的 Ubuntu 20.04 “开发母机”环境,完美解决了所有问题。
关键词:小米机器狗2
, CyberDog 2
, Ubuntu 24.04
, Ubuntu 20.04
, 刷机
, 交叉编译
, Docker
, QEMU
, No devices to flash
, Segmentation fault
一、 问题背景:为何官方教程在 Ubuntu 24.04 上失效?
小米 CyberDog 2 的官方开发文档和工具链(如刷机包内的 setup.sh
、flashall.sh
,以及用于交叉编译的 arm64
Docker 镜像)都是基于较旧的 Ubuntu 版本(如 18.04 或 20.04)进行开发和测试的。
当我们在最新的 Ubuntu 24.04 LTS 系统上直接遵循官方教程时,会遇到一连串看似无关、实则同源的问题:
- 刷机环境配置失败:运行
setup.sh
时,apt-get
报大量E: Unable to locate package ...
错误。这是因为很多旧的软件包(如libncurses5
,python-minimal
,g++-7
)在新版 Ubuntu 中已被重命名或彻底移除。 - 刷机时找不到设备:即使跳过
setup.sh
,直接运行flashall.sh
也会立即报错No devices to flash
。因为核心的 USB 通信依赖未能成功安装。 - 交叉编译时编译器崩溃:尝试在 24.04 上通过 QEMU 模拟运行官方提供的
arm64
Docker 镜像进行编译时,会顽固地出现internal compiler error: Segmentation fault (program cc1plus)
的错误。根本原因是 24.04 自带的新版 QEMU (v8.x) 与镜像内老旧的gcc-7
编译器存在深层兼容性 Bug。
核心结论:所有问题的根源都指向一点——宿主机环境与官方工具链的不兼容。强行在 24.04 上修改脚本或安装零散依赖是治标不治本的,我们需要一个与官方环境一致的“操作台”。
二、 终极解决方案:构建 Ubuntu 20.04 Docker “开发母机”
我们的策略是,不在宿主机 24.04 上直接操作,而是创建一个 ubuntu:20.04
的 Docker 容器,并在这个容器内部完成所有刷机和编译任务。这个容器我们称之为“开发母机”。
优势:
- 环境纯净:获得一个完美的、与官方兼容的 Ubuntu 20.04 环境。
- 无侵入性:不对你的宿主机 24.04 系统做任何修改。
- 可复现:所有步骤都在 Docker 内完成,流程清晰,可随时重建。
三、 详细操作步骤
第 1 步:准备工作
在开始之前,请在你的 Ubuntu 24.04 宿主机上整理好文件:
- 刷机包:解压官方的刷机包,假设路径为
/path/to/your/flash_package
。 - 源码:创建一个用于存放源码的目录,假设路径为
/path/to/your/source_code
。 - 配置文件:准备好刷机用的
ota_others.conf
文件,可以先放在刷机包同级目录。
第 2 步:创建并进入“开发母机”容器
在你的 Ubuntu 24.04 宿主机终端中,执行以下命令。这个命令会创建一个名为 cyberdog-dev
的容器,并将所有必要的目录和设备映射进去。
sudo docker run --name cyberdog-dev -it --privileged \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /dev:/dev \
-v /path/to/your/flash_package:/data/flash_package \
-v /path/to/your/source_code:/data/source_code \
ubuntu:20.04
命令参数详解:
--name cyberdog-dev
: 为容器命名,方便管理。-it
: 以交互式终端模式运行。--privileged
: 特权模式,赋予容器高级权限。-v /var/run/docker.sock:/var/run/docker.sock
: 核心! 映射 Docker Socket,让容器内的 Docker 命令能控制宿主机的 Docker 服务。-v /dev:/dev
: 核心! 映射宿主机所有设备,确保刷机时能访问到 USB 设备。-v /path/to/...:/data/...
: 将你的刷机包和源码目录映射到容器内的/data
目录下,方便访问。请务必替换为你自己的真实路径!
执行成功后,你的终端提示符会变为 root@<容器ID>:/#
,表示你已成功进入 ubuntu:20.04
环境。
第 3 步:在“开发母机”内配置刷机/编译环境
现在,所有后续操作都在这个 root@...
终端里进行。
安装核心依赖:
# 更新软件源,如果速度慢或报错,可更换为国内源 # sed -i "s@http://.*archive.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list # sed -i "s@http://.*security.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list apt-get update # 安装 sudo (某些脚本需要), nano (方便编辑), 以及交叉编译和原生编译的核心工具 apt-get install -y sudo nano git python3-colcon-common-extensions python3-vcstool build-essential # 【重要】安装用于交叉编译的旧版 QEMU apt-get install -y qemu-user-static binfmt-support
配置 QEMU (用于交叉编译):
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
第 4 步:执行刷机流程
运行
setup.sh
:
进入你映射的刷机包目录,运行环境配置脚本。cd /data/flash_package chmod +x tools/otf_tools/setup.sh ./tools/otf_tools/setup.sh
这次,它将在兼容的 Ubuntu 20.04 环境中顺利完成。
让机器狗进入恢复模式:
在宿主机上打开另一个终端,用ssh
或物理按键让狗进入恢复模式。务必在宿主机上用lsusb | grep NVIDIA
确认是否成功进入!执行刷机:
回到“开发母机”容器终端,执行刷机命令。# 假设你的配置文件在刷机包目录下 sudo ./flashall.sh --others-ota-conf-path /data/flash_package/ota_others.conf
等待 10-15 分钟,刷机即可成功!
第 5 步:执行交叉编译流程(如果需要)
如果你需要交叉编译而不是在狗上原生编译,现在也可以在这个正确的环境中进行了。
加载
arm64
镜像:# 假设你的 carpo_arm64.tar 在刷机包目录 docker load < /data/flash_package/carpo_arm64.tar
启动
arm64
编译容器:docker run --privileged=true -it -v /data/source_code:/home/builder/cyberdog_ws cyberdog_img:1.0 bash
在
arm64
容器内编译:
进入容器后,你的终端提示符会再次改变。# 进入工作区 cd /home/builder/cyberdog_ws/cyberdog_ws/ # 设置环境 source /opt/ros2/galactic/setup.bash # 清理并使用单线程编译 (最稳妥) rm -rf build/ install/ log/ colcon build --merge-install --packages-up-to <your_package> --install-base /opt/ros2/cyberdog --parallel-workers 1
由于是在正确的旧版 QEMU 环境下模拟,之前遇到的
Segmentation fault
问题将不复存在。
四、 总结
面对嵌入式开发中复杂的环境兼容性问题,与其在不兼容的系统上“打补丁”,不如从根源入手,利用 Docker 构建一个与官方一致的、隔离的、可复现的开发环境。本文提出的“开发母机”方案,不仅完美解决了在 Ubuntu 24.04 上为 CyberDog 2 刷机和编译的难题,也为其他类似的交叉开发场景提供了宝贵的参考。希望这份指南能帮助更多开发者顺利开启探索之旅!