硬盘组成概述

  • 盘片
  • 盘面
  • 磁头
  • 磁道
  • 扇区
  • 柱面

盘片、盘面和磁头

硬盘中一般会有多个盘片组成,每个盘片包含两个面,称为盘面,每个盘面都对应地有一个读/写磁头。受到硬盘整体体积和生产成本的限制,盘片数量都受到限制,一般都在5片以内。盘面的编号和磁头编号相对应,从上到下从零开始,如最上边的盘片有 0 面和 1 面,再下一个盘片就编号为 2 面和 3 面。由于每个盘面都有自己的磁头,因此,盘面数等于总的磁头数。如下图:

  • 早期的硬盘不工作的时候,磁头停靠在靠近主轴接触盘片的表面,即线速度最小的地方,这里是一个不存放任何数据的特殊区域,称为启停区或着陆区,启停区以外就是数据区。
  • 在硬盘的最外圈,离主轴最远的磁道称为 0 磁道,硬盘数据的存放是从最外圈 0 磁道开始的 。即硬盘数据从最外圈开始,而停止时磁头又是在最内圈启停区。
  • 0磁道非常重要,我们知道,系统的引导程序就在 0 柱面 0 磁道 1 扇区的前 446 Bytes,后 64 字节是分区表,最后两字节是结束标志 0x55 和 0xaa。0磁道属于隐藏磁道,这个磁道的 63 个扇区属于隐藏扇区。操作系统的所有命令,除了 FDISK 以外都不能访问它们。就连格式化程序 FORMAT,对它们也无能为力。

扇区和磁道

下图显示的是一个盘面,盘面中一圈圈灰色同心圆为一条条磁道,从圆心向外画直线,可以将磁道划分为若干个弧段,每个磁道上一个弧段被称之为一个扇区(图践绿色部分)。扇区是硬盘的最小读写单元数据容量通常是 512 字节。每个扇区包括 512 个字节的数据和扇区头 ,扇区头包含本扇区的信息,主要有本扇区的磁道号、磁头号、扇区号,用来供硬盘定位机构使用。

越靠外的磁道旋转的线速度越快,读取数据的速率也就越快。

柱面

硬盘通常由重叠的一组盘片构成,每个盘面都被划分为数目相等的磁道,并从外缘的“0”开始编号,具有 相同编号的磁道形成一个圆柱 ,称之为柱面。硬盘的柱面数与一个盘面上的磁道数是相等的。 如下图:

柱面是一个用来优化数据读写的概念 。需要注意的是,硬盘读写数据是柱面顺序来读的,而不是按磁道顺序来读的。举个例子,磁头读完 0 面 0 磁道后,接着读 1 面 0 磁道,再读 2 面 0 磁道,一直将该柱面读完。我们很容易认为磁头是这样读取数据的:磁头读完 0 面 0 磁道后,接着读 0 面 1 磁道,再读 0 面 2 磁道…为什么按柱面读取数据呢?因为按柱面读取数据就会大大减少寻道时间。参见后文硬盘读取响应时间

硬盘容量计算

存储容量 = 磁头数 × 磁道(柱面)数 × 每道扇区数 × 每扇区字节数

每个磁道的扇区数一样是说的老的硬盘,外圈的密度小,内圈的密度大,每圈可存储的数据量是一样的。新的硬盘数据的密度都一致,这样磁道的周长越长,扇区就越多,存储的数据量就越大。

硬盘读取响应时间

  1. 寻道时间:磁头从开始移动到数据所在磁道所需要的时间,寻道时间越短,I/O操作越快,目前硬盘的平均寻道时间一般在3-15ms,一般都在10ms左右。
  2. 旋转延迟:将数据所在扇区移至读写磁头下方所需要的时间,旋转延迟取决于硬盘转速。普通硬盘一般都是 7200rpm,慢的 5400rpm。
  3. 数据传输时间:完成传输所请求的数据所需要的时间。

读写一次硬盘信息所需的时间可分解为:寻道时间、延迟时间、传输时间。为提高硬盘传输效率,应着重考虑减少寻道时间和延迟时间。

硬盘寻址方式

CHS方式
CHS (Cylinder/Head/Sector) 方式通过柱面、磁头、扇区来定位。 由于早期硬盘的每个磁道的扇区数一样多(外圈磁颗粒稀疏),整体硬盘空间大小也不大,所以此方式比较高效。但 CHS 模式支持的硬盘容量有限,用 8bit 来存储磁头地址,用 10bit 来存储柱面地址,用 6bit 来存储扇区地址,而一个扇区共有 512 Byte,这样使用 CHS 寻址一块硬盘最大容量为 256 * 1024 * 63 * 512B = 8064 MB(约8.4GB)。CHS 下扇区从 1 开始编号

LBA方式
现在很多硬盘采用同密度盘片,意味着内外磁道上的扇区数量不同,扇区数量增加,容量增加,CHS 很难定位寻址,所以 LBA 方式应运而生。在 LBA 地址中,地址不再表示实际硬盘的实际物理地址(柱面、磁头和扇区)。LBA 编址方式将 CHS 这种三维寻址方式转变为一维的线性寻址,它把硬盘所有的物理扇区的 C/H/S 编号通过一定的规则转变为一线性的编号,系统效率得到大大提高,避免了烦琐的磁头/柱面/扇区的寻址方式。在访问硬盘时,由硬盘控制器再将这种逻辑地址转换为实际硬盘的物理地址。LBA 下扇区从 0 开始编号

