提交 b8bc2e77 编写于 作者: deathwish5's avatar deathwish5

chapter7 exercise

上级 b62bb485
......@@ -109,6 +109,7 @@ lab2 中,我们实现了第一个系统调用 ``sys_write``,这使得我们
3. 描述程序陷入内核的两大原因是中断和异常,请问 riscv64 支持那些中断/异常?如何判断进入内核是由于中断还是异常?描述陷入内核时的几个重要寄存器及其值。
4. 对于任何中断, ``__alltraps`` 中都需要保存所有寄存器吗?你有没有想到一些加速 ``__alltraps`` 的方法?简单描述你的想法。
报告要求
-------------------------------
......
chapter5 练习
==============================================
- 本节难度: **一定比lab4简单**
编程作业
---------------------------------------------
进程创建
+++++++++++++++++++++++++++++++++++++++++++++
大家一定好奇过为啥进程创建要用 fork + execve 这么一个奇怪的系统调用,就不能直接搞一个新进程吗?思而不学则殆,我们就来试一试!这章的编程练习请大家实现一个完全 DIY 的系统调用 spawn,用以创建一个新进程。
spawn 系统调用定义:
- syscall ID: 400
- C 接口: ``int spawn(char *filename)``
- Rust 接口: ``fn spawn(file: *const u8) -> isize``
- 功能:相当于 fork + exec,新建子进程并执行目标程序。
- 说明:成功返回子进程id,否则返回 -1。
- 可能的错误:
- 无效的文件名。
- 进程池满/内存不足等资源错误。
实验要求
+++++++++++++++++++++++++++++++++++++++++++++
- 实现分支:ch5。
- 完成实验指导书中的内容,实现进程控制,可以运行 usershell。
- 实现自定义系统调用 spawn,并通过 并通过 `Rust测例 <https://github.com/DeathWish5/rCore_tutorial_tests>`_ 中chapter5对应的所有测例。
challenge: 支持多核。
实验检查
+++++++++++++++++++++++++++++++++++++++++++++
- 实验目录要求
目录要求不变(参考lab1目录或者示例代码目录结构)。同样在 os 目录下 ``make run`` 之后可以正确加载用户程序并执行。
加载的用户测例位置: ``../user/build/bin``。
- 检查
可以正确 ``make run`` 执行,可以正确执行目标用户测例,并得到预期输出(详见测例注释)。
问答作业
--------------------------------------------
(1) fork + exec 的一个比较大的问题是 fork 之后的内存页/文件等资源完全没有使用就废弃了,针对这一点,有什么改进策略?
(2) 其实使用了题(1)的策略之后,fork + exec 所带来的无效资源的问题已经基本被解决了,但是今年来 fork 还是在被不断的批判,那么到底是什么正在"杀死"fork?可以参考 `论文 <https://www.microsoft.com/en-us/research/uploads/prod/2019/04/fork-hotos19.pdf>`_ ,**注意**:回答无明显错误就给满分,出这题只是想引发大家的思考,完全不要求看论文,球球了,别卷了。
(3) fork 当年被设计并称道肯定是有其好处的。请使用 **带初始参数** 的 spawn 重写如下 fork 程序,然后描述 fork 有那些好处。注意:使用"伪代码"传达意思即可,spawn接口可以自定义。可以写多个文件。
.. code-block:: rust
fn main() {
let a = get_a();
if fork() == 0 {
let b = get_b();
println!("a + b = {}", a + b);
exit(0);
}
println!("a = {}", a);
0
}
4. 描述进程执行的几种状态,以及 fork/exec/wait/exit 对与状态的影响。
报告要求
------------------------------------------------------------
* 简单总结本次实验与上个实验相比你增加的东西。(控制在5行以内,不要贴代码)
* 完成问答问题
* (optional) 你对本次实验设计及难度的看法。
\ No newline at end of file
......@@ -8,6 +8,7 @@
1process
2core-data-structures
3implement-process-mechanism
4exercise
MULTICS操作系统是侏罗纪的“霸王龙”操作系统。
UNIX操作系统是小巧聪明的“伤齿龙”操作系统。
\ No newline at end of file
chapter6 练习
===========================================
- 本节难度: **也就和lab3一样吧**
编程作业
-------------------------------------------
进程通信:邮件
+++++++++++++++++++++++++++++++++++++++++++
这一章我们实现了基于 pipe 的进程间通信,但是看测例就知道了,管道不太自由,我们来实现一套乍一看更靠谱的通信 syscall吧!本节要求实现邮箱机制,以及对应的 syscall。
- 邮箱说明:每个进程拥有唯一一个邮箱,基于“数据报”收发字节信息,利用环形buffer存储,读写顺序为 FIFO,不记录来源进程。每次读写单位必须为一个报文,如果用于接收的缓冲区长度不够,舍弃超出的部分(截断报文)。为了简单,邮箱中最多拥有16条报文,每条报文最大长度256字节。当邮箱满时,发送邮件(也就是写邮箱会失败)。不考虑读写邮箱的权限,也就是所有进程都能够随意给其他进程的邮箱发报。
**mailread**:
* syscall ID:401
* C接口: ``int mailread(void* buf, int len)``
* Rust接口: ``fn mailread(buf: *mut u8, len: usize)``
* 功能:读取一个报文,如果成功返回报文长度.
* 参数:
* buf: 缓冲区头。
* len:缓冲区长度。
* 说明:
* len > 256 按 256 处理,len < 队首报文长度且不为0,则截断报文。
* len = 0,则不进行读取,如果没有报文读取,返回-1,否则返回0,这是用来测试是否有报文可读。
* 可能的错误:
* 邮箱空。
* buf 无效。
**mailwrite**:
* syscall ID:402
* C接口: ``int mailwrite(int pid, void* buf, int len)``
* Rust接口: ``fn mailwrite(pid: usize, buf: *mut u8, len: usize)``
* 功能:向对应进程邮箱插入一条报文.
* 参数:
* pid: 目标进程id。
* buf: 缓冲区头。
* len:缓冲区长度。
* 说明:
* len > 256 按 256 处理,
* len = 0,则不进行写入,如果邮箱满,返回-1,否则返回0,这是用来测试是否可以发报。
* 可以向自己的邮箱写入报文。
* 可能的错误:
* 邮箱满。
* buf 无效。
实验要求
+++++++++++++++++++++++++++++++++++++++++++++
- 实现分支:ch6。
- 完成实验指导书中的内容,实现进程控制,可以基于 pipe 进行进程通信。
- 实现邮箱机制及系统调用,并通过 `Rust测例 <https://github.com/DeathWish5/rCore_tutorial_tests>`_ 中 chapter6 对应的所有测例。
challenge: 支持多核。
实验检查
++++++++++++++++++++++++++++++++++++++++++++++
- 实验目录要求
目录要求不变(参考lab1目录或者示例代码目录结构)。同样在 os 目录下 ``make run`` 之后可以正确加载用户程序并执行。
加载的用户测例位置: ``../user/build/bin``。
- 检查
可以正确 ``make run`` 执行,可以正确执行目标用户测例,并得到预期输出(详见测例注释)。
问答作业
-------------------------------------------
(1) 举出使用 pipe 的一个实际应用的例子。
(2) 假设我们的邮箱现在有了更加强大的功能,容量大幅增加而且记录邮件来源,可以实现“回信”。考虑一个多核场景,有 m 个核为消费者,n 个为生产者,消费者通过邮箱向生产者提出订单,生产者通过邮箱回信给出产品。
- 假设你的邮箱实现没有使用锁等机制进行保护,在多核情景下可能会发生那些问题?单核一定不会发生问题吗?为什么?
- 请结合你在课堂上学到的内容,描述读者写者问题的经典解决方案,必要时提供伪代码。
- 由于读写是基于报文的,不是随机读写,你有什么点子来优化邮箱的实现吗?
报告要求
---------------------------------------
* 简单总结本次实验与上个实验相比你增加的东西。(控制在5行以内,不要贴代码)
* 完成问答问题
* (optional) 你对本次实验设计及难度的看法。
\ No newline at end of file
......@@ -7,5 +7,6 @@
0intro
1file-descriptor
2pipe
3exercise
有团队协作能力的“迅猛龙”操作系统。
\ No newline at end of file
lab7 实验要求
================================================
- 本节难度: **综合难度较大,编程难度小**
编程作业
-------------------------------------------------
硬链接
++++++++++++++++++++++++++++++++++++++++++++++++++
你的电脑桌面是咋样的?是放满了图标吗?反正我的 windows 是这样的。显然很少人会真的吧可执行文件放到桌面上,桌面图标其实都是一些快捷方式。或者用 unix 的术语来说:软链接。为了减少工作量,我们今天来实现软链接的兄弟:[硬链接](https://en.wikipedia.org/wiki/Hard_link)。
硬链接要求两个不同的目录项指向同一个文件,在我们的文件系统中也就是两个不同名称目录项指向同一个磁盘块。本节要求实现三个系统调用 sys_linkat、sys_unlinkat、sys_stat。
**linkat**:
* syscall ID: 37
* 功能:创建一个文件的一个硬链接, `linkat标准接口 <https://linux.die.net/man/2/linkat>`_ 。
* C接口: ``int linkat(int olddirfd, char* oldpath, int newdirfd, char* newpath, unsigned int flags)``
* Rust 接口: ``fn linkat(olddirfd: i32, oldpath: *const u8, newdirfd: i32, newpath: *const u8, flags: u32) -> i32``
* 参数:
* olddirfd,newdirfd: 仅为了兼容性考虑,本次实验中始终为 AT_FDCWD (-100),可以忽略。
* flags: 仅为了兼容性考虑,本次实验中始终为 0,可以忽略。
* oldpath:原有文件路径
* newpath: 新的链接文件路径。
* 说明:
* 为了方便,不考虑新文件路径已经存在的情况(属于未定义行为),除非链接同名文件。
* 返回值:如果出现了错误则返回 -1,否则返回 0。
* 可能的错误
* 链接同名文件。
**unlinkat**:
* syscall ID: 35
* 功能:取消一个文件路径到文件的链接, `unlinkat标准接口 <https://linux.die.net/man/2/unlinkat>`_ 。
* C接口: ``int unlinkat(int dirfd, char* path, unsigned int flags)``
* Rust 接口: ``fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> i32``
* 参数:
* dirfd: 仅为了兼容性考虑,本次实验中始终为 AT_FDCWD (-100),可以忽略。
* flags: 仅为了兼容性考虑,本次实验中始终为 0,可以忽略。
* path:文件路径。
* 说明:
* 为了方便,不考虑使用 unlink 彻底删除文件的情况。
* 返回值:如果出现了错误则返回 -1,否则返回 0。
* 可能的错误
* 文件不存在。
**fstat**:
* syscall ID: 80
* 功能:获取文件状态。
* C接口: ``int fstat(int fd, struct Stat* st)``
* Rust 接口: ``fn fstat(fd: i32, st: *mut Stat) -> i32``
* 参数:
* fd: 文件描述符
* st: 文件状态结构体
.. code-block:: rust
#[repr(C)]
#[derive(Debug)]
pub struct Stat {
/// 文件所在磁盘驱动器号
pub dev: u64,
/// inode 文件所在 inode 编号
pub ino: u64,
/// 文件类型
pub mode: StatMode,
/// 硬链接数量,初始为1
pub nlink: u32,
/// 无需考虑,为了兼容性设计
pad: [u64; 7],
}
/// StatMode 定义:
bitflags! {
pub struct StatMode: u32 {
const NULL = 0;
/// directory
const DIR = 0o040000;
/// ordinary regular file
const FILE = 0o100000;
}
}
实验要求
+++++++++++++++++++++++++++++++++++++++++++++++++++++
- 实现分支:ch7。
- 完成实验指导书中的内容,实现基本的文件操作。
- 实现硬链接及相关系统调用,并通过 `Rust测例 <https://github.com/DeathWish5/rCore_tutorial_tests>`_ 中 chapter7 对应的所有测例。
challenge: 支持多核。
实验检查
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 实验目录要求
目录要求不变(参考lab1目录或者示例代码目录结构)。同样在 os 目录下 `make run` 之后可以正确加载用户程序并执行。
加载的用户测例位置: `../user/build/bin`。
- 检查
可以正确 `make run` 执行,可以正确执行目标用户测例,并得到预期输出(详见测例注释)。
问答作业
----------------------------------------------------------
1. 目前的文件系统只有单级目录,假设想要支持多级文件目录,请描述你设想的实现方式,描述合理即可。
2. 在有了多级目录之后,我们就也可以为一个目录增加硬链接了。在这种情况下,文件树中是否可能出现环路?你认为应该如何解决?请在你喜欢的系统上实现一个环路,描述你的实现方式以及系统提示、实际测试结果。
报告要求
-----------------------------------------------------------
* 简单总结本次实验与上个实验相比你增加的东西。(控制在5行以内,不要贴代码)
* 完成问答问题
* (optional) 你对本次实验设计及难度的看法。
\ No newline at end of file
......@@ -5,4 +5,6 @@
:hidden:
:maxdepth: 4
6exercise
最晚灭绝的“霸王龙”操作系统
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册