Skip to content

Commit c6cfe5f

Browse files
committed
Merge remote-tracking branch 'origin/master' into simplify
# Conflicts: # SUMMARY.md # chapter1/part1.md # chapter1/part2.md # chapter1/part3.md # chapter2/part2.md # chapter2/part3.md # chapter2/part4.md # chapter2/part7.md # chapter3/part4.md # chapter8/part1.md # chapter9/part1.md
2 parents 8363f62 + 9464ffe commit c6cfe5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+506
-68
lines changed

README.md

+17-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
1-
# Introduction
1+
# rCore Tutorial
2+
3+
这是一个展示如何从零开始用 Rust 语言写一个基于 64 位 RISC-V 架构的操作系统的教程。完成这个教程后,你将可以在内核上运行用户态终端,并在终端内输入命令运行其他程序。
4+
5+
## 代码仓库
6+
7+
左侧章节目录中含有一对方括号"[ ]"的小节表示这是一个存档点,即这一节要对最近几节的代码进行测试。所以我们对每个存档点都设置了一个 commit 保存其完整的状态以供出现问题时参考。
8+
9+
与章节相对应的代码可以很容易的找到。章节标题下提供了指向下一个存档点代码状态的链接。
10+
11+
## 评论区
12+
13+
对于章节内容有任何疑问及建议,请在对应页面最下面的评论区中发表观点。注意需要用 Github ID 登录后才能评论。
14+
15+
16+
17+
好了,那就让我们正式开始!

SUMMARY.md

+17-17
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,58 @@
55
* [安装 nightly rust](chapter1/part1.md)
66
* [使用包管理器 cargo 创建 rust binary 项目](chapter1/part2.md)
77
* [移除标准库依赖](chapter1/part3.md)
8-
* [移除 runtime 依赖](chapter1/part4.md)
8+
* [[移除 runtime 依赖]](chapter1/part4.md)
99
* [总结与展望](chapter1/part5.md)
1010
* [第二章:最小化内核](chapter2/introduction.md)
1111
* [使用目标三元组描述目标平台](chapter2/part1.md)
1212
* [编译、生成内核镜像](chapter2/part2.md)
1313
* [使用链接脚本指定内存布局](chapter2/part3.md)
14-
* [重写程序入口点 _start](chapter2/part4.md)
15-
* [使用 Qemu 运行内核](chapter2/part5.md)
14+
* [[重写程序入口点 _start]](chapter2/part4.md)
15+
* [[使用 Qemu 运行内核]](chapter2/part5.md)
1616
* [封装 SBI 接口](chapter2/part6.md)
17-
* [实现格式化输出](chapter2/part7.md)
17+
* [[实现格式化输出]](chapter2/part7.md)
1818
* [总结与展望](chapter2/part8.md)
1919
* [第三章:中断](chapter3/introduction.md)
2020
* [rv64中断介绍](chapter3/part1.md)
21-
* [手动触发断点中断](chapter3/part2.md)
21+
* [[手动触发断点中断]](chapter3/part2.md)
2222
* [程序运行上下文环境](chapter3/part3.md)
23-
* [实现上下文环境保存与恢复](chapter3/part4.md)
24-
* [时钟中断](chapter3/part5.md)
23+
* [[实现上下文环境保存与恢复]](chapter3/part4.md)
24+
* [[时钟中断]](chapter3/part5.md)
2525
* [总结与展望](chapter3/part6.md)
2626
* [第四章:内存管理](chapter4/introduction.md)
27-
* [物理内存探测与管理](chapter4/part1.md)
28-
* [动态内存分配](chapter4/part2.md)
27+
* [[物理内存探测与管理]](chapter4/part1.md)
28+
* [[动态内存分配]](chapter4/part2.md)
2929
* [总结与展望](chapter4/part3.md)
3030
* [第五章:内存虚拟化](chapter5/introduction.md)
3131
* [页表:从虚拟内存到物理内存](chapter5/part1.md)
3232
* [内核初始映射](chapter5/part2.md)
3333
* [内核重映射](chapter5/part3.md)
3434
* [内核重映射实现之一:页表](chapter5/part4.md)
3535
* [内核重映射实现之二:MemorySet](chapter5/part5.md)
36-
* [内核重映射实现之三:完结](chapter5/part6.md)
36+
* [[内核重映射实现之三:完结]](chapter5/part6.md)
3737
* [总结与展望](chapter5/part7.md)
3838
* [第六章:内核线程](chapter6/introduction.md)
3939
* [线程状态与保存](chapter6/part1.md)
4040
* [线程切换](chapter6/part2.md)
4141
* [内核线程初始化](chapter6/part3.md)
42-
* [内核线程创建与切换测试](chapter6/part4.md)
42+
* [[内核线程创建与切换测试]](chapter6/part4.md)
4343
* [总结与展望](chapter6/part5.md)
4444
* [第七章:线程调度](chapter7/introduction.md)
4545
* [线程池与线程管理](chapter7/part1.md)
4646
* [内核调度线程 idle](chapter7/part2.md)
4747
* [线程调度之 Round Robin算法](chapter7/part3.md)
48-
* [线程调度测试](chapter7/part4.md)
48+
* [[线程调度测试]](chapter7/part4.md)
4949
* [总结与展望](chapter7/part5.md)
5050
* [第八章:用户线程](chapter8/introduction.md)
51-
* [编写用户程序](chapter8/part1.md)
51+
* [[编写用户程序]](chapter8/part1.md)
5252
* [在内核中实现系统调用](chapter8/part2.md)
5353
* [创建虚拟内存空间](chapter8/part3.md)
54-
* [创建用户线程](chapter8/part4.md)
54+
* [[创建用户线程]](chapter8/part4.md)
5555
* [总结与展望](chapter8/part5.md)
5656
* [第九章:文件系统](chapter9/introduction.md)
57-
* [使用文件系统](chapter9/part1.md)
58-
* [实现记事本](chapter9/part2.md)
59-
* [实现终端](chapter9/part3.md)
57+
* [[使用文件系统]](chapter9/part1.md)
58+
* [[实现记事本]](chapter9/part2.md)
59+
* [[实现终端]](chapter9/part3.md)
6060
* [总结与展望](chapter9/part4.md)
6161

