部分往届内核及运行指引

除了这次试验要介绍的 Starry 之外,我们还推荐参考以下内核的实现:

名字和链接 学校 年份 使用语言 部分特性
umi 西安交通大学 2023 Rust 中断驱动的全局异步;函数自动转换为 future;模块化;用户地址检查;基于smoltcp 的协议栈
Titanix 哈尔滨工业大学(深圳) 2023 Rust 部分异步;用户地址检查;支持 redis、gcc、vi 和一个 httpserver
ByteOS 河南科技大学 2023 Rust 异步函数包装;支持 redis、gcc、ssh 和一个 httpserver
alien 北京理工大学 2023 Rust 支持 GUI;支持 bash、redis、sqlite3
FarmOS 北京航空航天大学 2023 C
FTLOS 哈尔滨工业大学(深圳) 2022 Rust 异步函数包装;RCU;syscall 快速路径
maturin 清华大学 2022 Rust cargo生成文档;模块化;支持 redis、gcc
Oops 哈尔滨工业大学(深圳) 2022 Rust 支持 binutils、vi、rustc
TatakaOS 杭州电子科技大学 2022 C 支持 vi、quickjs、xc(一个C的解释器)
NPUcore 哈尔滨工业大学(深圳) 2022 Rust 带缓存的VFS;支持 bash
TLTS 北京航空航天大学 2022 C 支持 redis、gcc
UltraOS 哈尔滨工业大学(深圳) 2021 Rust 运行时调试工具
404 中国科学院大学 2021 C
xv6 华中科技大学 2021 C 多核启动

上表中没有提及比赛要求实现的测例集和应用,只列出了要求之外的部分。另外,对于内核特性的描述比较主观。如果你有不同的想法,可以在本项目的 issue 告诉我们。

在 2021 年的第一届比赛时,还没有队伍能够完成赛事方提供的所有测例(主要是 lmbench 测例集),所以内核本身的特色会比较少。而在 2022 年的第二届比赛,有很多队伍完成了所有测例,并开始尝试支持更大的应用程序。到了 2023 年的第三届比赛,参赛队伍不仅在自己的内核上运行比赛没有要求的应用程序,还支持了许多现代内核特性。

表中的大部分内核都是用 Rust 写的。如果你找得足够仔细的话,这些 Rust 内核都在文档里鸣谢了 rCore-Tutorial 或者直接使用了它的的代码,因此学习 rCore-Tutorial 本身会对你理解他们的代码有很大的帮助!当然,每一届的内核也会参照往届其他内核的实现。在完成自己的内核时,不要忘了尝试运行一下这些优秀的内核,这会帮你节省很多 debug 的时间。

运行注意事项

由于比赛包含一些未写明的机制、评测机环境、测例约定,所以尝试运行它们可能会遇到一些问题

  • 如果是 2022 或 2023 年的作品,且赛后在 github 上有维护,那么大概率可以直接运行,不会和比赛环境有太大联系。本实验要用的 Starry 也是这种模式,且目前仍然在持续更新。
  • 如果是来自 gitlab 的链接,那么有可能这个内核只能在比赛环境运行,我们想在赛后运行它可能要花一些功夫。

具体来说,可能有以下问题

Rust 编译器版本

目前所有比赛中的 Rust 内核以及 rCore-Tutorial 都是用 rust-nightly 版本。在项目的根目录下,运行 cargo --version 即可查看项目使用的 Rust 版本。nightly 的更新非常频繁,包含许多不稳定的特性,而这些特性随时可能改动。所以往年比赛时用的 nightly 版本现在可能已经不再适用

这个版本记录在项目的根目录下的 rust-toolchain.toml 或者 rust-toolchain 文件中。如果没有这个文件,则会使用默认版本(一般是本机的架构的稳定版,x86_64arm64)。例如 Starryrust-toolchain.toml 写的是

[toolchain]
profile = "minimal"
channel = "nightly"
components = ["rust-src", "llvm-tools-preview", "rustfmt", "clippy"]
targets = ["x86_64-unknown-none", "riscv64gc-unknown-none-elf", "aarch64-unknown-none-softfloat"]

channel = "nightly" 意味着这个项目会主动跟随最新的 cargo 版本。这个内核在持续开发中,会及时修正代码中的版本冲突。

NPUcorerust-toolchain 写的是

nightly-2022-04-11

这是当年比赛要求使用的版本。直接尝试运行这个内核不会有太大问题,Rust 会自动下载 nightly-2022-04-11 这个版本。但如果你想在这个内核上继续开发,那么为了避免和新的库冲突,最好还是把它换成最新的版本,然后修改必要的特性和代码。

还有一种情况是 Oops,此时内核没有指定 rust-toolchain.toml 或者 rust-toolchain ,因此你在运行它时会默认采用最新的 cargo。但这个内核开发时的环境(指那一年评测机环境和队员的本地环境)其实是 nightly-2022-04-11,所以直接运行时可能会报错。给它加上一个和上面提到的 NPUcore 同样的版本文件可以规避掉这个问题。

评测机和离线编译

平时我们联网编译内核时,包管理器兼编译器 cargo 会根据 Cargo.toml 文件在包管理平台或者指定的 git 仓库下载到本地的 ~/.cargo 目录下作为缓存(除非依赖指定的是本地的路径),然后再进行编译。但在指定离线编译的情况下,包管理器只能找到找本地 ~/.cargo 里有的库和用相对路径指定的库。

至少从前三届的比赛来看,评测机是不联网的。评测机的 ~/.cargo 目录自带一些常用的库,这些库通常会在评测页面列出。但如果内核要用其他的库,就只能把它“复制粘贴”到自己的项目里了。以 FTLOS 为例,它的 Cargo.toml 里就有一些网上开源的库,但因为评测机上没有,所以只能复制到 ../dependencies 目录下使用了。

当然,引发问题的通常不是这些库,而是评测机本地有,但你的本地没有的库。由于指定了离线编译,所以编译器只会在 ~/.cargo 下试图找这些库,找不到时就会报错。此时只要把离线编译关掉就好了。离线编译是通过 --offline 形式指定的。一般来说,如果你看到内核目录的 Makefile 里有

cargo build --offline

那么把 --offline 删掉就可以了,这会迫使 cargo 联网去找这些库。比如 ByteOS 的实现 就是如此。如果内核 Makefile 写得比较花,也可能用其他方式传参,比如 FTLOS 的实现 就是藏在根目录下。你可以全局搜索 --offline 来找这个选项。

默认运行的文件

在比赛中,内核的编译使用的是每个队伍自己代码仓库里的 Makefile,但加载和运行会使用评测机上的脚本。

以大家熟悉的 rCore-Tutorial 为例,make run 时会先编译出一个内核镜像 os.bin,然后这个内核镜像与 RustSBI、文件系统镜像一起作为参数被扔给 Qemu 运行。对应到比赛中,就是评测机先调用项目根目录下 make all 得到 os.bin,然后再用一套自己的脚本去配置实机或 Qemu 并运行。这套脚本与每个队伍代码仓库中的运行方式无关,所以如果你的配置和它不太一样,就可能无法正确运行。例如 2022 年比赛中,评测机会将官方指定的文件系统镜像直接映射到物理内存的 [0x9000_0000, cfff_ffff),有一些参赛队会默认按这个逻辑实现。

不过,本节开头列出的内核都可以不依赖评测机环境、根据 README 指引生成文件系统镜像并运行。所以只有在运行其他参赛内核时你才需要担心这个问题。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""