wheatfox

开发分支:https://github.com/syswonder/hvisor/tree/dev-board-abstract

设计原则

  1. hvisor 本身的 src 内部不出现任何 platform_xxx 相关的 cfg
  2. 引入之前陈学长的 hvisor-deploy 架构,在 platform 文件夹下有序存放各个体系结构和板子的信息
  3. BOARD FOLDER(板卡专用目录)索引 URL: platform/$ARCH/$BOARD 【重要】
  4. 每个板卡的唯一 BID (Board ID)ARCH/BOARD ,例如 aarch64/qemu-gicv3 【重要】
  5. 在编译时可以指定 BID=xxx/xxx 来简写,同时也支持之前的 ARCH=xxx BOARD=xxx 风格,并且不再需要指定feature(见后文)
  6. 每个板子有一个专用目录(如上),其中包含:
    1. linker.ld - 每个板卡的链接脚本
    2. platform.mk - QEMU 启动 Makefile 和 hvisor.bin target(每个架构的 hvisor.bin 的处理都不太一样,需要每个 board 自行编写)
    3. board.rs - 类似之前 qemu_aarch64.rs 的板卡定义 rust 代码(就是一些结构),现在放在每个板子的专用目录中
    4. configs/ - hvisor tool 启动 zone 的 json 文件
    5. cargo/
      1. features - 通过 FEATURES 指定需要的 driver 型号 以及其他特性信息,编译时的 FEATURES 会从这里读取(之前每次都需要在命令行手写)
      2. config.template.toml - 移除根目录的 .cargo/config ,改为动态生成(因为每个板子的 linker 需要在这里指定,所以需要根据选择的 BOARD 动态生成,脚本位于 tools/gen_cargo_config.sh
    6. test/ - (Optional)内部存放用于 unittest+systemtest 的代码,目前仅 qemu-* 相关的板卡能进行 qemu 测试
    7. image/ - qemu / 实机 启动时需要的 kernel/rootfs/dtb 等存放在这里,和之前的 image 目录含义一致
      1. bootloader/ - (Optional) 用于 QEMU 本地运行和 unittest+systemtest 测试使用
      2. dts/ - (Optional)zone 0, 1, 2, … 的 dts 文件
      3. its/ - (Optional) 用于 uboot FIT image 生成(zcu102)
      4. acpi/ - (Optional) x64 下 acpi 设备树源码(hvisor x86 port)
      5. kernel/ - (Optional) ignore
      6. virtdisk/- (Optional) ignore

以下是通过脚本自动生成的 .cargo/config.toml,注释中会包含自动生成时的一些信息。

其中 template 支持 macro 替换,方便使用,__ARCH__ __BOARD__ 等将被直接替换为 ARCH 等:

# cat platform/aarch64/qemu-gicv3/cargo/config.template.toml
[target.aarch64-unknown-none]
runner = "platform/__ARCH__/__BOARD__/test/runner.sh"
rustflags = [
    "-Clink-arg=-Tplatform/__ARCH__/__BOARD__/linker.ld",
    "-Ctarget-feature=+a53,+v8a,+strict-align,-neon,-fp-armv8",
    "-Cforce-frame-pointers=yes",
]

# Generated by gen_cargo_config.sh at Mon Mar 10 11:14:26 AM CST 2025 (wheatfox@dedsec-amd0)
# BASH_VERSION = 5.2.15(1)-release
# HOST_ARCH    = x86_64
# OS_INFO      = Linux 6.1.0-27-amd64 debian
# ARCH         = aarch64
# BOARD        = qemu-gicv3
# FEATURES     = gicv3 pl011 iommu pci pt_layout_qemu
# HVISOR_SRC   = /home/wheatfox/Documents/Code/hvisor-abstract
# LD_SCRIPT    = /home/wheatfox/Documents/Code/hvisor-abstract/platform/aarch64/qemu-gicv3/linker.ld
# TEMPLATE     = /home/wheatfox/Documents/Code/hvisor-abstract/platform/aarch64/qemu-gicv3/cargo/config.template.toml

[target.aarch64-unknown-none]
runner = "platform/aarch64/qemu-gicv3/test/runner.sh"
rustflags = [
    "-Clink-arg=-Tplatform/aarch64/qemu-gicv3/linker.ld",
    "-Ctarget-feature=+a53,+v8a,+strict-align,-neon,-fp-armv8",
    "-Cforce-frame-pointers=yes",
]

  1. 规则:对于 QEMU 来说,qemu-gicv2 和 qemu-gicv3 认为是两个不同的板卡,分别存放,RISCV64的 plic/aia QEMU 同理,即对每一套在实际硬件模拟结构层次不同配置的 QEMU 认为是【不同】的板卡,单独建档,一些原因:
    1. gic/plic 配置不同的 qemu 启动 hvisor 和 rootlinux 均需要不同的 board.rs 和 dts 定义,存在一定的差别,之前都是混在一起放的(linux-v2.dts / linux.dts)
    2. 之前为了适配一个 qemu 目标的不同硬件配置,需要在 Makefile 写很多额外代码用于控制编译和启动 QEMU 的流程(如需要不同的 uboot.bin)
    3. ~~当然到底要不要分可能有不同意见,需要协商一下 :)~~针对几个固定的qemu配置分开的好处是目录和代码结构清楚

设计细节

  1. 一些操作通过 build.rs 实现,其主要负责把前面提到的每个板子的 board.rs 自动 symlink 到 src/platform 下面的临时文件 __board.rsgitignore掉了,对这个临时 symlink 软链接文件的修改会和 board 专有目录内的 board.rs 同步,后者会被保存到 git 仓库中),__board.rssrc/platform/mod.rs 自动导入
  2. 至于为什么用 build.rs 实现而不是在之前的 Makefile 里通过脚本实现:
    1. build.rs 支持配置 rerun 参数,在相关 env 变量没有修改的时候,这个build.rs不会被二次触发,避免每次都进行全量编译,降低开发效率(cargo 本身支持增量编译)
    2. 之后如果有新的自动化编译的需求,通过 build.rs 实现相对比较方便(可以使用 rust std)
  3. 去除了 src/device/uart 下面所有 platform_ 相关的 cfg,转而通过 FEATURES 传入需要的 driver (由前文板子专用目录内的 features 文件指定,一行一个):