6262

chapter1/introduction.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
# 第一章:独立化可执行程序
1+
## 第一章:独立化可执行程序
2+
3+
### 本章概要
24

3-
## 本章概要
45
这一章你将会学到:
56

67
* 如何移除对现有操作系统的依赖,构建一个独立化可执行rust程序。
8+

chapter1/part1.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 安装 nightly Rust
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/9900fd9c751761d262594053576ace8590610261)
4+
35
我们首先使用如下命令安装 Rust 工具链管理器 rustup 和 Rust 包管理器 cargo:
46

57
```bash

chapter1/part2.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 使用包管理器 cargo 创建 Rust binary 项目
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/9900fd9c751761d262594053576ace8590610261)
4+
35
使用 ``cargo new`` 创建一个新的 Rust binary 项目,命令如下:
46

57
```bash

chapter1/part3.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
## 移除标准库依赖
22

3-
项目默认是链接 Rust 标准库 std 的,它依赖于操作系统,因此我们需要显式将其禁用:
3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/9900fd9c751761d262594053576ace8590610261)
4+
5+
项目默认是链接 rust 标准库 std 的,它依赖于操作系统,因此我们需要显式将其禁用:
46

57
```rust
68
// src/main.rs

chapter1/part4.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 移除 runtime 依赖
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/9900fd9c751761d262594053576ace8590610261)
4+
35
对于大多数语言,他们都使用了 **运行时系统(runtime system)** ,这导致 main 并不是他们执行的第一个函数。
46

57
以 Rust 语言为例:一个典型的链接了标准库的 Rust 程序会首先跳转到 C runtime library 中的 **crt0(C runtime zero)** 进入C runtime 设置 C 程序运行所需要的环境(比如:创建堆栈,设置寄存器参数等)。
@@ -62,4 +64,4 @@ pub extern "C" fn _start() -> ! {
6264
6365
构建得到的可执行文件位置放在 ``os/target/debug/os`` 中。
6466
65-
迄今为止的代码可以在[这里]()找到,构建出现问题的话可以参考。
67+
迄今为止的代码可以在[这里](https://github.com/rcore-os/rCore_tutorial/tree/9900fd9c751761d262594053576ace8590610261)找到,构建出现问题的话可以参考。

chapter2/part1.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 使用目标三元组描述目标平台
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/1ba5fd7a1d7fc8794583ca1588a262916a20d707)
4+
35
cargo 在编译项目时,可以附加目标参数 `--target <target triple>` 设置项目的目标平台。平台包括硬件和软件支持,事实上, **目标三元组(target triple)** 包含:cpu 架构、供应商、操作系统和 [ABI](https://stackoverflow.com/questions/2171177/what-is-an-application-binary-interface-abi/2456882#2456882)
46

57
安装 Rust 时,默认编译后的可执行文件要在本平台上执行,我们可以使用

chapter2/part2.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 编译、生成内核镜像
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/1ba5fd7a1d7fc8794583ca1588a262916a20d707)
4+
35
### 使用 riscv64 目标编译项目
46

57
现在我们尝试用 riscv64 的目标来编译这个项目:

chapter2/part3.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 使用链接脚本指定程序内存布局
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/1ba5fd7a1d7fc8794583ca1588a262916a20d707)
4+
35
上一节中我们看到,编译出的程序默认被放到了从 0x10000 开始的位置上:
46

57
```

