提交 00a8a535 编写于 作者: Y Yifan Wu

Fix ex7 && complete code-intro of ch6

上级 e601d590
chapter5 练习
chapter5练习
==============================================
- 本节难度: **一定比lab4简单**
......
......@@ -155,5 +155,15 @@
实现流程概述
本章代码导读
-----------------------------------------------------
在本章第一节 :doc:`/chapter6/1file-descriptor` 中,我们引入了文件的概念,用它来代表进程可以读写的多种被内核管理的硬件/软件资源。进程必须通过系统调用打开一个文件,将文件加入到自身的文件描述符表中,才能通过文件描述符(也就是某个特定文件在自身文件描述符表中的下标)来读写该文件。
文件的抽象 Trait ``File`` 声明在 ``os/src/fs/mod.rs`` 中,它提供了 ``read/write`` 两个接口,可以将数据写入应用缓冲区抽象 ``UserBuffer`` ,或者从应用缓冲区读取数据。应用缓冲区抽象类型 ``UserBuffer`` 来自 ``os/src/mm/page_table.rs`` 中,它将 ``translated_byte_buffer`` 得到的 ``Vec<&'static mut [u8]>`` 进一步包装,不仅保留了原有的分段读写能力,还可以将其转化为一个迭代器逐字节进行读写,这在读写一些流式设备的时候特别有用。
在进程控制块 ``TaskControlBlock`` 中需要加入文件描述符表字段 ``fd_table`` ,可以看到它是一个向量,里面保存了若干实现了 ``File`` Trait 的文件,由于采用动态分发,文件的类型可能各不相同。 ``os/src/syscall/fs.rs`` 的 ``sys_read/write`` 两个读写文件的系统调用需要访问当前进程的文件描述符表,用应用传入内核的文件描述符来索引对应的已打开文件,并调用 ``File`` Trait 的 ``read/write`` 接口; ``sys_close`` 这可以关闭一个文件。调用 ``TaskControlBlock`` 的 ``alloc_fd`` 方法可以在文件描述符表中分配一个文件描述符。进程控制块的其他操作也需要考虑到新增的文件描述符表字段的影响,如 ``TaskControlBlock::new`` 的时候需要对 ``fd_table`` 进行初始化, ``TaskControlBlock::fork`` 中则需要将父进程的 ``fd_table`` 复制一份给子进程。
到本章为止我们支持两种文件:标准输入输出和管道。不同于前面章节,我们将标准输入输出分别抽象成 ``Stdin`` 和 ``Stdout`` 两个类型,并为他们实现 ``File`` Trait 。在 ``TaskControlBlock::new`` 创建初始进程的时候,就默认打开了标准输入输出,并分别绑定到文件描述符 0 和 1 上面。
管道 ``Pipe`` 是另一种文件,它可以用于父子进程间的单向进程间通信。我们也需要为它实现 ``File`` Trait 。 ``os/src/syscall/fs.rs`` 中的系统调用 ``sys_pipe`` 可以用来打开一个管道并返回读端/写端两个文件的文件描述符。管道的具体实现在 ``os/src/fs/pipe.rs`` 中,本章第二节 :doc:`/chapter6/2pipe` 中给出了详细的讲解。管道机制的测试用例可以参考 ``user/src/bin`` 目录下的 ``pipetest.rs`` 和 ``pipe_large_test.rs`` 两个文件。
\ No newline at end of file
chapter6 练习
chapter6练习
===========================================
- 本节难度: **也就和lab3一样吧**
......
......@@ -219,3 +219,5 @@
本章代码导读
-----------------------------------------------------
<To Be Continued>
\ No newline at end of file
chapter7 练习
chapter7练习
================================================
- 本节难度: **理解文件系统比较费事,编程难度适中**
......@@ -11,8 +11,35 @@ chapter7 练习
你的电脑桌面是咋样的?是放满了图标吗?反正我的 windows 是这样的。显然很少人会真的把可执行文件放到桌面上,桌面图标其实都是一些快捷方式。或者用 unix 的术语来说:软链接。为了减少工作量,我们今天来实现软链接的兄弟:[硬链接](https://en.wikipedia.org/wiki/Hard_link)。
硬链接要求两个不同的目录项指向同一个文件,在我们的文件系统中也就是两个不同名称目录项指向同一个磁盘块。本节要求实现三个系统调用 sys_linkat、sys_unlinkat、sys_stat。
硬链接要求两个不同的目录项指向同一个文件,在我们的文件系统中也就是两个不同名称目录项指向同一个磁盘块。本节要求实现三个系统调用 ``sys_linkat、sys_unlinkat、sys_stat`` 。注意在测例中 ``sys_open`` 的接口定义也发生了变化。
**open**
- syscall ID: 56
- 功能:打开一个文件,并返回可以访问它的文件描述符。
- C 接口: ``int open(int dirfd, char* path, unsigned int flags, unsigned int mode);``
- Rust 接口: ``fn open(dirfd: usize, path: *const u8, flags: u32, mode: u32);``
- 参数:
- **dirfd** : 仅为了兼容性考虑,本次实验中始终为 AT_FDCWD (-100)。可以忽略。
- **path** 描述要打开的文件的文件名(简单起见,文件系统不需要支持目录,所有的文件都放在根目录 ``/`` 下)
- **flags** 描述打开文件的标志,具体含义(其他参数不考虑):
.. code-block:: c
#define O_RDONLY 0x000
#define O_WRONLY 0x001
#define O_RDWR 0x002 // 可读可写
#define O_CREATE 0x200
- **mode** 仅在创建文件时有用,表示创建文件的访问权限,为了简单,本次实验中中统一为 *O_RDWR* 。
- 说明:
- 有 create 标志但文件存在时,忽略 create 标志,直接打开文件。
- 返回值:如果出现了错误则返回 -1,否则返回可以访问给定文件的文件描述符。
- 可能的错误:
- 文件不存在且无 create 标志。
- 标志非法(低两位为 0x3)
- 打开文件数量达到上限。
**linkat**:
* syscall ID: 37
......@@ -115,6 +142,13 @@ challenge: 支持多核。
可以正确 `make run` 执行,可以正确执行目标用户测例,并得到预期输出(详见测例注释)。
Tips
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 注意 ``sys_linkat`` 有 5 个参数,而原有的系统调用分发函数 ``syscall`` (位于 ``os/src/syscall/mod.rs`` 中)最多仅支持 3 个参数,因此我们需要进行拓展。这需要将 ``syscall`` 的函数签名中的 ``args`` 拓展为 ``[usize; 5]`` ,还需要对应调整 ``trap_handler`` 中对 ``syscall`` 的调用,从 Trap 上下文中获取更多通用寄存器放入参数 ``args`` 中。
问答作业
----------------------------------------------------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册