前言
CPU管理和内存管理构成了操作系统的核心,通过外设管理可以用键盘和显示器进行输入输出。现在开始论述操作系统的最后一部分——文件系统。用户对计算机的使用是以文件为基础的,我们编辑的文档、执行的命令、使用的外部设备在操作系统在操作系统那里都是文件,所以文件系统是构成操作系统的必要操作部分。
文件系统归根结底是对磁盘的驱动。在磁盘驱动过程中直接使用磁盘很烦琐,因此引入了五层抽象机制:
(1)从扇区到磁盘块的抽象;
(2)从单个盘快请求到多个进程的磁盘请求队列;
(3)从磁盘请求到高速缓存;
(4)从盘块集合到文件的抽象;
(5)从多个文件到构建文件系统。
一、磁盘工作的基本原理
1,磁盘工作原理
磁盘和一般外设的工作原理完全一样,包含两条主线:
(1)从CPU开始,当用户想要使用磁盘时,CPU发送命令给磁盘设备,最终通过“out ax,端口号”指令告诉磁盘具体的动作细节。(2)从磁盘开始,即磁盘工作完成后用磁盘中断告诉CPU,CPU在中断处理中完成后续工作,如将磁盘读入的内容复制到用户态内存buf中。
2.磁盘工作的过程
下图给出了磁盘的具体构成以及磁盘读写的细节。磁盘由多个圆形盘面形成的盘面组,每个盘面上由多个同心圆环,每个圆环被称为一个磁道,多个磁盘的同一磁道合在一起形成一个圆柱面,简称柱面。每个磁道再被分割成多个扇区,扇区是磁盘读写的***基本单位***。由于有多个盘面,所以每个盘面上都有一个读写磁头,当磁盘读写时,对应的其中一个磁头就会上电,读写电磁头所对应磁道上的扇区。
读写过程如下:(1)磁头移动,找到要读写的柱面,因为几个磁头是绑在一块的,所以所有磁头都移动到磁面上相对位置相同的磁道上,这些磁道组合在一起构成了一个柱面;(2)在柱面上选择要读的磁道,即选择对应的磁头上电;(3)旋转磁盘,把要读的扇区转到磁头下;(4)开始读写,将磁盘上的内容读到内存缓冲区或者将内存缓冲区的内容读写到该扇区。
3.使用磁盘的直观方法
要想使磁盘工作,最直观的方法:CPU向磁盘控制器发出读写命令,告知控制器要读写的柱面、扇道、扇区、内存缓存区的位置、读写的长度。需要查阅硬件手册,找到这些信息所对应的端口是哪些,之后CPU用out指令把这些信息发送出去,控制器收到后就会完成对应的操作。
//磁盘直接读写的代码
void do_hd_request(void)
{
hd_out(dev, nsect, sec, head, cyl, WRITE,);
port_write(HD_DATA, CURRENT->buffer, 256);//或者是port_read
}
void hd_out(drive, nsect, sec, head, cyl, cmd)
{
port = HD_DATA;//数据寄存器端口(0x1f0)
outb_p(nsect, ++port);
outb_p(sect, ++port);
outb_p(cyl, ++port);
outb_port(cyl>>8, ++port);
out_p(0xA0 | (drive<<4) | head, ++port);
outb_p(cmd, ++port);
}
hd_out将驱动器信息drive、读写长度nsect、读写扇区号sec、读写磁头号head、读写柱面号cyl以及读或写的命令cmd等信息用outb_p语句写到端口port上。在CPU将这些指令发送到磁盘控制器后,由port_write或者port_read进行内存缓冲区的CURRENT->buffer与磁盘控制器数据端口HD_DATA的数据互换。以下是port_write和port_read的宏定义。
#define port_write(port, buf, nr) _ _asm_ _("cld;rep;outsw"::
"d"(port), "S"(buf), "c"(nr))
#define port_read(port, buf, nr) _ _asm_ _("cld;rep;insw"::
"d"(port), "D"(buf), "c"(nr))