0%

2025秋冬季开源操作系统训练营-第三阶段总结-郑泉城

lab1: print_with_color

  • 本实验比较较为简单, 修改 arceos/exercises/print_with_color/src/main.rs 文件, 为 println 添加 ANSI 转义码即可. ANSI 转义码用于在终端中控制光标位置、文本颜色、文本样式等, 其以 ESC (Escape) 字符开头.
  • 初次在 Rust 中使用 \033[34m[WithColor]: Hello, Arceos!\033[0m 形式的 ANSI 转义码, 发现其不奏效; 但是在 C/C++ 中却是正常. 查阅资料后得知, \033 是 C 语言的传统写法, 在 C/C++ 中使用较多. 在 Rust 中, 应该使用 \x1b, 即 \x1b[34m[WithColor]: Hello, Arceos!\x1b[0m. 本是上来说, \033\x1b 是同一内容的不同表示.

lab2: support_hashmap

  • 本实验直接使用 hashbrown 来支持 hashmap. 在 arceos/ulib/axstd/Cargo.toml 中添加 hashbrown 依赖, 在 axstd 中添加 collections 模块, 并在 arceos/ulib/axstd/Cargo.toml 中声明 pub mod collections;. 在 collections 模块中, 使用 pub use alloc::collections::*;, 将 alloc::collections 的内容(比如 BTreeMap)导入当前的模块, 使用 pub use hashbrown::*; 将第三方库的 HashMap 等导入当前模块, 此时可以通过 axstd::collections 使用 HashMap(hashbrown 提供)、BTreeMap(alloc::collections 提供).
  • 还有一点要注意, 应该在启用 alloc feature 时才会声明并挂载 collections (#[cfg(feature = "alloc")]), 若不加以控制, print_with_color 则会出现报错. 原因在于, 若 collections 的编译不被 alloc feature 控制, 其中的 BTreeMap 等会依赖全局内存分配器, 但是因没有启用 alloc feature, 故而找不到全局内存分配器. 应该启用 alloc feature 时才会编译 collections.

lab3: alt_alloc

  • 此实验是实现简单的内存分配器, 在 arceos/modules/alt_axalloc/src/lib.rs 中具体实现.
  • arceos/exercises/alt_alloc/Cargo.toml 声明依赖 axstd: workspace = true 表明 axstd 是工作区成员; features = ["alt_alloc"] 使 axstd 开启 alt_alloc 特性. 当 axstdalt_alloc 特性被启用时, 其会继续将此传递下去, 还会根据 [features]alt_alloc = ["arceos_api/alt_alloc", "axfeat/alt_alloc"] 启用 arceos_api 中的 alt_alloc 特性和 axfeat 中的 alt_alloc 特性.

lab4: ramfs_rename

  • 实验要求在 arceos/axfs_ramfs 中实现 rename 操作, 但 arceos 原本依赖远程仓库的版本, 故需要调整.
  • 可以采用 patch 方式让工程临时使用 arceos/axfs_ramfs 的本地组件仓库. 为方便起见, 直接在 arceos/exercises/ramfs_rename/Cargo.toml 中将 axfs_ramfs = { version = "0.1", optional = true } 中的 version = "0.1" 替换为 workspace = true, 多次运行发现还是提示 Operation not supported. 然后对代码进行详细分析, 发现应用 ramfs_rename 会依赖 axfs(间接) 和 axfs_ramfs, axfs 还会依赖 axfs_ramfs, 此时 ramfs_rename 依赖的 axfs_ramfsaxfs 依赖的不同. 故还需将修改 arceos/modules/axfs/Cargo.toml, 替换 version = "0.1"workspace = true.
  • 具体实现 rename 功能, 只需修改 arceos/axfs_ramfs/src/dir.rs. 阅读测试用例后发现, 文件重命名只在同一个目录下操作, 故在具体实现中只考虑此情况, 并未做特殊处理.

lab5: sys_map

  • 初次运行 sys_map 时, 发现运行结果与课件中展示的内容有很大出入, 课件显示 not implement, 而本地运行则会显示 Cannot load app!. 经排查, 发现未设置 musl-libc, 导致无法编译出 mapfile 可执行文件.
  • 实现 sys_map 时针对测试用例做了简化处理, 未考虑复杂的情况. 实现 sys_mmap 系统调用主要有 5 个步骤: 获取当前进程的地址空间, 并在此查找空闲内存区域, 再准备参数执行内存映射, 再读取文件内容到缓冲区 buf 并将其写入映射的内存区域, 最后返回映射起始位置. 实现过程中, 务必查找空闲的内存区域再映射, 否则会出现 Mapping error: AlreadyExists.

lab6: simple_hv

  • 运行此实验代码, 发现QEMU会卡死. 经过仔细排查, 是由于 payload 构建失败导致的. 在外层 Makefile 中定义的 RUSTFLAGS 会被默认传递给 make -C ./payload 递归调用, 这会干扰编译 payload (尤其是 skernel). 故在 payloadMakefile 中添加 unexport RUSTFLAGS 来避免 RUSTFLAGS 变量的传播.
  • 正常运行后, 根据 panic 指示修改实现, 使测例通过即可. 在异常处理分支中, panic 改为 ax_println, 还要调整客户机的 spec, 即 ctx.guest_regs.sepc += 4;. 注意, 还要设置 A0 寄存器的值为 0x6688, A1 寄存器的值为 0x1234.