chapter2/part4.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 重写程序入口点 _start
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/1ba5fd7a1d7fc8794583ca1588a262916a20d707)
4+
35
我们在第一章中,曾自己重写了一个 C runtime 的入口点 ``_start`` ,在那里我们仅仅只是让它死循环。但是现在,类似 C runtime ,我们希望这个函数可以为我们设置内核的运行环境(不妨称为 kernel runtime ) 。随后,我们才真正开始执行内核的代码。
46

57
但是具体而言我们需要设置怎样的运行环境呢?

chapter2/part5.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 使用 Qemu 运行内核
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/3b1500685e14d7fe509d8b08e1e5eca4a299b022)
4+
35
### 安装模拟器 Qemu
46

57
如果你在使用 Linux (Ubuntu) ,需要到 Qemu 官方网站下载源码并自行编译,因为 Ubuntu 自带的软件包管理器 ``apt`` 中的 Qemu 的版本过低无法使用。参考命令如下:
@@ -153,6 +155,6 @@ run: build qemu
153155

154156
于是,我们可以使用 ``make run`` 来用 Qemu 加载内核镜像并运行。匆匆翻过一串长长的 OpenSBI 输出,我们看到了 ``OK`` !于是历经了千辛万苦我们终于将我们的内核跑起来了!
155157

156-
没有看到 OK ?迄今为止的代码可以在[这里]()找到,请参考。
158+
没有看到 OK ?迄今为止的代码可以在[这里](https://github.com/rcore-os/rCore_tutorial/tree/3b1500685e14d7fe509d8b08e1e5eca4a299b022)找到,请参考。
157159
下一节我们实现格式化输出来使得我们后续能够更加方便的通过输出来进行内核调试。
158160

chapter2/part6.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 封装 SBI 接口
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/8b1cfc9c84490b1a73817adb5bbcbb716453adb7)
4+
35
### 代码整理
46

57
将一切都写在一个 ``main.rs`` 中终究是一个不好的习惯,我们将代码分为不同模块整理一下。

chapter2/part7.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 实现格式化输出
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/8b1cfc9c84490b1a73817adb5bbcbb716453adb7)
4+
35
只能使用 ``console_putchar`` 这种苍白无力的输出手段让人头皮发麻。如果我们能使用 ``print!`` 宏的话该有多好啊!于是我们就来实现自己的 ``print!`` 宏!
46

