摘要
本文旨在為廣大開發者提供一份在非官方推薦的 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 刷機和編譯的難題,也為其他類似的交叉開發場景提供了寶貴的參考。希望這份指南能幫助更多開發者順利開啟探索之旅!