磁盘的基本原理

磁盘工作的原理

  • (1)从 CPU 开始,当用户想要使用磁盘时,由 CPU 发送命令给磁盘设备,最终通过“out ax, 端口号”指令告诉磁盘具体的动作细节。
  • (2)从磁盘开始,即磁盘在工作完成后用磁盘中断告诉 CPU,CPU 在中断处理中完成后续工作,如将磁盘读入的内容拷贝到用户态内存 buf 中等。

磁盘读写的具体过程是:

  • (1)磁头移动,找到要读的那个柱面(Cylinder,简称 C),由于多个磁头是绑在一起移动的,所以每个磁头下面的磁道在各自的盘面中具有同样的位置,所有磁头下面的磁道从上到下组合在一起就形成了一个“柱面”。
  • (2)从柱面中选择要具体读写哪个磁道,实际上就是选择哪个**磁头(Head,简称 H)**上电。
  • (3)旋转磁盘,将对应磁道中要读写的那个**扇区(Sector,简称 S)**转到磁头的下方,一般一个扇区 512 字节
  • (4)开始读写,将扇区中的内容读到内存缓存中去,或者是将内存缓存中的内容写出到该扇区中。

使用磁盘的直观方法

  • 让 CPU 给磁盘控制器发出读写命令,具体就是告诉磁盘控制器读写哪个柱面C、哪个磁头 H、哪个扇区 S 以及要读写的内存缓存位置和读写长度即可。
  • 当然需要查阅硬件手册,找到这些信息对应的端口地址,一旦找到以后,CPU 用一堆 out 指令将这些信息写出去即可,磁盘控制器一旦看到了这些信息就会自己执行磁头滑动、磁盘旋转以及读写扇区等动作了。
void do_hd_request(void)
{// 驱动器信息 drive// 读写长度信息 nsect、// 读写扇区号 sec// 读写磁头号 head、// 读写柱面号 cyl // 读或写的命令 cmd // 等信息用 outb_p(·, ++port) 语句写到端口port 上hd_out(dev,nsect,sec,head,cyl,WRITE,);// 用 port_write 和 port_read 实现内存缓存区 CURRENT->buffer和磁盘控制器的数据寄存器端口 HD_DATA 进行数据交换,// 这个交换的核心还是 out 指令和 in 指令,这一点可以很容易的从 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))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);outb_p(0xA0|(drive«4)|head, ++port);outb_p(cmd, ++port);
}

生磁盘的使用(基于块号)

L1:从扇区到磁盘块请求

  • 第一层抽象

直接操作柱面、磁头、扇区来读写磁盘扇区是不是有点太麻烦了

  • 因为要想给出 C、H、S,头脑中就必须时刻装着硬盘的结构图。
  • 实际上我们还必须知道诸如磁盘有多少柱面,总共有多少磁头,每个磁道能容纳多少扇区等诸多细节,否则给出的 C、H、S 数值很可能是非法的。这些细节对于一个普通的应用程序员来说很繁琐

什么样的磁盘读写才更符合人的习惯

  • 抹去 C、H、S 的具体细节,让用户感觉就是一大堆扇区排成一排等待用户使用,让用户访问第 0、1、···、10000、10001、··· 个扇区,这样的访问请求显然要方便得多。
  • 通过编址建立从 C、H、S 扇区地址到扇区号的一个映射,这就是文件系统第一层抽象的中心任务。要完成这个映射,编址的设计是最重要的。

编址方案

  • 给定一个磁盘,0 号扇区显然可以规定位置

    • 在 0 柱面(可以规定为最外层的那个柱面)
    • 0 磁头(可以规定为最上面的那个磁头)
    • 0扇区(可以规定为磁盘旋转整圈以后的那个扇区)
  • 关键问题是 1号扇区应该在哪里

    • 是和 0 号扇区在同一个磁道上且相邻的位置吗?
    • 是和 0 号扇区相邻的下一个柱面上吗?
    • 还是和 0 号扇区相邻的下一个磁头上?

