一 磁盘的物理地址
1.1 磁盘的物理地址
我们知道磁盘主要是包括盘片、机械臂和磁头组成的,一个盘片分为两面,每一面都可以进行读写。每一个盘面由磁道组成,每一个磁道由扇区组成,扇区是磁盘进行读写的最小单位。
那如何对磁盘寻址呢?首先我们得知道是哪一个磁道,所以首先要把所有磁头都移到对应的磁道柱面上,用来确定磁道;然后根据盘面号决定存储在哪一个盘面上的,最后确定在这个盘面上的哪一个扇区,然后将磁头移到这个扇区,然后控制磁盘旋转,就可以读写数据。如图示:
1.2 扇区和磁盘块的关系
一个扇区以前一般是512字节,现在一般厂商的扇区是4096字节,即4K。但是扇区是磁盘中或者物理上的概念。对于操作系统而言,方便操作磁盘,弄出来一个磁盘块的概念,一个磁盘块是扇区大小 2^N被,即时2的整数倍,所以磁盘块大小最小可以和扇区大小相同,最大取决于操作系统的配置。
1.3 磁盘块和内存页关系
都是操作系统虚拟的概念,对磁盘读写就是以块为基本单位进行;如果是对内存则是以页为单位进行。
二 磁盘调度算法
2.1 一次磁盘读写需要的时间
2.1.1 寻道时间
我们给定一个物理地址,首先我们需要寻找磁道,然后在读写数据之前将磁头移动到指定磁道所花的时间。即寻找磁道,移动磁头到指定磁道的时间。
#1 磁头是由磁头臂带动的,所以移动磁头需要启动磁头臂s1
#2 磁头臂带动磁头到指定磁道,即移动磁头也是需要花费时间s2
寻道时间 = s1+s2
2.1.2 延迟时间(平均旋转等待时间)
确定了磁道和盘面,我们需要通过转动盘面,使得磁头位于要读写的扇区,这个转动的过程也是需要花费时间的。假设磁盘转速为r(转/秒或者转/分),则平均所需要的延迟时间 = 1/r,转速越高,旋转等待时间越短。
2.1.3 数据传输时间
从磁盘读出或者向磁盘写入数据所经历的时间,假设磁盘转速为r/分,此次读写的字节数为b,每一个磁道上字节数为N,则
首先:确定需要多少个磁道才能存储完毕,此次读写的磁道数 = b/N
其次:确定每一次旋转一圈的时间 = 1/(r/60) 秒,比如5400/m 则等价于90/s,所以每一圈的时间为1/90秒
那么最后数据传输时间为:(b/N)*(1/(r/60)秒
但是操作可以直接影响的只有寻道时间,不同的调度算法会直接影响寻道时间
2.2 磁盘调度算法
2.2.1 先来先服务(FCFS)
根据进程请求磁盘的先后顺序进来进行调度,类似于CPU的FCFS算法。
假设磁道现在在100号磁道,然后进程需要访问50、20、120、30号磁道,那么磁头根据进程访问的先后顺序,先把磁头移到50号磁道,然后由50号移到20号磁道,依次类推。
优点:公平;如果访问磁道集中的话,性能还可以
缺点:大量进程访问磁盘,请求的磁盘道很分散,平均移动磁道过多,FCFS性能很差,影响效率
2.2.2 最短寻找时间优先(Shortest Search Time First)
优先处理此时与当前磁道最近的磁道的访问,可以保证每一次寻道时间最短,但是不能保证总的寻道时间最短,因为有可能最早的进程要访问的磁道距离当前磁道比较远。类似于贪心算法,只是选择眼前最优的,但未必是总体最优。
优点:性能较好,平均寻道时间较短
缺点:可能产生进程访问磁盘饥饿现象
2.2.3 扫描算法(SCAN)
我们知道,最短寻找时间优先会产生的饥饿的原因在于磁头有可能在一个小的区域来回移动。为了防止这个问题,可以规定只有磁头移动到最外侧的时候才能往内移动,移到最内侧的磁道时候才往最外侧移动。
优点:性能较好,平均寻道时间较短,不会产生饥饿现象
缺点:只有到达最边上的磁道才会改变磁头的方向
2.2.4 LOOK算法
LOOK调度算法在SCAN算法的基础上,如果发现后面已经没有别的请求了,则立即调转磁头,改变磁头移动方向。
2.2.5 循环扫描算法(C-SCAN)
沿着某一个方向,移动磁头,访问磁道,当达到最内层或者最外层磁道时候,再立即返回到另一端,中间不需要再扫描任何磁道。如图是:
缺点:比起SCAN算法来,平均寻道时间更长;而且也存在SCAM算法的问题
三 磁盘管理
3.1 磁盘初始化
第一:磁盘在出厂之前,需要进行低级格式化,将磁盘各个磁道划分扇区,一个扇区经常由头、数据区域、尾组成,管理扇区的数据结构一般放在头和尾,包括扇区所需要的校验码等等
第二:将磁盘分区,每一个分区由若干柱面组成
第三:逻辑格式化,创建文件系统,包括文件系统的根目录、初始化存储空间管理所用的数据结构
3.2 坏块的管理
坏块就是坏的无法使用的扇区,这属于硬件故障,操作系统是无法修复的,应该将坏块标记出来,以免被错误使用。对于简单的磁盘可以在逻辑格式化的时候,进行磁盘坏块检查,在FAT上标明;对于复杂的磁盘,磁盘控制器会维护一个坏块链表,在磁盘出厂之前,进行低级格式化就会将坏块进行初始化。
四 磁盘地址与物理块号的转换
柱面号 = [块号/(磁头数量扇区数)]
磁头号 = [(块号 mod (磁头数 * 扇区数))/扇区数]
扇区号 = (块号 mod (磁头数 扇区数)) mod 扇区数
如果已知磁盘地址:
块号 = 柱面号 * (磁头数扇区数) + 磁头号扇区数+扇区号