MIT6.828_LAB5_File system, Spawn and Shell

本文介绍了操作系统课程实验——MIT6.828的第五部分,涉及文件系统的设计和实现,包括文件元数据、块缓存、位图管理、文件操作、进程生成(spawn)和Shell。实验要求实现文件读写、块分配、进程状态设置等功能,并通过IPC实现文件系统服务。此外,还需改进fork和spawn以共享库状态,确保文件描述符在父子进程间正确共享。
摘要由CSDN通过智能技术生成

Lab 5: File system, Spawn and Shell

Introduction

本节中,我们将实现spawn,一个能够加载并运行硬盘上可执行文件的库调用,之后会扩招我们的jos内核和操作系统库使其能在控制台上运行shell,这些功能需要文件系统支持,本实验会介绍一个简单的读/写文件系统。

Getting Started

使用git获取并切换到分支lab5

athena% cd ~/6.828/lab
athena% add git
athena% git pull
Already up-to-date.
athena% git checkout -b lab5 origin/lab5
Branch lab5 set up to track remote branch refs/remotes/origin/lab5.
Switched to a new branch “lab5”
athena% git merge lab4
Merge made by recursive.

athena%

合并后进入fs目录,浏览该目录下的所有文件,以了解所有新内容。 此外,在用户和lib目录中还有一些与文件系统相关的新的源文件:

fs/fs.c Code that mainipulates the file system’s on-disk structure.
fs/bc.c A simple block cache built on top of our user-level page fault handling facility.
fs/ide.c Minimal PIO-based (non-interrupt-driven) IDE driver code.
fs/serv.c The file system server that interacts with client environments using file system IPCs.
lib/fd.c Code that implements the general UNIX-like file descriptor interface.
lib/file.c The driver for on-disk file type, implemented as a file system IPC client.
lib/console.c The driver for console input/output file type.
lib/spawn.c Code skeleton of the spawn library call.

在合并代码之后,确保pingpong,primes,forktree等程序能够通过测试,在开始练习1前注释掉 kern/init.c的ENV_CREATE(fs_fs)和lib/exit.c中的close_all().

File system preliminaries

本节中,我们要使用的文件系统要比大多是真正的文件系统(包括xv6 unix)简单.但是它已经足够提供以下基本功能了:创建,读取,写入,删除在一个分级的目录结构体下组织的文件。

我们在开发的只是一个单用户操作系统,它提供了足够的保护来抓取BUG,但不能保护多个相互怀疑的用户相互攻击。因此,我们的文件系统不支持UNIX的文件所有权或权限概念。与大多数UNIX文件系统一样,我们的文件系统目前也不支持硬链接、符号链接、时间戳或特殊设备文件。

On-Disk File System Structure

大多数UNIX文件系统将可用的硬盘空间划分为两种类型的区域:i节点区域和数据区。UNIX文件系统会为每个文件分配一个i节点,i节点中保留了对应文件的关键元数据,例如文件状态属性和指向其数据块的指针。数据区被划分为更大的数据块(一般是8KB大小也可能更大),文件系统在其中存储文件数据和目录元数据。目录项包含文件名和指向i节点的指针。如果文件系统中的多个目录项指向同一文件的i节点,则该文件称为硬链接文件,因为我们的文件系统不支持硬链接,所以我们不需要该级别的间接寻址,因此可以方便的简化,我们的文件系统也根本不会使用索引节点,而只会在描述该文件的(唯一)目录项中存储文件(或子目录)的所有元数据。
从逻辑上说,文件和目录都由一系列的数据块组成,这些数据块可能离散地分布在硬盘的各个地方就像单个进程的虚拟地址空间所拥有的页在物理内存上离散分布一样。文件系统环境隐藏了块布局的细节,并提供了接口用于在文件内的任意偏移量处读/写一串字节。文件系统环境在内部处理对目录的所有修改,这是执行诸如创建和删除文件之类的操作的一部分。 我们的文件系统确实允许用户环境直接读取目录元数据(例如,通过read),这意味着用户环境可以自己执行目录扫描操作(例如,执行ls程序),而不必依赖于其他特殊调用。 这种目录扫描方法的缺点以及大多数现代UNIX变体操作系统不鼓励这样做的原因是,它使应用程序依赖于目录元数据的格式,从而难以更改文件系统的内部布局,目录元数据格式如果发生变化,那么读取其数据的应用程序代码相应地也要发生改变,至少得重新编译应用程序。

Sectors and Blocks

