练习
在先前 Lab4 和 Lab5 的基础上继续添加功能.
当前的 I/O 实现
Section titled “当前的 I/O 实现”内核目前支持的 I/O 操作仅限于标准输出的写入,通过 sys_write 系统调用实现. 该系统调用定义在 kernel/src/syscall/fs.rs 中:
当用户程序调用 sys_write(1, buf, len) 时,内核将 buf 指针处长度为 len 的字节序列解释为 UTF-8 字符串,通过 print! 宏输出到控制台。print! 宏最终调用了 SBI 的 console_putchar 接口,将每个字符逐一发送到 QEMU 虚拟机的 UART 设备.
实现 alloc_fd() 函数,实现对于 fd 文件描述符的最小分配,从 fd_table 中找到一个空闲槽位 (None),如果找到就返回编号;如果找不到则再表尾添加一个空闲槽位并返回新槽位的索引.
然后实现 sys_write, sys_read, sys_open 和 sys_close,你可以参考我们先前提到的代码样例:
出于简化考虑,所有错误返回值均为 -1,正确返回时返回 fd 或者 0.
对于 sys_write 和 sys_read,获取当前任务的 inner 之后,各自检查是否可写、可读. 然后将用户态缓冲区翻译成 UserBuffer 后调用文件的 write 和 read 方法.
sys_open 把路径从用户态翻译成 &str后,打开文件. 如果返回 Some(inode),再分配描述符并存入 fd_table,返回 fd;失败返回 -1.
sys_close 获取可变 inner 后,依次判断 fd 是否越界或对应项是否为 None(两种情况都返回 -1). 合法时把文件描述符移除即可,最后返回 0.
可以使用 make test CHAPTER=6 进行本地测试. 完成后上传评测.