Skip to content

Commit 0c9c270

Browse files
committed
📃 docs: 修改 bug
1 parent 247173e commit 0c9c270

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

docs/初赛文档.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ chaos 是一个用 Rust 编写的基于 [2024 春夏季开源操作系统训练
2121
进程是操作系统中资源管理的基本单位,而线程是操作系统调度的基本单位。在 chaos 中,进程由 `Process` 结构体表示,线程由所属进程统一管理,二者的底层实现都是一个 `Task` 结构体。每个进程拥有独立的内核栈,同一进程下的线程则共享进程内核栈空间。
2222

2323
#### 2.1.1 进程控制块
24+
2425
```rust
25-
//os/src/task/process.rs
26+
// os/src/task/process.rs
2627

2728
/// Process Control Block
2829
pub struct ProcessControlBlock {
@@ -35,7 +36,7 @@ pub struct ProcessControlBlock {
3536
进程被分为可变和不可变两个部分管理。不可变部分仅包含 `PCB` 创建时就被分配的 `pid` ,而对于可变那部分我们封装为 `ProcessControlBlockInner` 由于进程的父进程和其锁管理的线程都需要持有其所有权,我们使用Rust的智能指针 `Arc` 将其包裹以确保异步安全性,而 `Arc` 在Rust中默认不可变,因此我们管理 `ProcessControlBlockInner` 时利用了Rust的内部可变性。我们封装了 `RefCell`
3637

3738
```rust
38-
//os/src/sync/up.rs
39+
// os/src/sync/up.rs
3940

4041
pub struct UPSafeCell<T> {
4142
/// inner data
@@ -61,7 +62,10 @@ impl<T> UPSafeCell<T> {
6162
`RefCell` 是 Rust 标准库中的一个类型,提供了在运行时进行可变借用检查的能力。它允许在单线程环境中进行内部可变性(interior mutability)。`Sync` 是一个标记 `trait`,表示类型可以安全地在多个线程间共享引用。`RefCell` 本身不是 `Sync` 的,因为它只在单线程环境中保证安全,因此我们通过 `unsafe impl` 声明,承诺 `UPSafeCell` 可以安全地在多线程环境中共享。在多核环境下,这种方法并不安全,只是一种在多核尚未实现的情况下的临时措施。
6263

6364
可变部分的内容如下:
65+
6466
```rust
67+
// os/src/task/process.rs
68+
6569
/// Inner of Process Control Block
6670
pub struct ProcessControlBlockInner {
6771
/// is zombie?
@@ -105,7 +109,10 @@ pub struct ProcessControlBlockInner {
105109
每个成员的作用如注释所述。我们通过对子进程持强引用,对父进程持弱引用来防止循环引用造成的内存泄漏。
106110

107111
#### 2.1.2 线程控制块
112+
108113
```rust
114+
// os/src/task/task.rs
115+
109116
/// Task control block structure
110117
pub struct TaskControlBlock {
111118
/// immutable
@@ -119,7 +126,10 @@ pub struct TaskControlBlock {
119126
`PCB` 的处理类似,我们也将 `TCB` 分为可变部分和不可变部分处理。这里不可变的部分是线程所属的父进程以及创建时就分配的内核栈位置,可变部分同样使用 `UPSafeCell` 管理。这里的实现是可以确保安全的,因为我们的OS仍是单核实现,且在我们的OS中, `Task` 作为程序执行的最小单位,也就是在多核环境下,一个 `Task` 只会在一个核心中执行。
120127

121128
可变部分的成员如下:
129+
122130
```rust
131+
// os/src/task/task.rs
132+
123133
pub struct TaskControlBlockInner {
124134
/// Resources of a task
125135
pub res: Option<TaskUserRes>,
@@ -162,7 +172,10 @@ chaos 采用了 stride 调度算法,算法描述如下:
162172
#### 2.1.4 异常与中断
163173

164174
chaos 支持响应来自内核态的中断,我们在进入中断时,将中断入口设置为内核中断处理函数的入口,这样就保证可以正确的处理内核态中断。
175+
165176
```rust
177+
// os/src/trap/mod.rs
178+
166179
/// set trap entry for traps happen in kernel(supervisor) mode
167180
fn set_kernel_trap_entry() {
168181
extern "C" {
@@ -184,7 +197,10 @@ chaos 暂时沿用了 rCore 的双地址空间机制,即内核与用户拥有
184197
#### 2.2.1 地址空间
185198

186199
chaos 使用 sv39 分页机制,拥有足够大的内存供内核与用户使用,因此我们直接指定了一个 `MMAP_BASE`(0x20000000)和 `STACK_TOP`(0x100000000)分别作为 mmap 的基地址和用户栈顶,将用户堆基地址固定放在应用程序 elf 文件末尾,并设置了一页的保护页
200+
187201
```rust
202+
// os/src/mm/memory_set.rs
203+
188204
let max_end_va: VirtAddr = max_end_vpn.into();
189205
let mut user_heap_base: usize = max_end_va.into();
190206
user_heap_base += PAGE_SIZE;
@@ -195,6 +211,8 @@ user_heap_base += PAGE_SIZE;
195211
在 chaos 中,内核与用户拥有各自的地址空间。内核的内存被恒等映射到了物理地址高处,而用户地址空间则是基于从elf文件中读取的数据进行物理页帧随机映射。在内核与用户相互切换时,需要用到一个跳板 `TRAMPOLINE` 页面,它被固定恒等映射到物理地址最高位处,且对于所有地址空间地址都相同,因此我们可以通过它来实现内核地址空间和用户地址空间之间的平滑切换。
196212

197213
```linkerscript
214+
// os/src/linker.ld
215+
198216
. = BASE_ADDRESS;
199217
skernel = .;
200218
stext = .;
@@ -205,12 +223,13 @@ user_heap_base += PAGE_SIZE;
205223
*(.text.trampoline);
206224
. = ALIGN(4K);
207225
*(.text .text.*)
208-
}
209226
```
210227

211228
关于物理页帧随机映射,我们使用了一个物理页帧分配器以管理所有物理页帧。对于单个物理页帧,我们遵循了 RAII 思想,这种思想也被广泛运用在我们内核的实现中。我们将一个物理页帧的生命周期绑定到一个 `FrameTracker` 变量上,当一个 `FrameTracker` 被创建的时候,我们需要从 `FRAME_ALLOCATOR` 中分配一个物理页帧:
212229

213230
```rust
231+
// os/src/mm/frame_allocator.rs
232+
214233
pub struct FrameTracker {
215234
pub ppn: PhysPageNum,
216235
}
@@ -227,7 +246,10 @@ impl FrameTracker {
227246
}
228247
```
229248
当一个 `FrameTracker` 生命周期结束被编译器回收的时候,我们需要将它控制的物理页帧回收到 `FRAME_ALLOCATOR`
249+
230250
```rust
251+
// os/src/mm/frame_allocator.rs
252+
231253
impl Drop for FrameTracker {
232254
fn drop(&mut self) {
233255
frame_dealloc(self.ppn);
@@ -238,6 +260,8 @@ impl Drop for FrameTracker {
238260
#### 2.2.3 内存管理相关数据结构
239261

240262
```rust
263+
// os/src/mm/memory_set.rs
264+
241265
/// address space
242266
pub struct MemorySet {
243267
/// page table
@@ -430,7 +454,7 @@ impl Fat32FS {
430454

431455
chaos 项目从初始化仓库到完成初赛的所有赛题,仅仅花费了一周的时间。在这七天里,我们实现了众多的 syscalls、文件系统的重构、 FAT32 的支持……这些成就,离不开队员们良好的沟通、相互的信任和夜以继日的努力。
432456

433-
在 chaos 的开发过程中,我们参考了许多优秀的开源项目,例如 [Linux](https://github.com/torvalds/linux)[Titanix](https://github.com/greenhandzpx/Titanixhttps://gitlab.eduxiji.net/202318123101314/oskernel2023-Titanix)[Main.os(2)(1)(1)](https://gitlab.eduxiji.net/202310008101520/oskernel2023-x) 等。不过,我们仅参考了这些项目的优秀思想,代码均是自己实现。
457+
在 chaos 的开发过程中,我们参考了许多优秀的开源项目,例如 [Linux](https://github.com/torvalds/linux)[Titanix](https://gitlab.eduxiji.net/202318123101314/oskernel2023-Titanix)[Main.os(2)(1)(1)](https://gitlab.eduxiji.net/202310008101520/oskernel2023-x) 等。不过,我们仅参考了这些项目的优秀思想,代码均是自己实现。
434458

435459
如此短的开发时间,注定了 chaos 会存在许多潜在的问题以及一些功能的缺失。在未来的时间里,我们会逐步将 chaos 进行重构,朝着更为完整的操作系统内核前进。
436460

0 commit comments

Comments
 (0)