57
我们将这一部分放在 ``src/io.rs`` 中,先用 ``console_putchar`` 实现两个基础函数:
@@ -129,3 +131,5 @@ pub extern "C" fn rust_main() -> ! {
129131
>
130132
131133
我们看到入口点的地址确实为我们安排的 ``0x80200000`` ,同时栈的地址也与我们在内存布局中看到的一样。更重要的是,我们现在能看到内核 ``panic`` 的位置了!这将大大有利于调试。
134+
135+
目前所有的代码可以在[这里](https://github.com/rcore-os/rCore_tutorial/tree/8b1cfc9c84490b1a73817adb5bbcbb716453adb7)找到。

chapter3/part2.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 手动触发断点中断
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/e40df6d48101f53a06e46e266372820ed8e17f33)
4+
35
我们引入一个对寄存器进行操作的库,这样就可以不用自己写了。
46
```rust
57
// Cargo.toml
@@ -68,5 +70,5 @@ pub extern "C" fn rust_main() -> ! {
6870
6971
可见在进入中断处理程序之前,硬件为我们正确的设置好了 ``scause,sepc`` 寄存器;随后我们正确的进入了设定的中断处理程序。
7072
71-
如果输出与预期不一致的话,可以在[这里]()找到目前的代码进行参考。
73+
如果输出与预期不一致的话,可以在[这里](https://github.com/rcore-os/rCore_tutorial/tree/e40df6d48101f53a06e46e266372820ed8e17f33)找到目前的代码进行参考。
7274

chapter3/part3.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 程序运行上下文环境
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/837b3cbf0603b642f2e2d47ffcbdf7dda58d3a0e)
4+
35
考虑在中断发生之前,程序的运行状态(比如说一个很重要的中间结果)保存在一些寄存器中。而中断发生时,硬件仅仅帮我们设置中断原因、中断地址,随后就根据 ``stvec`` 直接跳转到中断处理程序。而中断处理程序可能会修改了那个保存了重要结果的寄存器,而后,即使处理结束后使用 ``sret`` 指令跳回到中断发生的位置,原来的程序也会一脸懵逼:这个中间结果怎么突然变了?
46

57
> **[info] 函数调用与 calling convention**

chapter3/part4.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
## 实现上下文环境保存与恢复
22

3-
```asm
3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/837b3cbf0603b642f2e2d47ffcbdf7dda58d3a0e)
4+
5+
```riscv
46
# src/trap/trap.asm
57
68
.section.text
@@ -250,4 +252,4 @@ pub fn rust_trap(tf: &mut TrapFrame) {
250252
251253
可以看到,我们确实手动触发中断,调用了中断处理函数,并通过上下文保存与恢复机制保护了上下文环境不受到破坏,正确在 ``ebreak`` 中断处理程序返回之后 ``panic``。
252254
253-
迄今为止的代码可以在[这里]()找到。如果出现了问题的话就来检查一下吧。
255+
迄今为止的代码可以在[这里](https://github.com/rcore-os/rCore_tutorial/tree/837b3cbf0603b642f2e2d47ffcbdf7dda58d3a0e)找到。如果出现了问题的话就来检查一下吧。

chapter3/part5.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 时钟中断
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/da7ee0906a43681acf81d6d90fd2c1d372b39d06)
4+
35
在本节中,我们处理一种很重要的中断:时钟中断。这种中断我们可以设定为每隔一段时间硬件自动触发一次,在其对应的中断处理程序里,我们回到内核态,并可以对用户态的程序进行调度、监控管理他们对于资源的使用情况。
46

57
> **[info] riscv 中的中断寄存器**
@@ -191,4 +193,4 @@ fn panic(info: &PanicInfo) -> ! {
191193
> ...
192194
> ```
193195
194-
如果出现问题的话,可以在[这里]()找到目前的代码。
196+
如果出现问题的话,可以在[这里](https://github.com/rcore-os/rCore_tutorial/tree/da7ee0906a43681acf81d6d90fd2c1d372b39d06)找到目前的代码。

chapter4/introduction.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## 第四章:内存管理
2+
3+
### 本章概要
4+
5+
本章你将会学到:
6+
7+
* 物理内存的探测、分配和管理
8+
* 内核内部动态分配内存

chapter4/part1.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 物理内存探测与管理
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/0c11e42a2174f0cc76a275bfe8815b7aa47d8bec)
4+
35
我们知道,物理内存通常是一片 RAM ,我们可以把它看成一个以字节为单位的大数组,通过物理地址找到对应的位置进行读写。但是,物理地址**并不仅仅**只能访问物理内存,也可以用来访问其他的外设,因此你也可以认为物理内存也算是一种外设。
46

