blob: 3b93d54028929f2e495834a2749bac33fcc34602 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
# QEMU/AArch64 VIRT 板级支持包说明
中文页 | [English](README.md)
## 1. 简介
AArch64 是 ARMv8 架构下执行 A64 指令的 64 位执行状态。本 BSP 将 RT-Thread 移植到 QEMU `virt` AArch64 机器上,基于设备模型(DM)、Open Firmware(OFW/FDT)与 PCI 总线框架,可作为 VirtIO、PCI 及各类平台驱动的开发与验证平台。
当前默认配置要点:
| 项目 | 说明 |
| ---- | ---- |
| RT-Thread 版本 | 5.3 |
| 架构 | ARMv8 AArch64,MMU |
| SMP | 4 核(`RT_CPUS_NR=4`) |
| 中断控制器 | GICv2 / GICv3(含 ITS、MSI) |
| 控制台 | UART0(PL011,`ttyAMA0`) |
| 根文件系统 | VirtIO Block `vda0`,FatFs(elm-chan) |
| 内存 | 默认 128 MB(可通过 `qemu.py -mem` 调整) |
## 2. 编译说明
建议使用 ARM Developer GNU 交叉编译工具链,支持 Linux / Windows 平台:
```
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/
```
下载 x86_64 Hosted 平台对应的 `xxx-aarch64-none-elf` 二进制包,解压后将 `RTT_EXEC_PATH` 环境变量指向该编译器的 `bin` 目录。
进入 `rt-thread/bsp/qemu-virt64-aarch64` 目录执行:
```
scons
```
正常生成 `rtthread.elf` 与 `rtthread.bin` 文件。
也可通过 `scons --exec-path="GCC工具链路径"` 在指定工具链的同时直接编译。
配置修改可使用 `scons --menuconfig`,保存后重新 `scons` 编译。
## 3. 运行
本 BSP 使用 `qemu-system-aarch64` 模拟器,通过 `qemu.py` 启动。
### 3.1 安装 QEMU
Windows 平台:
```
https://www.qemu.org/download/
```
Linux 平台(以 Ubuntu、Deepin 为例):
```
sudo apt update
sudo apt install qemu-system-arm
```
部分可选功能对 QEMU 版本有要求:
| 功能 | 最低 QEMU 版本 |
| ---- | -------------- |
| UFS 存储 | 8.2.0 |
| VirtIO Sound(`-sound virtio`) | 8.2.0 |
### 3.2 环境变量
| 变量 | 说明 |
| ---- | ---- |
| `RTT_QEMU_ROOT` | QEMU 可执行文件所在目录前缀(脚本会在其后拼接 `qemu-system-aarch64`) |
| `RTT_ROOT` | RT-Thread 源码根目录,默认自动取 BSP 上两级目录 |
### 3.3 基本启动
在 BSP 目录下执行:
```
python qemu.py
```
或:
```
./qemu.py
```
首次运行会自动创建各存储设备对应的 64 MB `qcow2` 镜像。默认以 `-nographic` 模式启动,串口输出到当前终端。
典型启动日志:
```
heap: [0x40042aa0 - 0x40142aa0]
\ | /
- RT - Thread Operating System
/ | \ 5.3.0 build ...
2006 - 2026 Copyright by rt-thread team
hello rt-thread
msh />
```
### 3.4 `qemu.py` 命令行参数
| 参数 | 默认值 | 说明 |
| ---- | ------ | ---- |
| `-gic` | `2` | GIC 版本(`2` 或 `3`);`-smp` 大于 8 时自动切换为 GICv3;`-el 2` 且 GICv3 时内部使用 `gic-version=max`(不可通过 `-gic max` 手动指定) |
| `-smp` | `RT_CPUS_NR`(4) | CPU 核心数;`-dtbo` 检测到 `amp_soc` 时自动加 1 |
| `-mem` | `128` | 内存大小(MB) |
| `-el` | `1` | 异常级别:`1` 默认;`2` 开启虚拟化;`3` 开启 secure |
| `-bootargs` | 见下文 | 内核启动参数 |
| `-initrd` | — | 指定 initrd 镜像路径 |
| `-graphic` | — | 图形模式(ramfb + `virtio-gpu-device` + VirtIO 键盘/平板),替代 `-nographic` |
| `-gl` | — | 图形模式下挂载 `virtio-gpu-gl-pci` 并开启 QEMU 显示端 OpenGL(如 `-gl gtk`);需 QEMU 带 `--enable-opengl`、`--enable-virglrenderer`,且须与 `-graphic` 合用 |
| `-debug` | — | 启用 GDB 调试(`-S -s`) |
| `-dumpdtb` | — | 导出运行时 DTB 并转为 DTS |
| `-dtb` | — | 使用自定义 DTB 文件 |
| `-virtio-block` | `virtio` | VirtIO Block 磁盘镜像名前缀(生成 `virtio.qcow2`,挂载为 `vda`) |
| `-scsi` | `scsi` | VirtIO SCSI 磁盘镜像名前缀 |
| `-flash` | `flash` | pflash 磁盘镜像名前缀(pflash1,CFI NOR) |
| `-emmc` | `emmc` | SDHCI eMMC 磁盘镜像名前缀 |
| `-nvme` | `nvme` | NVMe 磁盘镜像名前缀 |
| `-ahci` | `ahci` | AHCI SATA 磁盘镜像名前缀 |
| `-ufs` | `ufs` | UFS 磁盘镜像名前缀(QEMU ≥ 8.2.0) |
| `-cdrom` | — | SCSI CD-ROM 镜像路径(如 ISO 文件) |
| `-sound` | `hda` | 音频设备:`hda`(Intel HDA)或 `virtio`(VirtIO Sound PCI) |
| `-tap` | — | 使用 TAP 网卡(替代 user 模式) |
| `-ssh` | `12055` | user 模式下 SSH 端口转发(`hostfwd=tcp::PORT-:22`) |
| `-9p` | — | VirtIO 9P 共享目录路径(需在 menuconfig 中启用 VirtIO 9P) |
| `-camera` | — | 宿主机 V4L2 设备路径(如 `/dev/video0`);仅 Linux;需对设备有读权限(通常加入 `video` 组);后台编译运行 `qemu-device-camera.c` 并通过 vfio-user 挂载 PCI 摄像头(需安装 **libvfio-user**) |
| `-dtbo` | — | AMP 模式:指定 DTBO overlay 文件(如 `amp.dtsi`);自动将 `-smp` 加 1;**须 Smart 版本内核**且配置足够 `-mem`(见下文) |
默认 `-bootargs`:
```
console=ttyAMA0 earlycon cma=8M coherent_pool=2M root=vda0 rootfstype=elm rootwait rw
```
### 3.5 常用启动示例
图形界面(VirtIO GPU + 键鼠):
```
./qemu.py -graphic
```
QEMU OpenGL 显示(`-gl`):
```
./qemu.py -graphic -gl gtk
```
> **说明**:`-gl` 仅在 QEMU / 宿主机显示链路侧启用 OpenGL(`virtio-gpu-gl-pci` + VirGL)。本 BSP 默认仅包含 VirtIO GPU 2D 帧缓冲驱动,**没有 OpenGL / VirGL 用户态与内核侧实现**,因此 `-gl` 不会带来 RT-Thread 内的 OpenGL 加速;图形演示请使用 `-graphic`(`virtio-gpu-device`)配合 framebuffer 栈。
GDB 调试:
```
./qemu.py -debug
```
更大内存与 GICv3:
```
./qemu.py -mem 256 -gic 3
```
挂载 CD-ROM:
```
./qemu.py -cdrom /path/to/image.iso
```
VirtIO Sound 音频:
```
./qemu.py -sound virtio
```
9P 目录共享(需先启用 `RT_VIRTIO_9P`):
```
./qemu.py -9p /path/to/share
```
AMP 异构多核(RPMSG 从核,**须 Smart 版本**):
```
./qemu.py -dtbo amp.dtsi -mem 300
```
> **说明**:AMP 示例要求启用 **Smart 版本**(`RT_USING_SMART`),且必须使用 **`-mem 300`**(`amp.dtsi` 内存布局约需 300 MB,默认 128 MB 不足)。`qemu.py` 检测到 `amp_soc` 时会将 `-smp` 自动加 1(例如 `RT_CPUS_NR=4` 时实际以 `-smp 5` 启动)。QEMU `loader` 会预先将 `amp.dtb` 与 `rtthread.bin` 加载到 `amp.dtsi` 指定的固定物理地址(如 `kernel-entry = 0x48480000`),主核再通过 PSCI 拉起从核。标准版内核要求在虚拟地址与物理地址相等的区域运行,无法用于从核地址空间。请在 menuconfig 中开启 Smart 后重新编译。
摄像头演示(`camera.c` 叠加画面到 framebuffer,需配合 `-graphic`):
```
./qemu.py -graphic -camera /dev/video0
```
> **说明**:`-camera` 必须传入宿主机 V4L2 设备路径。Linux 下需先安装 [libvfio-user](https://github.com/nutanix/libvfio-user)(详见 `qemu-device-camera.c` 注释),并确保当前用户对设备节点有读权限(例如 `sudo usermod -aG video $USER` 后重新登录,或用 `ls -l /dev/video0` 确认权限)。若设备正被其他程序占用,也会打开失败。脚本会编译 `qemu-device-camera.c`、等待 `/tmp/qemu-device-camera.sock` 就绪后启动 QEMU,并在 QEMU 退出后结束辅助进程。
### 3.6 控制台与 Telnet
| 端口 | 设备 | 说明 |
| ---- | ---- | ---- |
| 当前终端 | UART0(PL011) | 默认 `-nographic` 串口 |
| `4321` | VirtIO Console | `telnet 127.0.0.1 4321`,端口名 `org.rt-thread.console` |
| `4322` | PCI 8250 串口 | `telnet 127.0.0.1 4322` |
| `4323` | AMP 从核控制台 | 仅 `-dtbo` 模式,`telnet localhost 4323` |
VirtIO Console 连接示例:
```
telnet 127.0.0.1 4321
```
### 3.7 网络
默认使用 user 模式网络(`-netdev user`),SSH 端口转发到本机 `12055`(可用 `-ssh` 修改)。
TAP 网卡模式示例(以 `tap0` 为例):
```
./qemu.py -tap
```
Linux 下需预先配置 TAP 网桥,Windows / WSL 下 TAP 支持有限。TAP 模式下 SSH 端口转发不可用。
## 4. QEMU 默认挂载设备
`qemu.py` 默认向虚拟机挂载以下设备(与驱动默认配置对应)。UFS 仅在 QEMU ≥ 8.2.0 时挂载;带触发条件的可选设备在表中标注。
| QEMU 设备 | 镜像文件 | RT-Thread 侧 |
| --------- | -------- | ------------ |
| `virtio-blk-device` | `virtio.qcow2` | VirtIO Block,根分区 `vda0` |
| `virtio-scsi-pci` + `scsi-hd` | `scsi.qcow2` | VirtIO SCSI |
| `scsi-cd`(可选 `-cdrom`) | 用户指定 | SCSI CD-ROM |
| `pflash`(index=1) | `flash.qcow2` | MTD NOR CFI |
| `sdhci-pci` + `sd-card` | `emmc.qcow2` | SDHCI eMMC(需启用 SDIO) |
| `nvme` + `nvme-ns` | `nvme.qcow2` | NVMe |
| `ahci` + `ide-hd` | `ahci.qcow2` | AHCI SATA |
| `ufs` + `ufs-lu`(仅 QEMU ≥ 8.2.0) | `ufs.qcow2` | UFS |
| `virtio-net-device` | — | VirtIO Net(需启用网络协议栈) |
| `virtio-rng-device` | — | VirtIO RNG |
| `virtio-crypto-device` | — | VirtIO Crypto |
| `virtio-serial-device` | — | VirtIO Console / RPROC Serial |
| `pci-serial`(8250 PCI) | — | PCI 8250 串口 |
| `intel-hda` + `hda-duplex` | — | Intel HDA 音频 |
| `i6300esb` | — | I6300ESB 看门狗 |
| `edu` | — | QEMU EDU 教学设备(MFD) |
| `virtio-gpu-device`(`-graphic`) | — | VirtIO GPU 2D(默认) |
| `virtio-gpu-gl-pci`(`-graphic -gl`) | — | QEMU OpenGL 显示设备;RT-Thread 侧无对应 GL 驱动 |
| `virtio-keyboard-device` / `virtio-tablet-device` | — | VirtIO Input |
| `virtio-9p-device`(`-9p`) | — | VirtIO 9P(需启用驱动) |
| `virtio-sound-pci`(`-sound virtio`) | — | VirtIO Sound |
| vfio-user 摄像头(`-camera <路径>`) | 宿主机 V4L2 设备 | PCI 摄像头(BSP `drv_camera`) |
## 5. 驱动支持情况
### 5.1 默认已启用
| 类别 | 驱动 | 说明 |
| ---- | ---- | ---- |
| 串口 | PL011 | UART0,系统控制台 `uart0` / `ttyAMA0` |
| 串口 | 8250 PCI | PCI 串口,Telnet 端口 4322 |
| RTC | PL031 | 实时时钟 |
| GPIO | PL061 | GPIO 控制器 |
| 看门狗 | I6300ESB | PCI 看门狗 |
| 存储 | VirtIO Block | 块设备,`vda` |
| 存储 | VirtIO SCSI | SD / CD-ROM |
| 存储 | AHCI PCI | SATA 磁盘 |
| 存储 | NVMe PCI | NVMe 磁盘 |
| 存储 | UFS PCI | UFS 磁盘 |
| 存储 | MTD NOR CFI | pflash 闪存 |
| 存储 | BLK 分区 | DFS / EFI 分区表 |
| 图形 | VirtIO GPU | 2D 帧缓冲(`-graphic`);不含 OpenGL / VirGL |
| 图形 | Framebuffer | RAMFB 800×600(`RT_GRAPHIC_ROMFB_WIDTH` / `HEIGHT`,`drv_romfb.c`) |
| 图形 | LCD | LCD 设备框架 |
| 输入 | VirtIO Input | 键盘、鼠标、平板(`-graphic`) |
| 音频 | Intel HDA | 默认 `-sound hda` |
| 音频 | VirtIO Sound | `-sound virtio` |
| 加密 | VirtIO Crypto | VirtIO 加密后端 |
| 随机数 | VirtIO RNG | 硬件随机数 |
| 通信 | VirtIO Console | Telnet 4321 |
| 通信 | RPMSG | VirtIO RPMSG 字符设备 |
| 通信 | Mailbox PIC | 邮箱中断控制器 |
| 固件 | QEMU FW_CFG | 固件配置接口 |
| 总线 | PCI | ECAM + Generic Host,MSI / MSI-X |
| 其他 | MFD EDU | 多功能设备 |
### 5.2 默认未启用但可通过 menuconfig 开启
本 BSP 已启用 PCI 总线与 VirtIO PCI 传输,QEMU 中也已挂载对应设备。下列驱动在默认 `.config` 中未勾选,开启相应 Kconfig 选项并重新编译后即可使用(无需修改 `qemu.py`):
| 驱动 / 功能 | Kconfig 要点 | QEMU 设备 | 说明 |
| ----------- | ------------ | --------- | ---- |
| VirtIO Net | `RT_USING_SAL` + `RT_USING_LWIP` + `RT_USING_ETHERNET` | `virtio-net-device` | 网络协议栈未默认启用 |
| VirtIO 9P | `RT_VIRTIO_9P` | `virtio-9p-device` | 配合 `-9p` 共享目录 |
| SDHCI eMMC | `RT_USING_SDIO` + `RT_SDIO_SDHCI_PCI` | `sdhci-pci` | eMMC 存储 |
> **说明**:凡标注 `depends on RT_USING_PCI` 的 PCI 类驱动,均可在此 BSP 上通过 menuconfig 启用;QEMU 侧若未挂载对应设备,需自行在 `qemu.py` 中添加 `-device` 参数。
### 5.3 BSP 特有功能(驱动层)
| 功能 | 配置项 | 启动方式 |
| ---- | ------ | -------- |
| RAMFB 分辨率 | `RT_GRAPHIC_ROMFB_WIDTH` / `RT_GRAPHIC_ROMFB_HEIGHT` | `-graphic`(`drv_romfb.c` 向 RAMFB 提供尺寸) |
| 摄像头驱动 | `RT_SOC_CAMERA` | `-camera <v4l2路径>`;`camera.c` 预览需加 `-graphic` |
### 5.4 示例应用(`applications/`)
| 源文件 | 编译条件 | 说明 |
| ------ | -------- | ---- |
| `main.c` | 始终编译 | 入口 `main()`,打印 `hello rt-thread` |
| `amp.c` | `RT_RPMSG_RT_THREAD_VIRTIO` | AMP 异构多核与 RPMSG 通信示例 |
| `camera.c` | `RT_SOC_CAMERA` | 摄像头画面叠加到 framebuffer |
**`main.c`**
默认应用,系统启动后输出 `hello rt-thread`,随后进入 msh。
**`amp.c`(AMP + RPMSG)**
QEMU `loader` 预先将 `amp.dtb` 与 `rtthread.bin` 加载到 `amp.dtsi` 指定地址,主核再通过 `amp_soc` 设备树节点与 PSCI 拉起从核 CPU。主从之间通过 VirtIO RPMSG + Mailbox 通信。主核将 VirtIO Block `vdb` 的资源信息写入从核 DTB 后启动从核。`qemu.py` 会为这颗额外 CPU 将 `-smp` 加 1。
**版本要求**:须 **Smart 版本**(menuconfig 中 `RT_USING_SMART`),且须使用 **`-mem 300`**。标准版内核必须在虚拟地址与物理地址一致的映射下运行;AMP 从核加载到独立物理内存区域(见 `amp.dtsi` 中 `amp_memory`、`kernel-entry` 等),不满足该约束,因此标准版无法用于 AMP 演示。
启动方式:
```
./qemu.py -dtbo amp.dtsi -mem 300
```
从核控制台:`telnet localhost 4323`。
msh 命令:
| 命令 | 说明 |
| ---- | ---- |
| `rpmsg_write <设备> <消息>` | 向 RPMSG 字符设备写入消息 |
| `rpmsg_read <设备>` | 读取 RPMSG 字符设备全部消息 |
| `amp_startup` | 手动触发 AMP 从核启动(同时启用控制台与 msh 时导出;否则自动在应用初始化阶段执行) |
系统启动时会自动创建 RPMSG 端点(`rpmsg_char0`,端点名 `rpmsg-char`,地址 114/514)。从核侧地址互换。
**`camera.c`(摄像头预览)**
将 vfio-user PCI 摄像头画面居中叠加到 framebuffer,默认设备 `camera0` → `fb0`,约 10 秒(300 帧)。
启动方式(Linux 宿主机,已安装 libvfio-user 且存在 V4L2 摄像头):
```
./qemu.py -graphic -camera /dev/video0
```
msh 命令:
```
camera [摄像头设备] [framebuffer设备]
```
示例:`camera camera0 fb0`
## 6. 存储与分区
- 根文件系统默认挂载在 VirtIO Block 第一个分区 `vda0`,文件系统类型 `elm`(FatFs)。
- 各存储镜像首次运行自动创建为 64 MB `qcow2` 文件,可通过 `qemu-img` 扩容或预先替换。
- pflash0 用于 BootROM(如 UEFI),本 BSP 使用 pflash1(`flash.qcow2`)作为 CFI NOR;pflash0 数据在 QEMU 退出后不保留。
- Linux 下可使用 `qemu-nbd` + `fdisk` 对 `qcow2` 镜像分区(Windows 不支持)。
## 7. QEMU Monitor 热插拔提示
在 QEMU Monitor 中可动态增删 VirtIO 串口端口:
```
(qemu) chardev-add socket,host=127.0.0.1,port=4323,server=on,wait=off,telnet=on,id=console2
(qemu) device_add virtserialport,chardev=console2,name=org.rt-thread.port,id=port2
(qemu) device_del port2
(qemu) chardev-remove console2
```
VirtIO 设备可选参数(在 `qemu.py` 中按需添加):
- 禁用 legacy:` -global virtio-mmio.force-legacy=false`
- Virtqueue packed:` -device virtio-XXX-device,packed=on`
- PCI 模式(≥ 1.0):` -device virtio-XXX-pci,disable-legacy=on`
## 8. 修改配置后的注意事项
- 修改 CPU 数量后,重新编译使 `RT_CPUS_NR` 与之一致(或用 `qemu.py -smp` 覆盖)。`-dtbo` 模式下 `qemu.py` 会自动将 CPU 数加 1。
- 超过 8 核时 GIC 自动切换为 v3,也可手动指定 `-gic 3`。`gic-version=max` 仅在 `-el 2` 且 GICv3 时由脚本内部设置。
- 启用 9P 目录共享需 QEMU 编译时包含 virtfs(`--enable-virtfs`)。
- 使用 `-gl` 需 QEMU 编译时包含 OpenGL / VirGL(`--enable-opengl`、`--enable-virglrenderer`);这与 RT-Thread 是否支持 OpenGL 无关,当前软件栈默认仅 2D 图形。
- AMP(`-dtbo`)须 Smart 版本内核(`RT_USING_SMART`)、`-mem 300`,且自动增加 CPU 数;标准版要求 VA=PA 运行,无法用于从核固定物理地址加载场景。
- `-camera` 须传入宿主机 V4L2 设备路径,仅支持 Linux,且需 libvfio-user;当前用户须能访问该设备(通常加入 `video` 组);`-graphic` 仅 `camera.c` framebuffer 预览演示需要。
- 修改根设备或启动参数时,通过 `-bootargs` 覆盖默认参数。
|