> For the complete documentation index, see [llms.txt](https://rcore.gitbook.io/rust-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rcore.gitbook.io/rust-os-docs/zheng-ti-jia-gou-he-qi-dong-guo-cheng.md).

# 整体架构和启动过程

## 项目文件夹

#### root

```
.
├── README.md
├── status.md   支持状态文档
├── docs        各种文档，包含课程报告等
├── kernel      内核主项目目录
├── user        用户程序开发环境
├── crate       从内核中独立出去的库，包含内存管理、进程管理等
└── riscv-pk    BBL for RV32
```

#### kernel

```
.
├── src           代码目录
│   ├── arch      平台相关部分代码
│   │   ├── riscv32
│   │   └── x86_64
│   ├── xxx.rs    平台无关部分代码
│   └── ...
├── target        生成文件目录
├── Cargo.lock    cargo依赖锁定文件
├── Cargo.toml    cargo项目配置文件
├── build.rs      cargo build 前会执行的build脚本
├── Makefile
├── riscv32-blog_os.json    riscv32的target配置文件
└── x86_64-blog_os.json     x86_64的target配置文件
```

#### crate

```
.
├── bbl            bbl接口库
├── bit-allocator  线段树实现的0-N整数分配器，用来快速分配物理页
├── memory         内存管理模块
├── process        进程管理模块
├── riscv          riscv底层支持模块(Fork: rust-embedded/riscv)
└── sync           基于std的同步互斥测试程序
```

#### user

```
.
├── Cargo.lock
├── Cargo.toml
├── Makefile
├── riscv32-ucore.json    用于用户程序的target配置文件
├── x86_64-ucore.json     ……
├── src
│   └── bin
│       └── hello.rs      用户程序
├── ucore-ulib            RustOS的用户程序库
# 以上用于编写Rust用户程序

# 以下是现有二进制用户程序打包的磁盘镜像，未来可能被替代
├── ucore32.img           ucore x86-32用户程序 SFS磁盘镜像
├── user-riscv.img        ucore rv32用户程序 SFS磁盘镜像
└── xv6_64.img            xv6-x86_64用户程序 ……
```

## 启动过程概览

整体上和原版ucore一致，只是实现细节有所不同。

#### Boot

首先由Bootloader为Kernel配置好运行环境，设置好栈寄存器，跳转到Rust代码。

* riscv32：`arch/riscv32/mod.rs::rust_main()`
* x86\_64：`arch/x86_64/mod.rs::_start()`

#### 平台初始化

以x86\_64为例，上面的函数依次执行以下初始化工作：

1. Log模块初始化：设置全局Logger，此后即可使用`debug!`等宏输出不同等级的调试信息，它们会在终端中以彩色显示。
2. 中断初始化：设置中断向量表，此后中断处理函数即可工作。
3. 内存初始化：根据bootloader传来的内存信息……
   1. 初始化物理帧分配器，此后页表即可工作
   2. 为内核构造新的页表并启用（已废弃，转移到bootloader）
   3. 初始化堆分配器：此后即可在堆上分配内存，并使用core中如Vec、BTreeSet等强力工具。
4. GDT和TSS初始化：后面用户程序要用到
5. 设备初始化：PIC/APIC，时钟，串口，键盘

RISCV下则相对简单：

1. Log模块初始化
2. 中断初始化
3. 内存初始化：……
4. 时钟初始化

执行完毕后，跳转到kmain函数。

#### 线程初始化

初始化线程管理器，并添加当前线程和idle线程。

#### 进入Kernel Shell

它作为一个内核线程运行。首先加载用户程序磁盘数据，x86\_64下通过IDE磁盘读取，riscv32下将磁盘文件硬连接到kernel中，通过内存读取。然后使用SFS库解析磁盘内容，根据用户输入的程序名，将相应用户程序数据读取到内存。使用ELF库解析用户程序内容，设置好页表映射，创建新的线程。

#### 执行线程切换

Kernel Shell在为用户程序创建好新的线程后，会主动wait它，触发调度，切换到此线程执行。根据其初始内核栈帧的设置，上下文切换后它将进入用户态执行。

当用户程序运行一段时间后，可能由于系统调用、时钟中断、发生异常等原因，进入中断处理函数，并发生线程切换。

当用户程序主动或被动地退出后，它所占用的资源会被回收，Kernel Shell被唤醒，上述过程循环往复。

###
