计算机中的机械设备:磁盘

计算机中的机械设备:磁盘 相信对于大部分初学编程的人来说硬件都是一个比较恐怖的东西你可能已经熟练的掌握了编程语言的基本语法但是对电脑的硬件还是两眼一麻黑当然有许多人都会认为编程是纯软件方向的不需要关心硬件在这里本人的观点是:如果是往软件方向发展的话硬件确实没那么重要但是适当的了解硬件是必须的因为如果你想要写出牛逼的软件那么就必然要熟悉操作系统而熟悉操作系统的一个大前提就是对电脑的硬件有一定的了解(因为操作系统是硬件的管理者),比如磁盘如果你想要学透操作系统中的文件系统了解磁盘就是必要的因为文件系统就是依托于磁盘而存在的其主要功能就是管理磁盘中的存储空间。因此本文就来尽可能详细的介绍一下磁盘的工作原理和把硬件抽象成用软件进行管理的思维。1.什么是磁盘本章先来简单的介绍一下磁盘让读者看看磁盘内部是什么样子的把抽象的名称变为具体的实物。1.1磁盘的定义磁盘的全称是机械磁盘(也叫机械硬盘)它是计算机中一个比较特殊的硬件其特殊性就体现在磁盘是计算机中唯一一个使用机械结构实现数据存储的硬件磁盘的标准定义是:利用磁记录技术来存储数据的存储器。由于磁盘是使用机械结构这既有优势又有缺点其优势是:磁盘的价格比较低并且存储空间非常大。其缺点是磁盘比较笨重IO(输入输出)效率比较低并且可能会由于机械原因造成磁盘数据丢失(下文详细说明)。下面来看看磁盘具体是什么样子的:从上方的图片也明显可以看出磁盘内部确实是使用机械结构实现的其机械结构的具体组成在下文会进行详细的介绍。1.2磁盘的使用场景由于磁盘的笨重和不适合频繁进行移动(下文说明原因)的缺点当代笔记本电脑大多数都不使用磁盘作为存储结构了而是使用固态硬盘固态硬盘的存储空间一般没有磁盘大而且成本比较高但是固态硬盘的IO效率比较高并且比较轻便。不过又因为磁盘存储空间大成本低可以永久保存数据的优点大部分企业的后端都会使用磁盘来长期保存数据比如大型互联网公司的机房就是使用磁盘作为主要存储单元的下面来简单介绍一下机房具体是个什么东西:左上方的白色就是传说中的服务器了在其内部可以插入很多个磁盘然后其下方的那个柜子就是所谓的机柜在其中可以放置很多个服务器然后右边的图片中还有机柜中多个服务器的走线图右下方的那个包含多个机柜的大房子就是机房了。磁盘虽然是一种比较老的存储设备但是目前在大部分大型企业中依旧是使用磁盘作为主要的数据存储设备的因此适当的了解磁盘是非常有必要的。下面来说点题外话像机房这种东西只有大型互联网公司才玩得起可以简单的算一笔账:目前一个质量比较好的磁盘大约要500元左右然后一个服务器中一般可以20多个磁盘那么就需要10000元了(实际会更贵)然后一个机柜中少说也要放10个服务器最后一个机房中一般会有上百个机柜并且还需要考虑维护散热损坏等问题这一套下来就上亿了因此中小型公司是不可能玩得起机房的而大公司为了降低成本大部分大型互联网公司都会把自己的机房建立在气候凉爽地价低的地方(比如云贵高原那一片),在外国甚至还有把机房建在海底的。大公司在建立了机房后一般来说算力和存储都会有盈余因此它们就会利用网络把自己多余的算力和存储租出去(相当于一个远程的网吧)而租借的对象就是个人或是中小型企业然后这些大公司又给这种操作起了个高大上的名字即云服务。2.为什么要有磁盘2.1计算机的主要存储设备在计算机中存在各种各样的存储设备比如寄存器内存条磁盘闪卡固态硬盘....其中所有的存储设备都会遵循一条原则即:IO(输入输出)的速度越快能够存储的数据就越少并且造价就越高以磁盘内存条寄存器为例其中寄存器是IO速度最快的因此寄存器的造价就很高并且存储的数据量会非常少内存条IO的速度比较快因此造价会比较高存储的数据量一般般而磁盘的IO速度非常慢因此其造价就比较低并且存储的数据量巨大。一般对于计算机来说存储设备IO的速度越快计算机的性能就越好(你都有钱换高速IO设备了难度不会买性能更好的CPU吗?)理论上来说计算机的存储设备可以全部都换成内存条使用几百个内存条就差不多可以和一个磁盘存储相同的数据量了(部分科研用的计算机就是这么干的)。不过此时一台计算机最便宜可能也得要几十万这显然是我们平头老百姓不能接受的因此磁盘这种大容量低成本的存储设备就是必须的而使用了磁盘这种低IO效率的设备进行存储就必然会影响计算机的效率那么为了让该影响降到最低就需要冯诺依曼体系了。2.2冯诺依曼体系冯诺依曼体系是现代计算机的基础理论模型该体系由五大核心组件组成利用中间层进行过渡让CPU只能访问中间层(内存)不必与IO效率底下的外设打交道下面来看看其具体是什么样子的:在上图中输入设备和输出设备就是低IO效率设备简称外设(比如键盘磁盘显示器网卡...),存储器就是那个过渡的中间层一般是内存条而中央处理器可以认为是CPU实际上不止CPU我们重点关注数据信号(红色线的流程)可以看到数据输入输出的整个流程是输入设备先把数据输送给内存然后CPU直接从内存中读取数据并处理处理完毕后再把处理后的数据写回内存最后再从内存中输出数据到输出设备中。在该体系中可以认为CPU是不会与外设打交道的其只会从内存中读取数据写回数据时也只会写到内存中(内存和CPU之间的数据交互一般由寄存器完成)。举个具体的实例:微信接收和发送信息的过程首先外设网卡通过网络获取了数据然后网卡再把数据输入到内存中CPU通过寄存器从内存中获取并处理了数据后就把数据写回了内存然后内存再把数据输出到显示屏上(外设)。提出一个疑问为什么使用冯诺依曼体系可以提高数据输入输出的效率你看嘛内存从磁盘中读取数据不是一样需要时间吗然后还要多花费CPU从内存中读取数据的时间那这种操作不是比CPU直接从磁盘中读取数据要花费更多的时间吗?答案涉及到了计算机中的一个概念即局部性原理如果数据是按照内存读取一条数据CPU就执行一条数据然后内存在从磁盘中读取一条数据的顺序的话(即读取一条执行一条)那么CPU从磁盘中直接读取数据确实会更快但是利用了局部性原理后内存就可以预先从磁盘中加载一批数据然后再喂给CPU执行在CPU执行的过程中内存还可以继续从磁盘中加载另一批数据这样CPU的执行操作和内存从磁盘中加载数据的操作就变成异步的了此时就可以保证CPU可以一直从内存中读取数据并执行不需要等待内存从磁盘中加载数据那么IO效率自然就提高了。然后就出现了另一个问题内存能够预先从磁盘中加载数据的前提是内存得知道CPU要执行的数据具体是哪一批那么内存是怎么知道的呢答案就是上文提到的局部性原理了下面就来具体说说这个局部性原理举个例子相信大部分读者在上学时班级里面的同学都是以本地的居多的吧尽管从概率上来看在广东的一所学校中出现一个美国的学生并不是不可能的但是这种可能性非常低在程序中也同样如此同一个程序在磁盘中大多都是连续存储的这意味着如果CPU执行到了某一个程序的第100行代码那么CPU下一次要执行的代码大概率就在该程序的第90到110行代码中有可能会出现执行到9999行代码的情况(函数跳转),不过这种可能性非常低因此内存就可以根据CPU当前执行的代码所处的位置提前在磁盘中把该位置附近的数据加载进来了(用更专业的术语来说就是局部性原理提高了内存的命中率)。3.磁盘的机械结构在本文的标题中就已经提到过磁盘是计算机中少见的(几乎是唯一的)机械存储设备那么如果想要彻底的了解磁盘的存储原理了解其机械结构就是必须的。3.1磁盘的组成部分上方是磁盘内部的正面平面图可以看到磁盘内部存储数据的主要位置就是盘片(就是图中的磁盘图中的表述有点问题),磁盘的中间是主轴马达在盘片上方是磁头相当于笔磁头和盘片不会之间接触但是会离的非常近(微米级)磁头可以在磁盘上方左右摆动来写入数据连接磁头的是磁头臂而连接磁头臂的是一个永磁铁永磁铁和磁头臂的连接处是一个音圈马达该永磁铁和音圈马达就是带动磁头进行左右摆动的用马达往一边摆用磁力吸附回来在磁盘的背面还有控制机器原件的电路这里不做深究。要注意的是在磁盘中一般都会有多个盘片每个盘片的两面都可以存储数据并且都有对应的磁头来看看具体的图片:下面对上方的立体图进行一些讲解在主轴马达的带动下所有的盘片都会以同速同向的方式进行旋转而磁头在磁力和磁头臂的带动下进行左右摆动并且所有磁头的移动轨迹是相同的所有磁头共进退。从图片还可以看出盘片之间都会有间隔盘片的每一面都会有一个对应的磁头。最后提出一个疑问:如果磁头在向盘片写数据时要写入的位置被转过去了要怎么办答案非常简单只需要等该位置被转回来就可以了因此一个磁盘中的盘片转速越高该磁盘的IO效率就越高。3.2磁盘存储数据的原理没学过计算机的人也会知道计算机是使用0和1来存储数据的但是对于我们学计算机的人来说只知道这个肯定是不够的我们还得要知道计算机是怎么使用0和1存储数据的而这个问题的答案在磁盘中就可以得到部分解答了(只有部分),先来看看这副图片:这东西叫条形磁铁相信在坐的各位都是玩过的而这个小玩意就是磁盘存储数据的核心了首先磁铁在物理上存在一种特性:无论一块磁铁被分的多小其总能保持其两级的属性(即N级和S级)那么我们现在可以定义一块磁铁的N级代表1S级代表0然后想象有几亿个非常小的条形磁铁被竖着放在一起其中一个磁铁的N级朝上就代表该位置是1S级朝上就代表该位置是0如果你想象出来了的话那么恭喜你你成功的在你的大脑中构建出了一个磁盘中的盘片没错磁盘中的盘片就是由大量微小的磁铁组成的(具体来说是在铝合金上度一层磁性薄膜)然后利用这些小磁铁的N级和S级表示0和1来记录数据。那么自然就又出现了一个问题用N级和S级确实可以表示0和1但是在盘片上的小磁铁不都是固定的吗那怎么存储变化的数据呢答案藏在高中的物理课本里面简单来说在磁头上有一个小型的电磁铁通电后就可以产生磁性(电流的磁效应)而磁头是可以在盘片上移动的那么在写入数据时磁头就会通电并产生磁性利用磁力把盘片上对应区域的小磁铁进行翻转然后就可以让存储的数据发生变化了(比如把一个原本N级朝上的磁铁反转成S级朝上那么就在数据上就表示从1变为了0磁头同时对盘片上的几万个小磁铁进行这样的操作就可以存储大量有效数据了。有了上方的这些知识就可以回答另一个问题了:为什么磁盘不适合笔记本电脑首先笨重是一方面但最主要的原因还是在笔记本电脑中使用磁盘存储数据容易造成数据丢失。不知道你小时候有没有试过用火烧磁铁试过的朋友就会知道磁铁在受高温后就会失去磁性(消磁)失去磁性的原因藏在大学课本里面本人在此简单的介绍一下(感兴趣的可以看看)首先磁铁的磁性本质上还是由电流产生的在微观层面磁铁的电子会做有一定规律的定向移动(一般是转圈圈)如图:而电子的定向运动就会产生电流然后又由于电流的磁效应磁铁就产生磁性了但是在高温处理后磁铁中的电子就不会再保持定向移动了(可以理解成电子被烫到了然后就到处乱跑)此时电流就不会产生了那么相应的磁性也就被消去了(并且就算恢复了常温磁性也不会恢复)而磁铁失去磁性就意味着无法表示0和1了。下面回到笔记本电脑中首先笔记本电脑一般都是会被频繁的移动的而磁盘又是是机械结构的在移动的过程中磁头就会震动那么磁头就很可能会触碰到盘片此时由于盘片是超高速旋转的那么在触碰的一瞬间就会产生大量的热(摩擦生热),产生大量的热就会让盘片中被触碰到的区域被消磁那么这片区域的数据就会丢失了。4.计算机使用磁盘存储数据的方法上方所讲的都是硬件的层面那么下面就来看看要如何从硬件过渡到软件。4.1磁盘的逻辑划分如果是让你来设计你要怎么来使用磁盘存储数据呢难道是随心所欲想存放在盘片的哪个位置就存放在哪个位置吗如果是这样的话那么存了也是白存因为你下一次就找不到之前存放的数据了在这里要说明的是在计算机中把数据储存起来并不困难困难的是要怎么定位到存储的数据定位在计算机的任何一个地方都非常的重要(在硬件中要定位在软件中同样也要定位)因此在设计磁盘的存储方式时首先想到的不应该是怎么存储数据而是要想怎么定位数据。那么下面就来看看要怎么在磁盘的盘片中设计出定位机制先来举个生活中的例子你让快递员送快递时首先就要给他你家的地址比如某某省某某市某某县....很容易就可以看出来地址是越来越精细的也就是说在生活中定位最重要的就是不断的进行划分从国到省到市...一直到你家你在让快递员送快递时难道会这样说吗:我家在中国你把快递送过来吧。这不扯淡吗快递员找一辈子都找不到你家在哪里。而在计算机的存储设备中也是如此所有的存储设备在设计定位时最重要的一步就是进行划分要注意的是无论是划分生活中的地址还是划分存储设备中的存储区域都是逻辑上的划分比如你家的地址是人为定义的在物理上并不会在你家的附近造出一堵高高的墙上面写着这是某某某人的家为计算机的存储设备进行划分也是如此仅仅只是逻辑想象上的划分。(在计算机中存在大量的逻辑概念和物理概念分清楚一个概念是逻辑上的还是物理上的是非常重要的)接下来回到主题我们现在已经知道要在磁盘的盘片中存储数据首先就应该对磁盘的盘片进行划分下面就来看看具体要怎么划分先来看看盘片的正面逻辑划分图:可以看到首先第一层划分是使用多个同心圆吧一片磁盘分成一圈圈磁道(灰色的小圆环)每个磁道之间隔着一定的距离(实际上隔的没这么远)并且每一个磁道都会有对应的磁道数磁道从盘外圈向盘内圈依次编号为0, 1, 2.....然后下一层划分就是使用多条过圆心的线段把每一个磁道分成一个个扇区(标绿的那个东西)注意中心的白色区域是插主轴和停放磁头用的不会存储数据这样盘片的一面就被划分成了多个扇区在磁盘中存储数据的基本单位就是扇区了在这里就产生了一个问题从图片中明显可以看出盘片外部的扇区是要比盘片内部的扇区大那存储的数据量不应该是不同的吗对于这个问题扇区的大小不同确实可以存放不同的数据量但是这样的话磁盘中存储单位的大小就会不一致那么就会非常难进行管理了虽然有一部分磁盘的生产厂商确实会根据扇区大小的不同来设定不同的存储空间但是在本文中我们认为盘片中不同大小的扇区存储的数据量是一致的(实际上大部分磁盘的生产厂商都是这么做的)而让大小不同的扇区存放相同的数据量就只需要设置小磁铁的密度就可以了比起让存储单位的大小不一致显然是让盘片中小磁铁的密度不一致更加简单。最后说明一点大部分磁盘中的扇区大小都是512字节的也就是说盘片中的一个扇区可以存放512字节的数据在电脑中没有打开的文件或没有运行起来的程序(二进制可执行文件).....都储存在磁盘的扇区中。下面来详细的解释一下这个512字节可以认为512字节是磁盘进行输入输出(IO)的基本单位就像内存的基本单位是字节那么我们就可以一次向内存写入一个字节的数据但是我们不能向内存中写入1bit位的数据也就是说不能往磁盘中一次写入13或500....字节写入的字节数必须是512的整数倍在读取磁盘中的数据也一样只能读取512字节的整数倍。举个例子如果用户想对磁盘上的数据进行更改那么必须先从磁盘上读取512的整数倍个字节到内存中(就算要修改的数据只有1字节也要读取512字节)CPU再在内存中对数据进行修改最后再把512的整数倍个字节写入到磁盘中所以也把磁盘称为块设备因为其不是以单个字节为IO单位而是以512字节的数据块为单位进行IO 平面图已经介绍完毕下面来看看立体的划分图:可以看到每个盘片的两面都会被划分为多个磁道然后每一条磁道又会被分为多个扇区在这里要说明的是不同盘片中对应磁道的半径是相同的并且半径相同的磁道中扇区的大小也是相同的也就是说盘片每一面的扇区个数都是相同的(这样显然更加便于管理)在这里本人讲解立体图的主要原因就是要引用一个重要的逻辑概念即柱面(就是图中蓝色的那个东西)简单来说柱面就是想象把盘片中所有半径相同的磁道用一个圆柱的面连接起来这个由多个半径相同的磁道组成的圆柱面就是柱面。要重点注意的是柱面是一个逻辑概念在物理上磁盘中是没有柱面这种东西的不过柱面这个逻辑概念非常重要把磁盘硬件进行抽象并使用软件进行管理的关键就是柱面。4.2从硬件存储抽象到软件存储无论是学硬件还是学软件如何让软硬件进行联动都绝对是重中之重可以预见的是在不久的将来当物联网彻底发展起来后软硬件的联动会变得更加重要(这是实现物联网的基础)又比如现在非常火热的机器人想要造出机器人同样需要大量的软硬件联动没有软件控制的硬件就只是铁疙瘩而没有硬件依托的软件就不会有很强的实际意义。因此本节就借着磁盘这个硬件来介绍一下在磁盘中实现软硬件联动的方法。(注最关键的一点就是理解上文所介绍的柱面的概念如果没看懂的可以回去再多看几遍或是问问AI)首先先聚焦于单个盘片的一面我们已经知道盘片会被划分成很多个磁道而数据会被存储在磁铁上的扇区中那么如果我们把一个磁道给剪开并展平会发生什么呢如下图:看到那个长方形是不是感觉非常的熟悉如果还没有看出来的话那就让我们加上下标:我们发现了一个惊人的事实一个磁道被剪开后变成了一个一维数组而扇区就是该一维数组中的存储空间这意味着在逻辑上我们可以将一个磁道视为一个一维数组(即:扇区[ ])既然磁道是一维数组那么由很多个磁道组成的盘片的一面是什么呢把这个问题转换一下就变为了:多个一维数组可以组成什么答案显而易见是二维数组(即:扇区[ ][ ])也就是说在逻辑上我们可以将盘片的一面视为一个二维数组那么最后一个问题由多个盘片的面组成的磁盘存储结构是什么呢同样把问题转换一下就变为了多个二维数组可以组成什么答案用屁股想都知道是三维数组(即:扇区[ ][ ][ ])那么在逻辑上我们就可以将磁盘的整个存储结构视为一个三维数组。让你直接管理磁盘那肯定是两眼一麻黑的但是管理数组那不就是so easy吗毕竟就算是最简单的程序也会用到大量的数组。现在就可以来更深刻的理解一下柱面的本质了在逻辑上我们可以沿着柱面将多个同半径的磁道剪开从三维数组中抽出一个二维数组即可以得出在逻辑上柱面是将三维数组划分成二维数组的基本单位那么现在问你一个问题你在编程时是喜欢用三维数组还是喜欢用一维数组相信绝大多数人都是更喜欢使用一维数组的吧因为一维数组更加直观并且只需要使用一个下标就可以进行数据管理在磁盘中也是如此尽管磁盘在物理上定位扇区使用的是三维数组的下标比如扇区[2][3][6]就表示是在第2个柱面上的第3个磁道中的第6个扇区。但是人们在编写软件管理磁盘空间时并不喜欢使用三维数组进行管理而是选择使用一维数组进行管理那么此时在磁盘中就存在了两种寻址方式(找扇区的方式)即磁盘实际使用的三维寻址(CHS地址和在软件层面便于管理的一维寻址方式(LAB地址这两种地址之间可以按照一定的计算方法进行转换下面就来详细介绍一下。首先回答读者最可能产生的第一个问题:三维数组要如何转换成一维数组一维数组又要如何转换成三维数组来看看下面的图片:在计算机中实际上是只存在一维数组的因为在内存中存储时无论是多少维的数组实际上都是连续线性的进行存储的所谓高维的数组其实就是人们为了便于进行图形化的想象而把内存中的一维数组以不同的形式进行表示罢了比如上方的图片最右侧的就是一维数组我们把它剪开并叠起来就可以得到二维数组按照同样的方式再来一次就可以得到三维数组了。在这里要说明的是在计算机的世界中高维的数据是非常常见的而维度的转换也是非常常见的不过这些就是线性代数中的内容了这里就不再介绍了。下面回到计算机中让我们来详细的看看CHS地址和LAB地址以及它们两个是如何进行转换的。(如果是只搞软件的那么下面介绍的这些内容几乎不会用到本文加上这些内容也仅仅只是为了保证知识的连贯性当然知识肯定是不嫌多的感兴趣的就继续往下看吧CHS地址物理上由逻辑上结构的抽象后在实际物理的角度访问磁盘上具体位置的扇区时就类似于访问三维数组中的一个元素由此就产生了CHS地址。1.首先确定要访问哪一个柱面每个柱面都有编号 柱面(C)cylinder 三维降二维2.由磁头确定要访问的扇区在柱面的哪一个磁道上(确定磁道) 磁头(H)head 二维降一维3.最后再在磁道上找到要访问的扇区 扇区(S)sector因此CHS的本质上就是三维数组的数组下标三维线性地址比如上文所提到的:扇区[2][3][6]就表示是在第2个柱面上的第3个磁道中的第6个扇区下面来看看LAB地址(逻辑上)LAB地址就是把磁盘存储结构抽象成一维数组后一维数组的下标本质上就是一个维线性地址操作系统使用LAB地址管理磁盘的储存结构在原则上使用LAB地址时操作系统只需要知道磁盘的总容量那么就可以通过一定的计算方式来定位到每一个扇区的位置下面就来看看具体的转换方式。首先来看看具体要怎么使用柱面来计算出磁盘的总大小:磁盘容量磁头数*柱面数*单磁道扇区数*每扇区字节数,比如一个磁盘中有6个磁头(这意味着有6个盘片的面因为盘片的每一面都会对应一个磁头)有8个柱面(这意味着在一个盘面上会存在8条磁道因为半径相同的多个磁道才可以组成柱面)转换一下就变为了一个盘面上有8条磁道一共有6个盘面也就是说磁头数*柱面数 盘面数*单个盘面的总磁道数 磁盘中的总磁道数那么上方的式子就变为了:磁盘容量 磁盘中的总磁道数 * 单磁道扇区数 * 每扇区字节数而:磁盘中的总磁道数 * 单磁道扇区数磁盘的总扇区数那么最后该式子就变为了:磁盘容量 磁盘的总扇区数* 每扇区字节数这样是不是就看懂了。然后来看看CHS地址和LAB地址之间是怎么进行转换的首先明确已知的信息(顺便复习一下上文的内容):1.每一个柱面的储存空间大小是相同的三维数组中的每一个二维数组的元素数相同柱面中的每一个磁道的储存空间大小也是相同的二维数组中的每一个一维数组的元素数相同磁道中的每一个扇区的储存空间大小也是相同的(512字节)2.操作系统使用LBA地址(逻辑地址)管理磁盘空间但是在磁盘实际寻找扇区时需要CHS地址(物理地址)而磁盘通过CHS地址找到的扇区也需要转换为LBA地址才能与操作系统进行交互因此必须进行转换。3.扇区的下标是从1开始的(这是为了统一规则从便于操作数组的角度可以认为下标是从0开始的然后只需要在计算扇区号时1就可以了每一个柱面都有编号从最外围到内部0,1,2....),每一个磁头也有编号编号从0开始。4.一个柱面上有多少个扇区是固定的一个磁道上有多少个扇区也是固定的然后来看看要如何从LBA转换为CHS (一维数组下标转换为三维数组下标先来看看几条计算规则:1.磁头数 盘面数 单个柱面的磁道总数2.单个柱面的总扇区数 磁头数 * 单个磁道上的扇区总数3.柱面号C LBA下标 // 单个柱面总扇区数 //表示整除注:LAB下标就是LAB地址,说成下标是为了便于从数组的视角进行理解。4.磁头号H(磁头在柱面中的哪一个磁道 (LBA下标 % 单个柱面总扇区数) // 单个磁道总扇区数5.扇区号S LBA下标 % 单个磁道扇区数 1 注此时的起始位置是第二步计算出来的磁道处6.LBA % 单个柱面总扇区数:得出此时指定扇区在单个柱面的第几号下标位置处7.扇区在单个柱面的第几号下标 // 单个磁道总扇区数得出此时指定扇区在单个柱面中的哪一个磁道处看起来就非常的复杂下面就来讲解一下上面这堆东西吧(第一条和第二条是显而易见的这里不做讲解)首先我们现在已知的是LAB地址我们的目的是把LAB地址给转换成CHS地址而LAB地址只有一个数(一维数组下标)CHS地址有三个数(三维数组下标分别是柱面号C磁头号H扇区号S)那么问题就可以抽象成:我们要使用一定的计算规则把一个数分为三个数。在讲解这种抽象的规则时单单的语言讲解是抽象且不生动的所以必须要有具体的实例因此我们假设有一个磁盘该磁盘有2张盘片(4个盘面)4个磁头每个盘面上都有3圈磁道每圈磁道上都有6个扇区即先来通过磁盘容量磁头数*柱面数*单磁道扇区数*每扇区字节数计算一下磁盘的总大小磁盘容量4(磁头数) * 3(柱面数,就是磁道数) * 6(单磁道扇区数) * 512(单个扇区大小) 36864字节(这是一个小的可怜的磁盘)并且还可以计算出该磁盘的总扇区数为72单个柱面的扇区数为24(72/3),下面就来把磁盘展平变为一维数组(只看前50个扇区):该图片就是把0号扇区和1号扇区展开的情况磁头数会重复是因为每一个磁头都可以移动到不同的柱面(没明白的话就配合着立体图想象吧)好了前置工作已经完成下面我们假设已知28号LAB地址(下标)来看看要怎么通过上方的计算方法吧这个26转换成CHS地址首先我们从图就可得26转换成CHS地址应该是:[1][0][3],表示在第一个柱面内的0号磁道(0号磁头)中的第三个扇区。下面来验证一下先来使用3号计算方法计算出柱面号C 26 // 24 1是正确的可以认为该操作是加上了扇区前方的整柱面然后就可以得出其所在的柱面然后来使用4号方法计算方法计算出磁头号H (26 % 24) // 6 2 // 6 0答案是正确的第一个取模操作可以认为是把扇区前方的整柱面给去掉了让该扇区只从其所在的柱面开始计数后面的//操作就是加上该扇区前方的磁道数然后就可以得出其所在的正确磁道数了最后来使用5号计算方法计算出扇区号S (26 % 6) 1 2 1 3答案是正确的前方的取模操作可以认为是把扇区前方的整磁道给去掉了让该扇区从其所在的磁道开始计数后面的1是因为LAB地址(数组下标)是从1开始的。这里确实比较复杂本人已经尽量讲解的详细了在这里要说明的是除非你是做磁盘的不然这里的知识其实是不怎么重要的没看懂也不要慌直接跳过就可以了。最难的已经过去了下面来看看要怎么把CHS地址转换为LAB地址LBA地址 柱面号 * 单个柱面中的扇区数 磁头号 * 单个磁道上的扇区数 扇区号 - 1式子只有一条现在我们同样使用上方的示例假设我们已知CHS地址为[1][0][3]根据该计算方法可得LAB 1 * 24 0 * 6 3 - 1 26答案是正确的对于该式子柱面号 * 单个柱面中的扇区数就是把前方的整柱面的扇区都加上磁头号 * 单个磁道上的扇区数就是把不完整扇区中的整磁道扇区都加上最后的扇区号 - 1就是把不完整磁道中的扇区都加上要减一是因为扇区的LAB地址是从1开始的。好了两者转换方法都已经介绍完毕确实比较难理解读者如果还想了解的更深入的话就要去学学计算机组成原理了。4.3操作系统加载磁盘数据的基本单位在上文已经说过磁盘的存储单位是扇区(512字节)但是操作系统在加载磁盘数据时一般不是以扇区为单位进行加载(把磁盘数据加载到内存中)的也就是说操作系统在和磁盘进行IO操作时不会一次只读取一个扇区的数据而是会一次读取多个扇区的数据一般而言磁盘中的八个扇区(512字节*8即4kb)就可以组成一个块而块就是操作系统向磁盘文件IO的最小单位也就是说操作系统与磁盘进行IO时一次最少会加载或输出8个扇区。在这里单独聊这个东西是因为块(4kb)在电脑中是一个非常重要的东西许多IO的单位都是4kb比如操作系统在划分内存条中的空间时也会以4kb为单位进行划分内存中的每一个块(4kb)都被称为一个页框然后还有更加复杂的虚拟地址空间机制该机制也是基于这个4kb实现的不过这并不是本文的重点(本人会在之后的对Linux操作系统的讲解bolg中进行详细说明)读者只需要记住4kb这个数字非常重要就可以了。下面让我们回到磁盘提出一个问题为什么操作系统要以块为IO的单位以块为IO单位就意味着就算只加载1字节数据到内存操作系统也会加载一个块(就算会造成内存浪费)答案非常简单首先由于局部性原理以块为单位进行加载一般并不会造成很大的空间浪费其次如果以扇区为加载的单位就会导致操作系统访问磁盘的次数变多比如此时加载4kb的数据操作系统访问8次磁盘要知道磁盘是外设在冯诺依曼体系中已经提到过与外设进行IO操作是非常消耗时间的因此不能以扇区为磁盘IO的单位在这里要说明的是:一般而言在计算机中时间资源都是比空间资源珍贵的因此在计算机中拿空间换时间是非常常见的操作(不少算法都是基于这个原理设计的)而磁盘以块为IO的单位本质上也就是一个以空间换时间的操作最后的原因是在软件层以4kb为单位可以实现软硬件的解耦具体是什么意思呢举个例子如果你想要扩大你电脑的容量那么你可以直接去买一个任意品牌的磁盘然后只需要装到你的电脑上就可以了这是一个常识但是如果没有在软件层统一指定以4kb为IO单位那么就可能会出现A磁盘厂以90字节为IO单位B磁盘厂以70字节为IO单位......哦这种操作简直是计算机世界的灾难在意味着你每一次装磁盘都是一次电脑的重装并且连操作系统也要进行相应的调整这实在是太恐怖了。在这里要补充的是电脑本身几乎实现了所有设备所有软硬件的完全解耦(前人的智慧真是太NB了)这也是你可以在不同的硬件上跑相同的软件的原因同样也是你可以任意更换电脑鼠标键盘网卡甚至是CPU的原因。5.总结好了本文到这里就差不多结束了在本人看来本文最重要的是如何把硬件抽象成软件的思维这种磁盘是死的但是思维是活的在其它许多设备上也会使用到这种思维(比如数控机床电控机器....)最后要补充的是数组是一种非常厉害的数据结构(在本文中也有体现)如果你是初学者那么你可能会由于数组操作的简单性而认为这个东西不怎么厉害但要明白操作简单本身就是数组的一大优势并且数组天生就带有下标的属性意味着其几乎所有的数据操作都是O(1)的空间复杂度(这在其它数据结构中几乎是不可能的)最后由于数组在内存中是连续存储的这就意味着使用数组不会产生内存碎片数组的优势数不胜数(比如自带哈希映射)希望读者可以意识到这一点并在以后的编程生涯中好好使用这个核武器。如果在看完本文后你对磁盘不再是两眼一麻黑的了那么这篇文章的基本目的就达到了如果你还大概了解到了从硬件抽象成软件的思维那就再好不过了总之希望这篇文章能让读者有所收获。