引言

本章导读

我们将开发一个用户 终端 (Terminal) 或 命令行 (Command Line Application, 俗称 Shell ) , 形成用户与操作系统进行交互的命令行界面 (Command Line Interface)。

为此,我们要对任务建立新的抽象: 进程 ,并实现若干基于 进程 的强大系统调用。

注解

任务和进程的关系与区别

第三章提到的 任务 是这里提到的 进程 的初级阶段,与任务相比,进程能在运行中创建 子进程 、 用新的 程序 内容覆盖已有的 程序 内容、可管理更多物理或虚拟 资源

实践体验

获取本章代码:

$ git clone https://github.com/LearningOS/rCore-Tutorial-Code-2024A.git
$ cd rCore-Tutorial-Code-2024A
$ git checkout ch5
$ git clone https://github.com/LearningOS/rCore-Tutorial-Test-2024A.git user

请仿照ch4的做法将代码在本地更新并push到自己的实验仓库中。

注意:user仓库有对ch5的测例更新,请重新clone或者使用git pull等获取。

在 qemu 模拟器上运行本章代码:

$ cd os
$ make run

待内核初始化完毕之后,将在屏幕上打印可用的应用列表并进入shell程序:

[rustsbi] RustSBI version 0.2.0-alpha.4
.______       __    __      _______.___________.  _______..______   __
|   _  \     |  |  |  |    /       |           | /       ||   _  \ |  |
|  |_)  |    |  |  |  |   |   (----`---|  |----`|   (----`|  |_)  ||  |
|      /     |  |  |  |    \   \       |  |      \   \    |   _  < |  |
|  |\  \----.|  `--'  |.----)   |      |  |  .----)   |   |  |_)  ||  |
| _| `._____| \______/ |_______/       |__|  |_______/    |______/ |__|

[rustsbi] Implementation: RustSBI-QEMU Version 0.0.1
[rustsbi-dtb] Hart count: cluster0 with 1 cores
[rustsbi] misa: RV64ACDFIMSU
[rustsbi] mideleg: ssoft, stimer, sext (0x222)
[rustsbi] medeleg: ima, ia, bkpt, la, sa, uecall, ipage, lpage, spage (0xb1ab)
[rustsbi] pmp0: 0x80000000 ..= 0x800fffff (rwx)
[rustsbi] pmp1: 0x80000000 ..= 0x807fffff (rwx)
[rustsbi] pmp2: 0x0 ..= 0xffffffffffffff (---)
[rustsbi] enter supervisor 0x80200000
[kernel] Hello, world!
/**** APPS ****
ch2b_bad_address
ch2b_bad_instructions
ch2b_bad_register
ch2b_hello_world
ch2b_power_3
ch2b_power_5
ch2b_power_7
ch3b_sleep
ch3b_sleep1
ch3b_yield0
ch3b_yield1
ch3b_yield2
ch5b_exit
ch5b_forktest
ch5b_forktest2
ch5b_forktest_simple
ch5b_forktree
ch5b_initproc
ch5b_user_shell
**************/
Rust user shell
>>

可以通过输入ch5b开头的应用来测试ch5实现的fork等功能:

>> ch5b_forktest_simple

sys_wait without child process test passed!
parent start, pid = 2!
ready waiting on parent process!
hello child process!
child process pid = 3, exit code = 100
Shell: Process 2 exited with code 0

本章代码树

 1├── os
 2   ├── build.rs(修改:基于应用名的应用构建器)
 3   ├── ...
 4   └── src
 5       ├── ...
 6       ├── loader.rs(修改:基于应用名的应用加载器)
 7       ├── main.rs(修改)
 8       ├── mm(修改:为了支持本章的系统调用对此模块做若干增强)
 9       │   ├── address.rs
10       │   ├── frame_allocator.rs
11       │   ├── heap_allocator.rs
12       │   ├── memory_set.rs
13       │   ├── mod.rs
14       │   └── page_table.rs
15       ├── syscall
16       │   ├── fs.rs(修改:新增 sys_read)
17       │   ├── mod.rs(修改:新的系统调用的分发处理)
18       │   └── process.rs(修改:新增 sys_getpid/fork/exec/waitpid)
19       ├── task
20       │   ├── context.rs
21       │   ├── manager.rs(新增:任务管理器,为上一章任务管理器功能的一部分)
22       │   ├── mod.rs(修改:调整原来的接口实现以支持进程)
23       │   ├── pid.rs(新增:进程标识符和内核栈的 Rust 抽象)
24       │   ├── processor.rs(新增:处理器管理结构 ``Processor`` ,为上一章任务管理器功能的一部分)
25       │   ├── switch.rs
26       │   ├── switch.S
27       │   └── task.rs(修改:支持进程机制的任务控制块)
28       └── trap
29           ├── context.rs
30           ├── mod.rs(修改:对于系统调用的实现进行修改以支持进程系统调用)
31           └── trap.S
32
33cloc os
34-------------------------------------------------------------------------------
35Language                     files          blank        comment           code
36-------------------------------------------------------------------------------
37Rust                            29            180            138           2049
38Assembly                         4             20             26            229
39make                             1             11              4             36
40TOML                             1              2              1             13
41-------------------------------------------------------------------------------
42SUM:                            35            213            169           2327
43-------------------------------------------------------------------------------