# 整体架构和启动过程

## 项目文件夹

#### 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被唤醒，上述过程循环往复。

###


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rcore.gitbook.io/rust-os-docs/zheng-ti-jia-gou-he-qi-dong-guo-cheng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
