引言¶
本章导读¶
本章的目标是实现分时多任务系统,它能并发地执行多个用户程序,并调度这些程序。为此需要实现
一次性加载所有用户程序,减少任务切换开销;
支持任务切换机制,保存切换前后程序上下文;
支持程序主动放弃处理器,实现 yield 系统调用;
以时间片轮转算法调度用户程序,实现资源的时分复用。
实践体验¶
注解
基于github classroom的开发方式
基于github classroom,可方便建立开发用的git repository,并可基于github的 codespace (在线版ubuntu +vscode)在线开发使用。整个开发环境仅仅需要一个网络浏览器。
在网络浏览器中用自己的 github id 登录 github.com
接收 第一个实验(os3)的github classroom在线邀请 ,根据提示一路选择OK即可。
完成第二步后,你的第一个实验的 github repository 会被自动建立好,点击此github repository的链接,就可看到你要完成的第一个实验了。
在你的第一个实验的网页的中上部可以看到一个醒目的 code 绿色按钮,点击后,可以进一步看到 codespace 标签和醒目的 create codesapce on main 绿色按钮。请点击这个绿色按钮,就可以进入到在线的ubuntu +vscode环境中
再按照下面的环境安装提示在vscode的 console 中安装配置开发环境:rustc,qemu等工具。注:也可在vscode的 console 中执行
make codespaces_setenv来自动安装配置开发环境(执行``sudo``需要root权限,仅需要执行一次)。在vscode的 console 中执行 make setupclassroom_test3 (该命令仅执行一次)配置githubclassroom 自动评分功能。
然后就可以基于在线vscode进行开发、运行、提交等完整的实验过程了。
上述的3,4,5步不是必须的,你也可以线下本地开发。
注:如果是本地的ubuntu中建立开发环境,可在shell中执行 make ubuntu_local_setenv 来自动安装配置开发环境(执行``sudo``需要root权限,仅需要执行一次)。
获取本章代码:
$ git clone ``gitaddr of github-classroom-build-lab1``
$ cd ``github-classroom-build-lab1``
$ make setupclassroom_test3 //注意:这一步很重要,是用于github classroom自动评测你的工作。这一步只需在首次克隆项目仓库时执行一次,以后一般就不用执行了,除非 .github/workflows/classroom.yml发生了变化。
注解
实验名称 :实验编号
lab0-0 : test1
lab0-1:test2
lab1:test3
lab2:test4
lab3:test5
lab4:test6
lab5:test8
在 qemu 模拟器上运行 lab1(os3)参考框架: :
$ cd os3
$ make run
运行代码,看到用户程序交替输出信息:
[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!
power_3 [10000/200000]
power_3 [20000/200000]
power_3 [30000/200000]
power_3 [40000/200000]
power_3 [50000/200000]
power_3 [60000/200000]
power_3 [70000/200000]
power_3 [80000/200000]
power_3 [90000/200000]
power_3 [100000/200000]
power_3 [110000/200000]
power_3 [120000/200000]
power_3 [130000/200000]
power_3 [140000/200000]
power_3 [150000/200000]
power_3 [160000/200000]
power_3 [170000/200000]
power_3 [180000/200000]
power_3 [190000/200000]
power_3 [200000/200000]
3^200000 = 871008973(MOD 998244353)
Test power_3 OK!
power_5 [10000/140000]
power_5 [20000/140000]
power_5 [30000/140000]
power_5 [40000/140000]
power_5 [50000/140000]
power_5 [60000/140000]
power_7 [10000/160000]
power_7 [20000/160000]
power_7 [30000/160000]
power_7 [40000/160000]
power_7 [50000/160000]
power_7 [60000/160000]
power_7 [70000/160000]
power_7 [80000/160000]
power_7 [90000/160000]
power_7 [100000/160000]
power_7 [110000/160000]
power_7 [120000/160000]
power_7 [130000/160000]
power_7 [140000/160000]
power_7 [150000/160000]
power_7 [160000/160000]
7^160000 = 667897727(MOD 998244353)
Test power_7 OK!
get_time OK! 42
current time_msec = 42
AAAAAAAAAA [1/5]
BBBBBBBBBB [1/5]
CCCCCCCCCC [1/5]
power_5 [70000/140000]
AAAAAAAAAA [2/5]
BBBBBBBBBB [2/5]
CCCCCCCCCC [2/5]
power_5 [80000/140000]
power_5 [90000/140000]
power_5 [100000/140000]
power_5 [110000/140000]
power_5 [120000/140000]
power_5 [130000/140000]
power_5 [140000/140000]
5^140000 = 386471875(MOD 998244353)
Test power_5 OK!
AAAAAAAAAA [3/5]
BBBBBBBBBB [3/5]
CCCCCCCCCC [3/5]
AAAAAAAAAA [4/5]
BBBBBBBBBB [4/5]
CCCCCCCCCC [4/5]
AAAAAAAAAA [5/5]
BBBBBBBBBB [5/5]
CCCCCCCCCC [5/5]
Test write A OK!
Test write B OK!
Test write C OK!
time_msec = 143 after sleeping 100 ticks, delta = 101ms!
Test sleep1 passed!
Test sleep OK!
Panicked at src/task/mod.rs:98 All applications completed!
lab1(os3)参考框架:¶
── os3
├── build.rs
├── Cargo.toml
├── Makefile
└── src
├── batch.rs(移除:功能分别拆分到 loader 和 task 两个子模块)
├── config.rs(新增:保存内核的一些配置)
├── console.rs
├── logging.rs
├── sync
├── entry.asm
├── lang_items.rs
├── link_app.S
├── linker.ld
├── loader.rs(新增:将应用加载到内存并进行管理)
├── main.rs(修改:主函数进行了修改)
├── sbi.rs(修改:引入新的 sbi call set_timer)
├── syscall(修改:新增若干 syscall)
│ ├── fs.rs
│ ├── mod.rs
│ └── process.rs
├── task(新增:task 子模块,主要负责任务管理)
│ ├── context.rs(引入 Task 上下文 TaskContext)
│ ├── mod.rs(全局任务管理器和提供给其他模块的接口)
│ ├── switch.rs(将任务切换的汇编代码解释为 Rust 接口 __switch)
│ ├── switch.S(任务切换的汇编代码)
│ └── task.rs(任务控制块 TaskControlBlock 和任务状态 TaskStatus 的定义)
├── timer.rs(新增:计时器相关)
└── trap
├── context.rs
├── mod.rs(修改:时钟中断相应处理)
└── trap.S
cloc os
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Rust 21 87 20 627
Assembly 4 12 22 144
make 1 11 4 36
TOML 1 2 1 10
-------------------------------------------------------------------------------
SUM: 27 112 47 817
-------------------------------------------------------------------------------