浅谈硬盘寻址演变
半个月前,我提到了硬盘的一些单位。那今天,借着这些单位,来看一个问题:打开文件时,你的硬盘是怎么找到文件的。
一、“古典概型”
没什么特别的意思。我就突然想起来这个词了。我想说的意思就是,在若干年前,硬盘要如何定位文件呢?
正如之前的内容所说,一块硬盘里有多张碟片,每个碟片有两个磁头,在磁道上读写着它所对应的碟片面的扇区,而所有碟片的相同半径的磁道就构成了柱面。想一想,磁头可以确定一个扇区所在的碟片面,碟片切柱面便得到了扇区所在的磁道,再加上扇区号,这三个维度便可以确定一个扇区了。
这就是传统的三维寻址,学名叫C(Cylinder,柱面)H(Head,磁头)S(Sector,扇区)寻址方式。注意,这种方式下,磁头和柱面从0开始计算,而扇区数则是从1开始算的。至于为什么这么定义,标准。因为当年的IBM兼容机就是这么规定的,你要想兼容,那按要求做就行了。
规定的这一部分稍微的扩展一些吧:在IBM兼容机中,INT 13H中断被用作硬盘操作。如果调用这个中断来读写硬盘,就需要一组CHS参数来定位一个扇区。其中,C用10个二进制位存储,最大到1023;H用8个二进制位存储,最大255;S用6个二进制位存储,最大63. 而一个扇区的大小一般是512B,所以调用了INT 13H中断的程序,只能读写到1023 * 255 * 63 * 512
字节大小的硬盘区域,核算过来就是可以读写到硬盘前8G左右的扇区。但现在的硬盘肯定远远大于8G,所以为了照顾使用INT 13H的老程序,微软等几家公司制定了扩展INT 13H标准,又出现了采用线性寻址方式来操作硬盘,从而突破了这个限制。
而线性寻址,也是当今机械硬盘主要的寻址方式。全称逻辑块寻址,缩写LBA(Logical Block Address)。
二、LBA
这种寻址方式就简单粗暴了很多。从0柱面0磁头1扇区开始,一直到最后一个柱面最后一个磁头最后一个扇区结束,每一个扇区都有一个独一无二的序号,这个序号是从0开始记录的。也就是说,0柱面0磁头1扇区转换到线性地址上就是逻辑0扇区,这便是“扇区从0还是从1开始的”这种矛盾症结所在,知道就行了。
再来看LBA本身。它其实也有一个进化的过程。
CHS寻址,就像之前所说,一共用了24个二进制位来存储了坐标的3个量,LBA一开始也用了24位。区别只限于CHS将这24位分成了3份,LBA则用来保存一个数。那这个数有多大呢?16777215. 算上可以用0了,一个可以编号16777216个扇区。这有多大?8589934592字节。注意哦,单位是字节,换算过来只有8.6G多一些。很明显,啥用都没有。因此,LBA扩大了一次存储的二进制位数,达到了28位。这时候能编号多少扇区了呢?268435456。核算过来最大容量137.4G左右。很明显还是不够啊,因此LBA再次进行了扩展,用48位来保存。此时不考虑其他的情况下,按512字节一扇区来计算,可以访问到144PB的位置,这个数量级,一段时间内应该够用了。
容量问题解决了,再来看一个问题:我已经知道逻辑0扇区对应的CHS坐标了,那么之后的序号按什么顺序排列呢?我是把0柱面1磁头1扇区编号为逻辑1扇区,还是把0柱面0磁头2扇区编号为逻辑1扇区呢?在了解了磁盘使用扇区的顺序之后,你应该就能知道了。
现在的多碟片硬盘,虽然有多个磁头,但往往都是由一个轴统一带动的。因此很容易想象出来,同一时刻,各个磁头会处在同一个磁道——或者说柱面上面。而移动磁头到其他柱面是硬盘读写过程中最消耗时间的一个步骤,所以尽最大可能让磁头不动才能确保有更高的执行效率。因此,编号从0柱面0磁头1扇区开始,到0柱面0磁头这一圈都编好序号之后,才会切换到0柱面1磁头1扇区继续编号,从而保证了效率最高。
你可能会有一个疑问:移动磁头最耗时间,那磁盘转动同样要消耗时间。这么一看,好像不需要任何机械动作的切换读写磁头这个动作才是最快的。那为什么我不先把所有柱面同一位值的扇区都写完,再切换到下一个扇区的位置呢?换句话说,为什么不按照0柱面0磁头1扇区 - 0柱面1磁头1扇区 - 0柱面2磁头1扇区这个顺序给扇区编号呢?另外,就像前边我说到的,其实扩展INT 13H也打破了8G界限。如果你想计算的话,在28位LBA的时候,CHS28位同样可以记录到136G多的位置(CHS寻址下,28位分成这三份:柱面使用两个寄存器共16位,扇区用一个寄存器共8位,磁头用一半寄存器共4位)。但为什么好好地CHS就被抛弃了,硬要造一个线性寻址方式呢?以后再说。