大多数磁盘无法按字节粒度执行读写操作,而是以扇区为单位执行读写操作。在JOS中,每个扇区均为512字节。文件系统实际上以块为单位分配并使用磁盘存储。注意两个术语之间的差别:扇区大小是磁盘硬件的属性,而块大小是使用磁盘的操作系统的基本分配单位。文件系统的块大小必须是基础磁盘的扇区大小的倍数。
xv6文件系统使用512字节的块大小,与基础磁盘的扇区大小相同。但是,大多数现代文件系统使用更大的块大小,因为管理存储空间的开销小的多,并且以较大的粒度管理存储更为有效。我们的文件系统将使用4096字节的块大小,可以方便地匹配处理器的页面大小。

Superblocks

文件系统通常会在硬盘上易于查找的位置保留一些块(如非常前或非常后的位置)来保存描述整个文件系统属性的元数据(例如块大小,硬盘大小,查找根目录所需元数据,文件系统上次装载的时间,文件系统上次检查错误的时间等等)。这些特殊的块被称为超级块。
我们的文件系统将只有一个超级块,在硬盘上是第1块,inc/fs.h中定义的super结构体描述了它的布局,第0块通常用于保存boot loaders和分区表,所以文件系统通常不会用到最起始的块。很多真正的文件系统会维护多个超级块,这些超级块在磁盘的几个间隔很宽的区域中复制,因此,如果其中一个超级块损坏,或者磁盘在该区域中出现介质错误仍然可以找到其它超级块并用来访问文件系统。
JOS的硬盘布局:

在这里插入图片描述

File Meta-data

在JOS的文件系统中,inc/fs.h中的file结构体描述了文件的元数据的布局。该元数据包括文件的名称。大小。类型(常规文件或目录)以及指向组成文件的块的指针。如上所述,我们没有索引结点,因此这些元数据存储在磁盘上的一个目录项中。与大多数真正的文件系统不同,为了简单起见,我们将使用这种文件结构来表示文件元数据,因为它同时出现在磁盘和内存中。
struct File中的f_direct数据包含存储文件前10个(NDIRECT)块的块号的空间,我们称之为文件的直接索引块。对于大小不到10*4096B=40KB的小文件,使用f_direct就够了。但是,对于较大的文件,我们分配一个额外的磁盘块,称为文件的间接索引块,以容纳4096/4=1024个额外的块号。
因此,我们的文件系统允许的文件大小最多为1034块,即超过4MB一点点。为了支持更大的文件,真正的文件系统通常还支持二级间接索引块和三级间接索引块。
file结构体:

在这里插入图片描述

Directories versus Regular Files

JOS文件系统中的file结构体可以用来表示常规文件或者目录,两者用file结构体中的type域进行区分,文件系统实际上用同一种方式来管理这两种类型的文件,除了它不解释与常规文件相关联的数据块的内容,而文件系统将目录文件的内容解释为描述目录内的文件和子目录的一系列结构。
文件系统中的超级块包含一个file结构体(struct Super中的root字段),它保存文件系统根目录的元数据。该目录文件的内容是一系列file结构体,描述位于文件系统根目录中的文件和目录。根目录中的任何子目录又可能包含更多表示子目录的file 结构体,依次类推。

The File System

本实验的目标不是让你实现整个文件系统,而是让你只实现某些关键组件。你将负责将数据块读入数据块缓存,并将其刷新回磁盘;分配磁盘块;将文件偏移量映射到磁盘块;以及在IPC接口中实现读、写和打开。因为你不会实现所有的文件系统,所以熟悉所提供的代码和文件系统接口是非常重要的。

Disk Access

JOS操作系统中的文件系统进程需要讷讷够访问磁盘,但是我们的内核中还未实现任何访问磁盘的功能,我们没有采用传统的“单块”操作系统策略,即在内核中添加一个集成开发环境磁盘驱动程序,以及允许文件系统访问它的必要系统调用,而是将集成开发环境磁盘驱动程序实现为用户级文件系统的一部分。我们需要修改内核,以便进行设置,使文件系统进程拥有实现磁盘访问所需的特权。
只要我们使用轮询,基于磁盘的可编程I/O访问,不使用硬盘中断就很容易在用户空间实现磁盘访问。也可以在用户态下实现中断驱动的设备驱动程序(例如L3和L4内核就是这么做的),但是这更加困难,因为内核必须现场设备中断,并将它们分派到正确的用户态进程。
x86处理器通过EFLAGS的IOPL位来决定保护模式下的代码是否有权限执行特殊的设备I/O指令(如IN和OUT指令)。因为我们需要访问的所有集成开发环境磁盘寄存器都位于x86的I/O空间,而不是内存映射的空间,所以为了允许文件系统访问这些寄存器,我们唯一需要做的事是给文件系统进程赋予“I/O特权”。实际

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值