0%
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 特性. 当 axstd 的 alt_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_ramfs 与 axfs 依赖的不同. 故还需将修改 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). 故在 payload 的 Makefile 中添加 unexport RUSTFLAGS 来避免 RUSTFLAGS 变量的传播.
- 正常运行后, 根据
panic 指示修改实现, 使测例通过即可. 在异常处理分支中, panic 改为 ax_println, 还要调整客户机的 spec, 即 ctx.guest_regs.sepc += 4;. 注意, 还要设置 A0 寄存器的值为 0x6688, A1 寄存器的值为 0x1234.