Files
rust-based-os-comp2022/guide/source/chapter2/0intro.rst
2022-07-03 13:42:31 +08:00

179 lines
8.8 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
引言
================================
本章导读
---------------------------------
**批处理系统** (Batch System) 出现于计算资源匮乏的年代,其核心思想是:
将多个程序打包到一起输入计算机;当一个程序运行结束后,计算机会 *自动* 执行下一个程序。
应用程序难免会出错,如果一个程序的错误导致整个操作系统都无法运行,那就太糟糕了。
*保护* 操作系统不受出错程序破坏的机制被称为 **特权级** (Privilege) 机制,
它实现了用户态和内核态的隔离。
本章在上一章的基础上,让我们的 OS 内核能以批处理的形式一次运行多个应用程序,同时利用特权级机制,
令 OS 不因出错的用户态程序而崩溃。
本章首先为批处理操作系统设计用户程序,再阐述如何将这些应用程序链接到内核中,最后介绍如何利用特权级机制处理 Trap.
实践体验
---------------------------
.. note::
基于github classroom的开发方式
基于github classroom可方便建立开发用的git repository并可基于github的 codespace 在线版ubuntu +vscode在线开发使用。整个开发环境仅仅需要一个网络浏览器。
1. 在网络浏览器中用自己的 github id 登录 github.com
2. 接收 `第二个实验练习的github classroom在线邀请 <https://classroom.github.com/a/UEOvz4qO>`_ 根据提示一路选择OK即可。
3. 完成第二步后,你的第二个实验练习的 github repository 会被自动建立好点击此github repository的链接就可看到你要完成的第一个实验了。
4. 在你的第二个实验练习的网页的中上部可以看到一个醒目的 `code` 绿色按钮,点击后,可以进一步看到 `codespace` 标签和醒目的 `create codesapce on main` 绿色按钮。请点击这个绿色按钮就可以进入到在线的ubuntu +vscode环境中
5. 再按照下面的环境安装提示在vscode的 `console` 中安装配置开发环境rustcqemu等工具。注也可在vscode的 `console` 中执行 ``make codespaces_setenv`` 来自动安装配置开发环境(执行``sudo``需要root权限仅需要执行一次
6. 在vscode的 `console` 中执行 `make setupclassroom_test2` 该命令仅执行一次配置githubclassroom 自动评分功能,以后一般就不用执行了,除非 ``.github/workflows/classroom.yml`` 发生了变化。
7. 然后就可以基于在线vscode进行开发、运行、提交等完整的实验过程了。
上述的345步不是必须的你也可以线下本地开发。
如果是本地的ubuntu中建立开发环境可在shell中执行 ``make ubuntu_local_setenv`` 来自动安装配置开发环境(执行``sudo``需要root权限仅需要执行一次
本章我们引入了用户程序。
获取本章代码:
.. code-block:: console
$ git clone ``gitaddr of github-classroom-build-lab0-1``
$ cd ``github-classroom-build-lab0-1``
$ make setupclassroom_test2 //注意这一步很重要是用于github classroom自动评测你的工作。这一步只需在首次克隆项目仓库时执行一次以后一般就不用执行了除非 .github/workflows/classroom.yml发生了变化。
.. note::
实验名称 :实验编号
- lab0-0 : test1
- lab0-1test2
- lab1test3
- lab2test4
- lab3test5
- lab4test6
- lab5test8
在 qemu 模拟器上运行本章代码:
.. code-block:: console
$ cd os2
$ make run LOG=INFO
批处理系统自动加载并运行了所有的用户程序,尽管某些程序出错了:
.. code-block::
[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!
[ INFO] [kernel] num_app = 6
[ INFO] [kernel] app_0 [0x8020b040, 0x8020f868)
[ INFO] [kernel] app_1 [0x8020f868, 0x80214090)
[ INFO] [kernel] app_2 [0x80214090, 0x80218988)
[ INFO] [kernel] app_3 [0x80218988, 0x8021d160)
[ INFO] [kernel] app_4 [0x8021d160, 0x80221a68)
[ INFO] [kernel] app_5 [0x80221a68, 0x80226538)
[ INFO] [kernel] Loading app_0
[ERROR] [kernel] PageFault in application, core dumped.
[ INFO] [kernel] Loading app_1
[ERROR] [kernel] IllegalInstruction in application, core dumped.
[ INFO] [kernel] Loading app_2
[ERROR] [kernel] IllegalInstruction in application, core dumped.
[ INFO] [kernel] Loading app_3
[ INFO] [kernel] Application exited with code 1234
[ INFO] [kernel] Loading app_4
Hello, world from user mode program!
[ INFO] [kernel] Application exited with code 0
[ INFO] [kernel] Loading app_5
3^10000=5079(MOD 10007)
3^20000=8202(MOD 10007)
3^30000=8824(MOD 10007)
3^40000=5750(MOD 10007)
3^50000=3824(MOD 10007)
3^60000=8516(MOD 10007)
3^70000=2510(MOD 10007)
3^80000=9379(MOD 10007)
3^90000=2621(MOD 10007)
3^100000=2749(MOD 10007)
Test power OK!
[ INFO] [kernel] Application exited with code 0
Panicked at src/batch.rs:68 All applications completed!
本章代码树
-------------------------------------------------
.. code-block::
── os2
│   ├── Cargo.toml
│   ├── Makefile (修改:构建内核之前先构建应用)
│   ├── build.rs (新增:生成 link_app.S 将应用作为一个数据段链接到内核)
│   └── src
│   ├── batch.rs(新增:实现了一个简单的批处理系统)
│   ├── console.rs
│   ├── entry.asm
│   ├── lang_items.rs
│   ├── link_app.S(构建产物,由 os/build.rs 输出)
│   ├── linker.ld
│   ├── logging.rs
│   ├── main.rs(修改:主函数中需要初始化 Trap 处理并加载和执行应用)
│   ├── sbi.rs
│   ├── sync(新增包装了RefCell暂时不用关心)
│   │   ├── mod.rs
│   │   └── up.rs
│   ├── syscall(新增:系统调用子模块 syscall)
│   │   ├── fs.rs(包含文件 I/O 相关的 syscall)
│   │   ├── mod.rs(提供 syscall 方法根据 syscall ID 进行分发处理)
│   │   └── process.rs(包含任务处理相关的 syscall)
│   └── trap(新增Trap 相关子模块 trap)
│   ├── context.rs(包含 Trap 上下文 TrapContext)
│   ├── mod.rs(包含 Trap 处理入口 trap_handler)
│   └── trap.S(包含 Trap 上下文保存与恢复的汇编代码)
└── user(新增:应用测例保存在 user 目录下)
├── Cargo.toml
├── Makefile
└── src
├── bin(基于用户库 user_lib 开发的应用,每个应用放在一个源文件中)
│   ├── ...
├── console.rs
├── lang_items.rs
├── lib.rs(用户库 user_lib)
├── linker.ld(应用的链接脚本)
└── syscall.rs(包含 syscall 方法生成实际用于系统调用的汇编指令,
各个具体的 syscall 都是通过 syscall 来实现的)
cloc os
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Rust 14 62 21 435
Assembly 3 9 16 106
make 1 12 4 36
TOML 1 2 1 9
-------------------------------------------------------------------------------
SUM: 19 85 42 586
-------------------------------------------------------------------------------