57
这样设计是因为:一开始访问其他外设与访问物理内存要使用不同的指令,会带来很多麻烦,于是我们通过 MMIO(Memory Mapped I/O) 技术将外设映射到一段物理地址,这样我们访问其他外设就和访问物理内存一样啦!
@@ -298,7 +300,7 @@ fn frame_allocating_test() {
298300
299301
我们回收的页面接下来马上就又被分配出去了。
300302
301-
如果结果有问题的话,在[这里]()能找到现有的代码。
303+
如果结果有问题的话,在[这里](https://github.com/rcore-os/rCore_tutorial/tree/0c11e42a2174f0cc76a275bfe8815b7aa47d8bec)能找到现有的代码。
302304
303305
不过,这种物理内存分配给人一种过家家的感觉。无论表面上分配、回收做得怎样井井有条,实际上都并没有对物理内存产生任何影响!不要着急,我们之后会使用它们的。
304306

chapter4/part2.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 动态内存分配
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/e0d003d70879db6b72f05142fe611ea7c19b551b)
4+
35
我们之前在 ``C/C++`` 语言中使用过 ``new, malloc`` 等动态内存分配方法,与在编译期就已完成的静态内存分配相比,动态内存分配可以根据程序运行时状态修改内存申请的时机及大小,显得更为灵活,但是这是需要操作系统的支持的,会带来一些开销。
46

57
我们的内核中也需要动态内存分配。典型的应用场景有:
@@ -164,4 +166,4 @@ fn dynamic_allocating_test() {
164166
165167
我们可以发现这些动态分配的变量可以使用了。而且通过查看它们的地址我们发现它们都在 $$\text{.bss}$$ 段里面。这是因为提供给动态内存分配器的那块内存就在 $$\text{.bss}$$ 段里面啊。
166168
167-
如果结果不太对劲,可以在[这里]()查看现有的代码。
169+
如果结果不太对劲,可以在[这里](https://github.com/rcore-os/rCore_tutorial/tree/e0d003d70879db6b72f05142fe611ea7c19b551b)查看现有的代码。

chapter4/part3.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
## 总结与展望
1+
## 总结与展望
2+
3+
本章我们介绍了物理内存管理:即物理页帧分配、回收;以及内核内部的动态内存分配,在 $$\text{.bss}$$ 端上一段预留的内存上进行。后面各章都会使用到这两个工具。

chapter5/part4.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 内核重映射实现之一:页表
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/ac0b0f2f658a9ae777356fb5151b08ccfeb30d57)
4+
35
首先我们来看如何实现页表。
46

57
### 访问物理内存

chapter5/part5.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 内核重映射实现之二:MemorySet
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/ac0b0f2f658a9ae777356fb5151b08ccfeb30d57)
4+
35
我们实现了页表,但是好像还不足以应对内核重映射的需求。我们要对多个段分别进行不同的映射,而页表只允许我们每次插入一对从虚拟页到物理页帧的映射。
46

57
为此,我们另设计几种数据结构来抽象这个过程:

chapter5/part6.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 内核重映射实现之三:完结
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/ac0b0f2f658a9ae777356fb5151b08ccfeb30d57)
4+
35
在内存模块初始化时,我们新建一个精细映射的 ``MemorySet`` 并切换过去供内核使用。
46
```rust
57
// src/memory/mod.rs
@@ -134,4 +136,4 @@ panicked at 'page fault!', src/interrupt.rs:65:5
134136
> ```
135137
136138
从中我们可以清楚的看出内核成功的找到了错误的原因,内核各段被成功的设置了不同的权限。我们达到了内核重映射的目的!
137-
目前的代码能在[这里]()找到。
139+
目前的代码能在[这里](https://github.com/rcore-os/rCore_tutorial/tree/ac0b0f2f658a9ae777356fb5151b08ccfeb30d57)找到。

chapter5/part7.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## 总结与展望
2+
3+
本章我们区分了物理内存和虚拟内存,并利用页表在他们中间建立联系。我们分析了内核初始映射的代码,并希望通过更加精细的映射使各段具有不同的权限。
4+
5+
我们使用 ``MemorySet -> MemoryArea -> MemoryHandler`` ,来以不同的方式调用页表 ``PageTableImpl`` 的接口,使得各段的映射方式不同。
6+
7+
``MemorySet`` 是内核给程序分配的虚拟内存空间,现在它只是给自己分配了一个,之后还会给其他用户程序分配。

chapter6/introduction.md

-2
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,3 @@
2020
* 内核线程的概念
2121
* 线程执行的状态表示与保存
2222
* 线程切换
23-
24-
代码可以在[这里]()找到。

chapter6/part1.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 线程状态与保存
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/ac0b0f2f658a9ae777356fb5151b08ccfeb30d57)
4+
35
如果将整个运行中的内核看作一个**内核进程**,那么一个**内核线程**只负责内核进程中**执行**的部分。虽然我们之前从未提到过内核线程的概念,但是在我们设置完启动栈,并跳转到 ``rust_main`` 之后,我们的第一个内核线程——**内核启动线程**就已经在运行了!
46

57
### 线程的状态

chapter6/part2.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 线程切换
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/ac0b0f2f658a9ae777356fb5151b08ccfeb30d57)
4+
35
我们要用这个函数完成线程切换:
46

57
```rust

chapter6/part3.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 内核线程初始化
22

3+
* [代码](https://github.com/rcore-os/rCore_tutorial/tree/ac0b0f2f658a9ae777356fb5151b08ccfeb30d57)
4+
35
回忆一下我们如何进行启动线程的初始化?无非两步:设置栈顶地址、跳转到内核入口地址。从而变为启动线程的初始状态,并准备开始运行。
46

57
其他线程的初始化也差不多。事实上我们要构造一个停止的线程状态,使得一旦其他的进程切换到它,就立刻变为我们想要的该线程的初始状态,并可以往下运行。

0 commit comments

Comments
 (0)