mingo
路径:
os/arceos/tools/raspi4/chainloadercrate 形态:独立二进制 crate,包名为mingo,[[bin]]名为kernel运行环境:aarch64-unknown-none-softfloat、#![no_std]、#![no_main]实际角色:Raspberry Pi 3/4 板端 UART chainloader,ArceOSchainboot/jtagboot工作流的第一阶段接收器 版本:0.6.0文档依据:Cargo.toml、README.md、README.CN.md、Makefile、build.rs、src/main.rs、src/console.rs、src/driver.rs、src/synchronization.rs、src/_arch/aarch64/cpu/boot.s、src/bsp/raspberrypi/driver.rs、src/bsp/raspberrypi/memory.rs、src/bsp/raspberrypi/kernel.ld、src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs、src/bsp/device_driver/bcm/bcm2xxx_gpio.rs、tests/chainboot_test.rb、os/arceos/tools/raspi4/common/serial/minipush.rb、os/arceos/scripts/make/raspi4.mk、os/arceos/doc/platform_raspi4.md、os/arceos/doc/jtag_debug_in_raspi4.md
mingo 的真实定位必须先讲清楚,否则整篇文档都会偏掉。它不是可以被别的 crate 依赖的库,也不是开发机上执行的串口发送命令;它是部署在树莓派板上的裸机小程序,先由树莓派固件从 SD 卡拉起,再通过 UART 向宿主机的 minipush.rb 请求下一级镜像,最后把 payload 写回固件默认加载地址 0x8_0000 并直接跳转。它位于 tools/ 目录,源码又保留了上游 tutorial 风格,因此很容易被误写成“实验样例”或“宿主机辅助工具”;更准确的说法应是:它是一个带教学来源色彩、但已经被 ArceOS 树莓派开发流程实际使用的板端链加载工具。
架构设计
1.1 它是什么,不是什么
| 问题 | 结论 | 依据 |
|---|---|---|
| 它是库 crate 吗 | 不是 | 没有公共 API,入口是 src/main.rs,目标产物是裸机可执行镜像 |
| 它是宿主机命令行工具吗 | 不是 | 真正运行时在 Raspberry Pi 板端,由固件从 0x8_0000 启动 |
| 它是板端工具吗 | 是 | 启动后初始化 UART/GPIO、接收 payload、跳转执行 |
| 它有实验/教学背景吗 | 有 | README 仍是 tutorial 体例,协议和错误处理都很极简 |
| 它在当前仓库里只是摆设吗 | 不是 | os/arceos/scripts/make/raspi4.mk 和实板文档都把它当成 chainboot / jtagboot 前提 |
因此,mingo 的最准确分类是:
- 形态上,它是一个独立的裸机二进制工具 crate。
- 部署上,它驻留在树莓派板端,而不是宿主机。
- 用途上,它服务于开发阶段的快速重载与调试,不是通用生产级 bootloader。
- 工程属性上,它比“可复用库”更专用,比“纯样例”更真实,因为 ArceOS 的树莓派工作流确实围绕它展开。
1.2 真实调用关系
源码和主工程脚本连起来看,实际链路如下:
这里最容易搞混的地方有两个:
- 宿主机侧发送器是
os/arceos/tools/raspi4/common/serial/minipush.rb,不是mingo。 os/arceos/tools/raspi4/chainloader/Makefile里的chainboot发送的是教程自带的demo_payload_rpi4.img;而 ArceOS 主工程os/arceos/scripts/make/raspi4.mk里的make chainboot才会发送当前构建出来的真实内核镜像。
架构设计
2.1 启动与自重定位
src/_arch/aarch64/cpu/boot.s 与 src/bsp/raspberrypi/kernel.ld 共同定义了它最核心的结构:加载地址与链接地址分离。
- 树莓派固件把镜像放在
0x8_0000。 - 链接脚本把程序链接到
0x0200_0000。 _start只允许 boot core 继续运行,其余核心进入wfe停车。- 启动代码清零
.bss后,把__binary_nonzero_start..__binary_nonzero_end_exclusive从当前加载地址复制到链接地址。 - 栈顶取自
__boot_core_stack_end_exclusive,随后跳到重定位后的_start_rust。
这个设计的目的非常直接:先把 mingo 自己挪开,空出 0x8_0000,这样收到的 payload 就可以按 Raspberry Pi 固件默认约定落回这个地址,并像“直接从 SD 卡启动”那样继续执行。