1 号扇区的位置应该在哪里要从提高磁盘读写速度的角度进行分析

  • 磁盘读写主要分为三步(读写时间也是由这三部分):移动磁臂(也称为寻道);旋转磁盘;数据传输。

    • 移动磁臂通常要花费 10ms 左右,即寻道时间为 10ms;
    • 7200 转/分钟的磁盘平均旋转半圈,花费的时间约为 4ms,即旋转时间为 4ms;
    • 现在硬盘的传输速度都在每秒几十兆字节以上,以 50M/s 为例,传输 1 个扇区 512 个字节需要 0.01ms,即传输时间为 0.01ms。
    • 即:对比这三个数字一目了然,读写磁盘的主要时间花费是寻道上。
  • 另一方面,一旦将所有扇区“排成一排”,变成一个线性序列 0、1、2、···进行读写时。我们通常会读写扇区号连续的多个扇区
    • 因为在给一个文件分配扇区空间时,比如文件需要 10 个扇区,通常我们会找出一段扇区号连续的磁盘空间进行分配,比如从 1000—1009 的 10 个扇区。
    • 再根据局部性原理,我们在一段时间内通常会读写文件中一个连续区域,两个连续导致的结果就是在一段时间内通常要读写扇区号连续的多个扇区。所以,在读写完 0 号扇区以后,很可能去读写 1 号扇区。
  • 如果读写完 0 号扇区以后,马上去读写 1 号扇区,最省寻道时间和旋转时间的显然是”是和 0 号扇区在同一个磁道上且相邻的位置“
    • 因为这种情况下不用寻道也不用旋转(在磁盘读写的时候,要滑过整个扇区,因为要有相对运动才能将磁信号变成电信号)

s e c t o r = C × ( H e a d s × S e c t o r s ) + H × S e c t o r s + S sector = C × (Heads × Sectors) + H × Sectors + S sector=C×(Heads×Sectors)+H×Sectors+S

  • sector 是扇区号
  • Heads 是磁盘的磁头数量。
  • Sectors 是每个磁道的扇区数

计算C、H、S

  • C = s e c t o r / S e c t o r s / H e a d s C = sector/Sectors/Heads C=sector/Sectors/Heads

  • H = s e c t o r / S e c t o r s H = sector/Sectors%Heads H=sector/Sectors

  • S = s e c t o r % S e c t o r s S = sector\%Sectors S=sector%Sectors

磁盘块

  • 扇区号连续的多个扇区就是一个磁盘块

    • 引入磁盘块以后用户读写磁盘的基本单位就不再是扇区,而是磁盘块了。用磁盘块将扇区概念隐藏起来,是文件系统的第一层抽象.
  • 为什么每次读写要读写多个连续扇区而不是一个扇区呢
    • 因为数据传输时间和寻道/旋转时间相比要小得多,所以寻道、旋转一次读写 K 个扇区的策略比只读写 1 个扇区的策略,其磁盘读写速度的提高接近于 K倍。所以抽象出磁盘块以后,磁盘读写速度会有非常显著提高。
    • 具体的说,用了 14ms+0.01ms 读写了一个扇区,磁盘的读写速度是 0.5K/14.01ms;但如果用14ms+0.1ms 读写了十个扇区,其中 0.1ms 是传输 10 个扇区数据的时间,磁盘的读写速度就变成为 5K/14.1ms,速度提高了 9.93 倍。
  • 磁盘块作为磁盘读写的基本单位也有缺点:造成磁盘空间的浪费
    • 这是显然的,以 1M 作为单位进行磁盘分配,一个文件平均会造成 0.5M 的空间浪费,即该文件的最后一个盘块即使没有用满也不能分配给别的文件使用(不然读这个文件会读到其他文件的内容)。
    • 但是现在的磁盘容量通常都很大,相比来说,读写速度要重要的多。

