diff --git "a/source/_posts/2025\347\247\213\345\206\254\345\255\243\345\274\200\346\272\220\346\223\215\344\275\234\347\263\273\347\273\237\350\256\255\347\273\203\350\220\245-\347\254\254\344\270\211\351\230\266\346\256\265\346\200\273\347\273\223-\351\203\221\346\263\211\345\237\216.md" "b/source/_posts/2025\347\247\213\345\206\254\345\255\243\345\274\200\346\272\220\346\223\215\344\275\234\347\263\273\347\273\237\350\256\255\347\273\203\350\220\245-\347\254\254\344\270\211\351\230\266\346\256\265\346\200\273\347\273\223-\351\203\221\346\263\211\345\237\216.md" new file mode 100644 index 00000000000..c7be4577fcb --- /dev/null +++ "b/source/_posts/2025\347\247\213\345\206\254\345\255\243\345\274\200\346\272\220\346\223\215\344\275\234\347\263\273\347\273\237\350\256\255\347\273\203\350\220\245-\347\254\254\344\270\211\351\230\266\346\256\265\346\200\273\347\273\223-\351\203\221\346\263\211\345\237\216.md" @@ -0,0 +1,32 @@ +--- +title: 2025秋冬季开源操作系统训练营-第三阶段总结-郑泉城 +date: 2025-11-16 19:26:30 +tags: + - author: ZhengQuancheng +mathjax: true +--- + +## 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`.