• 哈工大李治军老师操作系统笔记【26】:生磁盘的使用(Learning OS Concepts By Coding Them !)


    0 回顾

    • 还是从硬件开始
    • 从磁盘开始,怎么让磁盘用起来,再转起来
    • 其实和控制之前的外设一样,核心是out再加上中断处理

    在这里插入图片描述


    1 磁盘


    在这里插入图片描述


    • 磁盘的基本单位是扇区
    • 磁盘的一个扇区是512字节
    • 扇区的大小是传输时间和碎片浪费的折衷

    1.1 使用磁盘


    在这里插入图片描述


    • 读/写一个字节,具体的操作如下:
    1. 首先将磁头移动到指定的磁道上
    2. 然后磁道开始旋转
    3. 转到相应的扇区以后,再一转,磁生电电生磁
    4. 磁生电的时候,磁信号就变成电信号,然后就读回去了,也就是读到内存的缓冲区当中
    5. 读到内存的缓冲区后 ,再将这个内存缓冲区修改一个字节,然后再到里面转,再电生磁,把这个字节写进去
    6. 核心就是移动磁头移动到磁道上,然后转动磁道移动到扇区上,然后一边旋转一边磁生电电生磁和内存缓冲区进行数据的交互,是读了还是写了都一样

    综上,磁盘/O过程:控制器→寻道→旋转→传输!

    怎么使用磁盘?就是移动磁头,旋转磁盘,进行读写,就是这三步,所以只要告诉计算机/磁盘控制器这几个数怎么移动磁头,怎么旋转,这样,磁盘驱动器就会自己工作,核心就是告诉磁盘控制器这几个参数

    1.2 最直接的使用磁盘


    在这里插入图片描述


    • 柱面: 就是刚刚移动的磁道(将磁头移动到磁道上)(现在不是一张盘,现在是一堆盘,所以现在就是一堆磁道形成一个柱面,知道柱面后,磁壁就会移动到相应的柱面上),cyl
    • 磁头: 旋转到这个柱面了,那到底是在第一个盘面读写还是其他几个呢?这就要根据磁头来定,head
    • 扇区: 到底读写这个盘面的哪个扇区sec
    • 所以传递了这三个值,磁盘就知道该怎么移动磁壁,怎么让哪个磁头上电,怎么旋转磁盘
    • 再告诉缓冲区后(告诉内存的位置),接下来就可以利用总线倒用技术DMA进行倒用总线,这样的话就可以将磁盘扇区上的数据放到内存上,或者将内存的数据写到扇区上,这样就完事了,具体来说,只要传递这几个值就可以读写磁盘,写到磁盘控制器上,用out指令
    void do hd request(void)
    {··.hd out(dev,nsect,sec,head,cyl,WIN WRITE,...)
    port write(HD DATA,CURRENT->buffer,256);}
    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);
    outb_p(0xAOI(drive<<4)head,++port);
    outb p(cmd,++port);}
    
    • 可以看出,最后就是一堆out指令
    • 就是通过这些out指令,把磁头,柱面,扇区都写到了某些端口上
    • 并且这些柱面磁头扇区还要转变为他认的格式,所以要左移右移进行拼接,这些都是细节

    SSD本来就不是磁盘(uh-oh),实际上它是一种闪存( f l a s h flash flash),操作当然不一样。

    1.3 通过盘块号读写磁盘

    • 上面那种还是太麻烦了,因为要知道很多信息,现在想直接知道磁盘号就能完成类似的工作该怎么做?
    • 可以发个盘块号,总比发磁头扇区柱面这三个参数要容易的多
    • 用户根据盘块号来读写磁盘
    • 磁盘驱动会负责将盘块号来计算出那三个参数,柱面磁头扇区(后面简称CHS)
    • 这是这一层抽象的核心
    • CHS是一个三维编址(参考柱面坐标系)
    • 而盘块号是一维编址,所以要明白一维到三维的这个换算编址

    在这里插入图片描述


    • 现在要求,连续的盘块号可以快速读出(就是在浪费时间的地方少浪费时间)
    • 主要是移动磁壁时间花费多,这个时间又称为寻道时间,寻找哪个磁道,寻找哪个柱面,最核心的就放在寻道时间上
    • 现在我们希望相邻盘块号的盘块应该尽量放在同一个磁道,这样才能让连续盘块进行读写的时候,尽量少花费时间,少花费时间就是少寻道
    • 磁头数不一定等于盘数,而是等于盘面数,一个盘可能两面都有磁性物质的

    在这里插入图片描述


    • Sectors: 总扇区数,Heads: 总磁头数;C: 目标柱面,H: 目标磁头,S: 目标扇区
    • 上方的公式当中,第一项是一个完整的柱面包含的扇区数,第二项是前H个磁头包含的扇区数,最后加上 S S S个扇区就是 b l o c k block block
    • 所以说 b l o c k block block % \% % s e c t o r s = S sectors = S sectors=S,因为前面的 s e c t o r s sectors sectors都有公因数,所以直接消掉,只剩下一个 S S S了,这样就可以通过 b l o c k block block反推回 C H S CHS CHS
    • 由一个磁道形成的柱面从上到下编号结束了,到下一个磁道开始从上到下的编号,就能理解了。这里理解为每个磁道上的扇区数量是一样的
    • 磁盘读写的单位是扇区
    • 现在用空间的大小来换时间
    • 读写的单位从一个空间换成盘块
    • 用空间的浪费换区时间效率,所以读写磁盘的基本单位从扇区变为盘块(几个连续的扇区),也就是磁盘
    • 得到连续的扇区,就能得到CHS,这些扇区有了,再通过out发给磁盘控制器,进行计算

    1.4 输出block

    • 现在使用磁盘可以通过盘块号使用,block
    • 用下方的公式,就能算出CHS

    在这里插入图片描述


    • linux0.11的盘块是2个扇区
    • 盘块越大读写效率越高

    1.5 多进程使用盘块


    在这里插入图片描述


    • 多个进程的话必须形成请求队列
    • 到底应该先给谁呢?这就要进行折中和调度
    • 磁盘驱动从队列当中取出来,算出CHS
    • 这里仍然是生磁盘,即从盘块号来使用
    • 熟磁盘是使用文件

    多个磁盘访问请求出现在请求队列怎么办?
    调度的目标是仕么?调度时主要考察什么?

    • 给调度算法,仍然从FCFS开始
    • 对磁盘来说,时间是最核心的因素,寻道时间又是最主要的大头
    • FCFS先来先服务,从中发现问题,在一步步改进

    1.6 FCFS磁盘调度算法


    在这里插入图片描述


    • 每个进程访问磁盘,由程序决定
    • 那些数字代表柱面

    1.7 SSTF短寻道优先磁盘调度


    • 在移动过程中把经过的请求处理了
    • 位于中间的比较多,总是会在中间晃荡,磁头总在中间移动
    • 远处请求划不过去,存在饥饿
      在这里插入图片描述

    1.8 SCAN扫描磁盘调度


    • 扫过去再扫回来
      在这里插入图片描述

    • 既公平,又移动比较小

    1.9 C-SCAN磁盘调度(电梯算法)


    • 就是这个电梯只有一个方向,走到头了立刻复位,复位过程不带人
      在这里插入图片描述

    • 多进程通过电梯算法将自己的的请求放在队列当中

    1.10 多进程使用磁盘


    在这里插入图片描述


    • 注解如下if当中的条件
    • 当temp->next小于temp的时候相当于进行了折回
    • 第一种是上楼的过程中处理,第二种是折回来从头处理
    • 猜测队列第2种情况是req
    • 就是反向复位的时候如果req
    • 第一个条件,是看req是不是能在上楼过程中被处理,后面那个条件是将req放在下楼过程中处理

    2 总结


    在这里插入图片描述


  • 相关阅读:
    [业务设计]-秒杀抢票问题
    学信息系统项目管理师第4版系列15_资源管理基础
    tcpdump抓包详解
    4、Netty 线程模型
    socket实现简单聊天【linux】
    文件操作(1)
    ArrayList源码解析
    生成.keystore 安卓签名
    UDF 函数返回中文结果在 datastudio 客户端为乱码
    第十八章:Swing自述
  • 原文地址:https://blog.csdn.net/weixin_44673253/article/details/127105460