计算 C、H、S:用盘块号 blocknr→ sector → C、H、S

  • s e c t o r = b l o c k n r × b l o c k s i z e sector = blocknr × blocksize sector=blocknr×blocksize

    • 其中 blocksize 是描述磁盘块大小的一个参数,这是操作系统可以调整的一个参数。
  • 一旦算出扇区号以后,再用上面给出的公式计算出 C、H、S,然后 CPU 就可以发出 out 命令了。

    static void make_request()
    {// requset 中的核心信息就是用户要读写的扇区号 sector,该信息是根据用户提供的盘块号 blocknr 计算得出的struct requset *req;req = request+NR_REQUEST;req->sector=bh->b_blocknr«1;add_request(major+blk_dev,req);
    }// do_hd_request 函数会使用汇编指令 divl实现从 sector 到 C、H、S 的计算
    void do_hd_request(void)
    {unsigned int block=CURRENT->sector;__asm__(“divl %4”:”=a”(block),”=d”(sec):”0”(block),“1”(0),”// hd_info[dev].sect 就是公式中 Sectors// 在系统启动时调用 BIOS 中断获得并初始化到 hd_info 数据结构中的r”(hd_info[dev].sect));__asm__(“divl %4”:”=a”(cyl),”=d”(head):”0”(block),“1”(0),”// hd_info[dev].head 是公式中的 Heads// 在系统启动时调用 BIOS 中断获得并初始化到 hd_info 数据结构中的r”(hd_info[dev].head));hd_out(dev,nsect,sec,head,cyl,WRITE);
    }
    

【操作系统系列】磁盘基本原理与盘块编号相关推荐

  1. 操作系统(习题记录):假定盘块的大小为1KB,对于1.2 MB的软盘,FAT需占用多少存储空间

    一.问题描述 1.假定盘块的大小为1KB,对于1.2 MB的软盘,FAT需占用( B )的存储空间 A.1KB B.1.8KB C.2.4KB D.3KB E.1.5KB 2.文件系统的模型可分为三层 ...

  2. 操作系统:磁盘结构和磁盘块号计算方法

    磁盘结构 磁盘存储器是一种高速.大容量的随机存储设备 用于存放大量的文件和数据 磁盘设备由一组盘组组成: 包括一张或多张盘片,每张盘片分正反两面 每面可划分成若干磁道各磁道之间留有必要的间隙 每条磁道 ...

  3. 深大操作系统实验四:磁盘 Inode 读取,盘块读取,软硬链接,磁盘挂载

    目录 前言 1. 目录树构建 2. Inode 与物理盘块读取 3. 软硬链接 4. 内存磁盘 cache 5. 磁盘挂载(选做) 6. open 与 fopen(选做) 7. 文件指针游标(选做) ...

  4. 假设磁盘块与缓冲区大小相同,每个盘块读入缓冲区的时间为10μs,由缓冲区送至用户区的时间是5μs,系统对每个磁盘块数据的处理时间为2μs。若用户需要将大小为10个磁盘块的

    [详细计算公式!][详细计算公式!][详细计算公式!] 做这道题的时候伤透了脑筋, 而网上只有答案没有过程, 经过漫长的推算,参考网上和书上的解析,终于总结出了做这种题的万能公式! 送给大家! 题目: ...

  5. 【中级软考】位示图bitmap是什么?(利用二进制的一位来表示磁盘中的一个盘块的使用情况)

    位示图 位示图是利用二进制的一位来表示磁盘中的一个盘块的使用情况.当其值为"0"时,表示对应的盘块空闲:为"1"时,表示已经分配.有的系统把"0&qu ...

  6. 磁盘位置_CPT201-磁盘

    转载于: 简单理解磁盘结构_刘小绪同学的博客-CSDN博客​blog.csdn.net 数据库系统总会涉及到辅助存储(大多都是磁盘),因为它们能够存储大量需要长期保存的数据,因此我们有必要先了解了解磁 ...

  7. 华为云服务器不显示盘符,磁盘不显示盘符

    磁盘不显示盘符 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. 您可以通过设置查 ...

  8. 【操作系统】磁盘管理高级

    文章目录 RAID磁盘阵列 什么是RAID? RAID 0 RAID 1 RAID 5 RAID 10 磁盘阵列管理 mdadm 工具的使用 创建并管理RAID LVM 磁盘管理 物理卷 - PV 卷 ...

  9. 银河麒麟Linux操作系统报错:U盘---只读文件系统

    银河麒麟Linux操作系统报错:U盘-只读文件系统 1.问题描述: 将桌面文件复制到U盘或者在U盘创建文件时无法实现创建,报文件系统只读! 2.问题解决过程: 2.1 将U盘重新挂载 尝试将U盘重新挂 ...

最新文章

  1. 如何去掉Silverlight应用程序在浏览器中的滚动条
  2. 万众期待的《Cisco/H3C路由器配置与管理完全手册》开锣了
  3. idea快捷键生成返回类型_十三肝了2晚的《IDEA操作手册-终极秘籍》终于来了......
  4. Mac电脑设置adb环境变量
  5. day1||python
  6. .netcore 整合 log4net
  7. Linux驱动(2)--ARM的架构发展以及如何评价处理器
  8. 入门SVN基础使用教程
  9. WIN10的永久杜比音效的安装(2021)
  10. 产品读书《创新者的窘境》
  11. 【技巧】如何给CSDN上的每篇原创文章添加版权声明
  12. 【Matplotlib】(二)图例legend
  13. vue嵌套路由,二级路由使用介绍
  14. Java 中代码优化的 30 个小技巧(下)
  15. 8.微信小程序-Mobx数据共享(类似vuex)
  16. 鸿蒙系统能用wps吗,WPS Office
  17. 2019java 开发工程师 最新面试官 问的问题
  18. 前台--中台--后台,什么是中台呢?看这一篇足矣
  19. 【硬见小百科】看完这篇,请不要再说不懂MOSFET!
  20. Dataset之IRIS:莺尾(Iris)数据集的简介、下载、使用方法之详细攻略

热门文章

  1. Mac如何使用自带的录屏软件
  2. 六石管理学:随心所欲的理解
  3. 【渝粤题库】广东开放大学 平法视图 形成性考核
  4. echarts南海诸岛问题
  5. opencv--直方图
  6. python七段数码管绘制字母31bdacef_图中7段数码管显示器型号,在proteus中怎么找出来?...
  7. 脑成像坐标系: MNI + Talairach
  8. 一个技术总监的内心独白(3)
  9. 常用的jquery在线引用地址
  10. Qt控件滑块QSlider的图片使用注意事项