块/簇

硬盘块/簇(虚拟出来的)。 块是操作系统中最小的逻辑存储单位。操作系统与硬盘打交道的最小单位是硬盘块。通俗的来讲,在 Windows 下如NTFS 等文件系统中叫做簇;在 Linux 下如 Ext4 等文件系统中叫做块(block)。每个簇或者块可以包括2、4、8、16、32、64…2的n次方个扇区。
为什么存在硬盘块?1)读取方便:由于扇区的数量比较小,数目众多在寻址时比较困难,所以操作系统就将相邻的扇区组合在一起,形成一个块,再对块进行整体的操作。2)分离对底层的依赖:操作系统忽略对底层物理存储结构的设计。通过虚拟出来硬盘块的概念,在系统中认为块是最小的单位。

page

操作系统经常与内存和硬盘这两种存储设备进行通信,类似于“块”的概念,都需要一种虚拟的基本单位。所以,与内存操作,是虚拟一个页的概念来作为最小单位。与硬盘打交道,就是以块为最小单位。

扇区、块/簇、page的关系

  1. 扇区: 硬盘的最小读写单元
  2. 块/簇: 是操作系统针对硬盘读写的最小单元
  3. page: 是内存与操作系统之间操作的最小单元。

扇区 <= 块/簇 <= page

硬盘预读

硬盘存取,硬盘 I/O 涉及机械操作。硬盘是由大小相同且同轴的圆形盘片组成,硬盘可以转动(各个硬盘须同时转动)。硬盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个硬盘的内容。磁头不动,硬盘转动,但磁臂可以前后动,用于读取不同磁道上的数据。磁道就是以盘片为中心划分出来的一系列同心环。磁道又划分为一个个小段,叫扇区,是硬盘的最小存储单元。

硬盘读取时,系统将数据逻辑地址传给硬盘,硬盘的控制电路会解析出物理地址(哪个磁道,哪个扇区),于是磁头需要前后移动到相应的磁道——寻道,消耗的时间叫——寻道时间,硬盘旋转将对应的扇区转到磁头下(磁头找到对应磁道的对应扇区),消耗的时间叫——旋转时间,这一系列操作是非常耗时。
为了尽量减少I/O操作,计算机系统一般采取预读的方式,预读的长度一般为页(page)的整倍数 。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和硬盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和硬盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向硬盘发出读盘信号,硬盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行
计算机系统是分页读取和存储的,一般一页为4KB(8个扇区,每个扇区125B,8*125B=4KB),每次读取和存取的最小单元为一页,而硬盘预读时通常会读取页的整倍数。根据局部性原理,程序运行期间所需要的数据通常比较集中,当一个数据被用到时,其附近的数据也通常会马上被使用。由于硬盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),所以即使只需要读取一个字节,硬盘也会读取一页的数据。

磁盘碎片

文件系统碎片是文件系统将文件内容非连续排列以方便就地修改其内容的结果。磁盘碎片会增加磁盘磁头移动频率,即增加了寻道时间,会降低磁盘读写性能,进而影响操作系统操作系统及软件性能 。另外,文件系统不能承受无限制的碎片。对现有碎片的更正称为碎片重组,是将文件和可用空间重新组织为连续区域的过程。

需要注意的是,固态磁盘(SSD)不是真正的磁盘,也不是“旋转的”,所以没有文件碎片问题

Linux 下读写硬盘

  1. 创建硬盘 :利用 Bochs 的 bximg bool 创建硬盘,在 bochs 文件夹下输入命令:

    bximage -q -hd=16 -func=create -sectsize=512 -imgmode=flat ./build/hd.img
    

    参数解释:
    -q :以静默模式创建,不会和用户交互
    -hd :创建硬盘,-fd 创建软盘;后面的 16 笔者也不太清楚。
    -func=create :表明创建硬盘。
    -imgmode :硬盘类型,有 flat,sparse,growing 三种。
    -secsize :硬盘大小,以 MB 为单位。
    ./build/hd.img :为硬盘位置及其名称。
    也可以直接输入 bximage 然后一步一步按提示创建。

  2. 写入硬盘 :使用 LInux 的 dd 命令写入硬盘:

    dd if=./app.bin of=./hd.img bs=512 seek=100 conv=notrunc
    

    参数解释:

    参数 说明
    if=文件名 输入文件名,默认为标准输入。即指定源文件。
    of=文件名 输出文件名,默认为标准输出。即指定目的文件。
    ibs=bytes 一次读入bytes个字节,即指定一个块大小为bytes个字节。
    obs=bytes 一次输出bytes个字节,即指定一个块大小为bytes个字节。
    bs=bytes 同时设置读入/输出的块大小为bytes个字节。
    cbs=bytes 一次转换bytes个字节,即指定转换缓冲区大小。
    skip=blocks 从输入文件开头跳过blocks个块后再开始复制。
    seek=blocks 从输出文件(硬盘)开头跳过blocks个块后再开始复制。
    count=blocks 仅拷贝blocks个块,块大小等于ibs指定的字节数。
    conv=<关键字> 关键字可以有 11 种,通常用 notrunc 就行。

文章参考硬盘详解硬盘介绍硬盘介绍

文章作者: 极简
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 后端技术分享
自制操作系统
喜欢就支持一下吧