工作也有两年了,在研究很多项目时发现很多问题追根溯源都会到计算机底层的知识,也是越来越发现编程语言只是一层外壳,这个外壳需要去和操作系统协商使用后者管理的的计算机资源,包括存储资源和计算资源。如果计算机底层知识不牢靠,遇到一些问题还真是不好分析,也很容易成为职业上升的瓶颈。现在回想起大学时学习这么课时是比较抽象的,那时没有太多编程经验,知识很难落地,造成了只知其然不知其所以然的情况,所以现在重新梳理一下计算机操作系统的一些底层知识,在这里记录一下。
我们最常使用的各种文件是进程创建的信息逻辑单元,同时文件也是对磁盘的一种建模模型。
文件系统是对磁盘的抽象,他用于管理文件和磁盘的使用,一块磁盘有成千上万个文件,每个文件都是独立与其它文件的。
这里先简单的介绍一下磁盘的一些知识,磁盘盘片的示意图如下所示:
盘片:磁盘中圆形的盘片是主要记录数据的物理介质
扇区:为磁盘的最小物理存储单元,每个扇区的大小都是固定的,同时每个磁道的扇区数量都是相同的。
柱面:将扇区组成一个圆环就是柱面,柱面是磁盘分区的最小单位。
磁盘分区:就是在分区表中记录可以访问的柱面范围。
其中磁盘的第一个扇区是最重要的,这里面记录了硬盘的主引导记录(Master boot Record)MBR,以及记录磁盘的分区表。
我们常见的文件系统主要有FAT,ext2,ext3,NTFS等,下图为一个典型的文件系统的组织结构示意图。
我们知道在使用一块磁盘之前是一定要进行格式化的,而这个格式化的过程就是将文件系统的一些元数据写入到磁盘中,比如描述正文件管理系统的超级块,分区表信息,MBR信息,一旦格式化完成这些信息就很难修改了。磁盘属于块设备,每次操作系统读磁盘都是一块一块的从磁盘读取数据,下面我们主要通过linux系统下的ext2文件系统。
文件
在Linux系统中一个文件包含文件的权限(rwx)与文件属性(所有者,群组,时间参数),ext2文件系统将这些参数分别存放在不同的块中,权限与属相放置到inode中,至于实际的数据则放置到data block块中。在格式化磁盘分区格式化的时候,就为磁盘每个inode和block创建好了唯一的编号,每一个分区都有一个超级块,这个超级块记录了文件系统的整体信息,包括inode与block的总量,使用量,剩余量,同时在磁盘的使用过程中这些数据是实时变化的。
总结一下文件的存储结构:
我们用上图来说明一下inode与block的关系,假如一个文件的属性与权限存在编号为4的inode上,inode记录了文件的存储位置为2、7、13、15这几个block上。这样操作系统就能在短时间内读取出全部的数据。
inode和block在磁盘格式化之后就已经规划好了,由于现在磁盘容量巨大,如果将所有的inode和block都放在一起是不容易管理的,所以,磁盘在格式化的时候是按照磁盘分区inode/block/super block分组进行格式化的。在本文的第一幅图中我们可以看到,磁盘分区为块组0、块组1、块组2、块组3等。
从虚拟内存的角度来说,虚拟页和磁盘中的块映射起来,当虚拟页被加载到内存的物理页的时候,就由DMA把虚拟内存对应的磁盘块加载到内存的对应地址的物理页中。当物理页写回到磁盘时,也是由DMA把数据传输到磁盘控制器,由磁盘控制器写到磁盘块对应的扇区。内存和磁盘交换数据的时候实际采用了内存的缓冲区来加速磁盘的访问速度。
缓冲区的目的是适配两个速度不一致的设备,从磁盘的工作原理我们看到磁盘操作是一个很慢的操作,内存操作相比磁盘操作是一个很快的操作,为了让内存对磁盘的读写不必等待磁盘操作返回再返回,操作系统设置了内存缓冲区来加速对磁盘的访问速度。