惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
L
LINUX DO - 热门话题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
V
V2EX
GbyAI
GbyAI
量子位
Microsoft Azure Blog
Microsoft Azure Blog
有赞技术团队
有赞技术团队
G
Google Developers Blog
云风的 BLOG
云风的 BLOG
B
Blog
Microsoft Security Blog
Microsoft Security Blog
S
SegmentFault 最新的问题
O
OpenAI News
N
News and Events Feed by Topic
博客园 - Franky
爱范儿
爱范儿
Forbes - Security
Forbes - Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V2EX - 技术
V2EX - 技术
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News and Events Feed by Topic
N
News | PayPal Newsroom
Schneier on Security
Schneier on Security
Cloudbric
Cloudbric
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recent Commits to openclaw:main
Recent Commits to openclaw:main
人人都是产品经理
人人都是产品经理
P
Privacy International News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
Last Week in AI
Last Week in AI
罗磊的独立博客
Spread Privacy
Spread Privacy
Recent Announcements
Recent Announcements
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
AWS News Blog
AWS News Blog
The Register - Security
The Register - Security
Y
Y Combinator Blog
J
Java Code Geeks
I
Intezer

博客园 - 空空儿

JavaScript里String.Format方法的实现 asp.net异步页 获取SQL Server数据行的物理地址信息(%%lockress%% & %%physloc%%) 利用Spire.DataExport将数据(Database/DataTable)导成各种文件 使用XML的value()方法将多行数据合并成一列 获取所有的外键信息 ASP.NET application and page life cycle SQL Server 2005 CLR 调用Web Service需要注意的几个问题 SQL SERVRE 2005 CLR TVF错误:从用户定义的表值函数获取新行时出错:Data access is not allowed in this context. PHP执行MYSQL存储过程报错:Commands out of sync; you can't run this command now 在C#里使用属性 - 空空儿 - 博客园 Read text file (txt, csv, log, tab, fixed length) 批量写数据---将XML数据批量写入数据库 对对象类型和调用方法属性进行存储以提升反射性能 过程 sp_addlinkedsrvlogin,第 91 行解密过程中出错的解决办法 生成大量随机字符串不同实现方式的效率对比 用SQL SERVER 2005新提供的命令实现行列转换 APM (异步编程模型) 利用宏让ERStudio生成代码文件
硬盘分区、寻址和系统启动过程
空空儿 · 2016-11-22 · via 博客园 - 空空儿
硬盘划分为磁头(Head)、柱面(Cylinder)、扇区(Sector)。
磁道: 每个盘面都有 n 个同心圆组成,每个同心圆称之为一个磁道。由外向内分为 0 磁道到 n 磁道。 磁头(Head):每张磁片的正反两面各有一个磁头,一个磁头对应一张磁片的一个面。磁头固定在可移动的机械臂上,用于读写数据。现代硬盘都是双面可读写,因此磁头数量等于盘片数的 2 倍。磁头数最大值为 255 (8 个二进制位)。 柱面(Cylinder):所有磁片中半径相同的同心磁道构成“柱面"。简单地理解,柱面就是磁道。n 个盘面的相同磁道 (位置相同) 共同组成一个柱面。柱面数最大为 1023 (10 个二进制位) 扇区(Sector):从磁盘中心向外画直线,可以将磁道划分为若干个弧段。每个磁道上一个弧段被称之为一个扇区。扇区是硬盘的最小组成单元,通常是 512 字节。磁道上的扇区数最大为 63 (6 个二进制位)。 硬盘容量=磁头数×柱面数×扇区数×512字节

在老式硬盘中,尽管磁道周长不同,但每个磁道上的扇区数是相等的,越往圆心扇区弧段越短,但其存储密度越高。不过这种方式显然比较浪费空间,因此现代硬盘则改为等密度结构,这意味着外围磁道上的扇区数量要大于内圈的磁道,寻址方式也改为以扇区为单位的线性寻址。
为了兼容老式的 3D 寻址方式,现代硬盘控制器中都有一个地址翻译器将 3D 寻址参数翻译为线性参数.

硬盘物理结构

先看下硬盘物理结构

 

                           1 硬盘物理结构

硬盘物理上主要是盘片、机械手臂、磁头、和主轴等组成。在盘片逻辑划分上又分为磁道、扇区,例如下图:

 

                             2 盘片磁道、扇区

磁道(Track):

当硬盘盘片旋转时,磁头若保持在一个位置上,则磁头会在盘片表面划出一个圆形轨迹,这些圆形轨迹就叫做磁道。以盘片中心为圆心,由此可以划分出很多磁道来, 这些磁道用肉眼是根本看不到的,因为它们仅 是盘面上以特殊方式磁化了的一些磁化区,硬盘上的信息便是沿着这样的轨道存放的,盘片上的磁道由外向内依次从“0”开始进行编号。

 

柱面(Cylinder):

由于硬盘可以由很多盘片组成,不同盘片的相同磁道就组成了柱面(cylinder),如图1所示。

磁头(Head):

假设有N个盘片组成的硬盘,那么有2N个盘面(一个盘片有2面),那么磁头也就有2N个,即每个盘面有一个磁头。

扇区 (Sector):

早期的硬盘盘片的盘面以圆心开始向外放射状将磁道分割成等分的弧段,这些弧段便是硬盘的扇区(如图2)。每个扇区一般规定大小为512byte,这里大家应该比较疑惑,外圈周长很明显比内圈要长,怎么可能每个扇区都是512byte?其实答案早期硬盘外圈存储比内圈存储密度低一些,所以外圈很长但是仍然只能存储512byte,因此如果我们知道了柱面数(磁道数) Cylinders、磁头数Heads、扇区数Sectors,基本上硬盘的容量我们能够计算出来 硬盘总容量= Cylinders * Heads * Sectors * 512byte。 但是由于早期硬盘外圈密度低,导致盘片利用率不高,现在的硬盘盘片则采用内外存储密度一致的方式,每个磁道都划分成以512byte大小的弧段,这样也造成了内外磁道上扇区数量会不一样,外圈上的扇区数要多于内圈扇区数。

硬盘寻址方式

硬盘存取、读取数据,首先要做的就是寻址,即定位到数据所在的物理地址,在硬盘上就要找到对应的柱面、磁头以及对应的扇区,那么怎么寻址呢?   有两种方式:CHS和LBA

CHS模式:

CHS(Cylinder/Head/Sector)寻址模式也称为3D模式,是硬盘最早采用的寻址模式,它是在硬盘容量较小的前提下产生的。

硬盘的C/H/S 3D参数(Disk Geometry)既可以计算出硬盘的容量,也可以确定数据所在的具体位置。这是因为扇区的三维物理地址与硬盘上的物理扇区一一对应,即三维物理地址可完全确定硬盘上的物理扇区。三维物理地址通常以C/H/S的次序来书写,如C/H/S为0/1/1,则第一个数字0指0柱面,第二个数字1指1磁头(盘面),第三个数字1指1扇区,表示该数据位于硬盘1盘面上的0磁道1扇区。现在定位已完成,硬盘内部的参数和主板BIOS之间进行协议,正确发出寻址信号,从而正确定位数据位置。

早期硬盘一个磁道上分63个扇区,物理磁头最多16个(8个盘片,盘片多了硬盘那就真要加厚了)。采用8位寻址方式,8位二进制位的最大值是256(0-255),可以表示磁头数,而扇区只有63个(1-63),只需要其中6个二进制位即可表示,剩下2位拿去表示柱面,柱面数用10(8+2)位来表达,达到1024个柱面(0-1023),因此总扇区数(1024×16×63)。前面说一个扇区大小为512byte,这也就是说,如果以C/H/S寻址模式寻址,则IDE硬盘的最大容量只能为1024×16×63×512B= 500MB左右。

   可以思考下,在8位寻址模式下,其实可以寻址的硬盘最大容量为1024×256×63×512B =8G,那为啥CHS模式硬盘只支持到500MB呢?原因很简单,我们的硬盘盘片不可能让128片盘片重叠起来吧,那会是多厚??如果采用28位寻址方式,那么可以寻址137G,盘片也不可能一直堆叠下去。  

LBA(Logical Block Addressing)

   经常去买硬盘的人都知道,目前硬盘经常都说单碟、双碟,其实意思就是说硬盘盘片只有1个或者2个,而且都只是用一面,单碟一个磁头而已,但是硬盘容量确是几百G,而且硬盘柱面往往都大于1024个柱面,CHS是无法寻址利用完这些硬盘容量的。

另外由于老硬盘的扇区划分方式对硬盘利用率不高,因此出现了现在的等密度盘,外圈的扇区数要比内圈多,原来的3D寻址方式也就不能适应这种方式,因此也就出现了新的寻址方式LBA,这是以扇区为单位进行的线性寻址方式,即从最外圈柱面0开始,依次将扇区号编为0、1….等等,举个例子,假设硬盘有1024个柱面,由于是等密度硬盘,柱面0(最外圈)假设有128个扇区,依次编号为0-127,柱面1有120个扇区,则依次编号为127-246,…..依次最内圈柱面127只有扇区64个,则编号到最后。因此要定位到硬盘某个位置,只需要给出LBA数即可,这个就是逻辑数。

  在LBA方式下,系统把所有的物理扇区都按照某种方式或规则看做是一个线性编号的扇区,即从0到某个最大值方式排列,并连成一条线,把LBA作为一个整体来对待,而不再是具体的实际的C/H/S值,这样只用一个序数就确定了一个惟一的物理扇区,显然线性地址是物理扇区的逻辑地址。

为了保留原来CHS时的概念,也可以设置柱面、磁头、扇区等参数,但是他们并不是实际硬盘的物理参数,只是为了计算方便而出的一个概念,1023之前的柱面号都一一物理对应,而1023以后的所有柱面号都记录成1023磁头最大数可以设置为255,而扇区数一般是每磁道63个,硬盘控制器内部的地址翻译器会把由柱面、磁头、扇区等参数确定的地址转换为LBA地址。

 物理扇区号:

一般我们称CHS模式下的扇区号为物理扇区号,扇区编号开始位置是1

 逻辑扇区号:

LBA下的编号,扇区编号是从0开始。

CHS模式转换到逻辑扇区号LBA

计算公式

 由于系统在写入数据时是按照从柱面到柱面的方式,在上一个柱面写满数据后才移动磁头到下一个柱面,并从柱面的第一个磁头的第一个扇区开始写入,从而使磁盘性能最优,所以,在对物理扇区进行线性编址时,也按照这种方式进行。即把第一柱面(0柱)第一磁头(0面)的第一扇区(1扇区)编为逻辑“0”扇区,把第一柱面(0柱)第一磁头(0面)的第二扇区(2扇区)编为逻辑“1”扇区,直至第一柱面(0柱)第一磁头(0面)的第63扇区(63扇区)编为逻辑“62”扇区,然后转到第一柱面(0柱)第二磁头(1面)的第一扇区(1扇区),接着上面编为逻辑“63”扇区,0柱面所有扇区编号完毕后转到1柱面的0磁头1扇区,依次往下进行,直至把所有的扇区都编上号。

 另外还要注意C/H/S中的扇区编号从“1”至“63”,而LBA方式下扇区从“0”开始编号,所有扇区顺序进行编号。

从C/H/S到LBA的转换公式

C表示当前柱面号,

H表示当前磁头号,

S表示当前扇区号,

CS表示起始柱面号,HS表示起始磁头号,SS表示起始扇区号,PS表示每磁道扇区数,PH表示每柱面磁道数,所以公式为:

LBA=(C–CS)﹡PH﹡PS+(H–HS)﹡PS+(S–SS)

一般情况下,CS=0,HS=0,SS=1,PS=63,PH=255。

下面带入几个值验证一下:

当C/H/S=0/0/1时,代入公式得LBA=0

当C/H/S=0/0/63时,代入公式得LBA=62

当C/H/S=0/1/1时,代入公式得LBA=63

从LBA到C/H/S的转换公式为

DIV为整除运算,MOD为取商的余数

C=LBA DIV (PH﹡PS)+CS

H=(LBA DIV PS)MOD PH+HS

S=LBA MOD PS+SS

同样可以带入几个值进行验证:

当LBA=0时,代入公式得C/H/S=0/0/1

当LBA=62时,代入公式得C/H/S=0/0/63

当LBA=63时,代入公式得C/H/S=0/1/1

硬盘分区

我们知道,一般使用硬盘,我们首先会对硬盘进行分区,然后对分区使用某个文件系统格式(NTFS、FAT、ext2/ext3)进行分区格式化,然后才能正常使用。那么分区是怎么回事呢?我们常见的windows中说到的c、d、e盘是怎么划分出来的呢?其实,在装windows系统过程中,一般我们只需要填写每个分区的大小,看不出来分区过程的实际工作情况,我们可以从linux系统分区过程反而能反应底层实际分区情况。

柱面是分区的最小单位,即分区是以某个某个柱面号开始到某个柱面号结束的。

 

如图,柱面1~200我们可以分为一个区,柱面201~500再划分为一个区,501~1000再划分为一个区,以此类推。大家可以看到,柱面0没有在任何分区里面,为何?这里说说,前面说到硬盘从外圈(柱面0)到内圈扇区是依次编号,看似各个扇区没有什么区别,但是这里硬盘的柱面0的第一个扇区(逻辑扇区0,CHS表示应该是0/0/1)却是最重要的,因为硬盘的第一个扇区记录了整个硬盘的重要信息,第一个扇区(512个字节)主要记录了两部分:

①    MBR(Master Boot Record):主引导程序就放在这里,主引导程序是引导操作系统的一个程序,但是这部分只占446字节。

②    DPT(Disk Partition table):硬盘分区表也在这里,分区表就是用来记录硬盘的分区情况的,例如c盘是1~200柱面,d盘是201~500柱面,分区表总共只占64字节,可以看出,分区其实很简单,就是在这个表里面修改一下记录就重新分区了,但是由于只有64字节,而一条记录就要占用16字节,这个分区表最多只能记录4个分区信息,为了继续分出更多分区来,引入了扩展分区的概念,也就是说,在这4个分区中,可以使用其中一条记录来记录扩展分区的信息,然后在扩展分区中再继续划分逻辑分区,而逻辑分区的分区记录则记录在扩展分区的第一个扇区中,如此则可以像链表一样划分出很多分区来。但是请注意,一个分区表中可以有1~4条主分区,但是最多只能有1个扩展分区。

举例,主分区可以是P1:1~200,扩展分区P2: 2~1400,扩展分区开始的第一个扇区可以用来记录扩展分区中划分出来的逻辑分区。

 

分区表链

       分区表之间是如何关联的,详细讲一下,分区表是一个单向链表,第一个分区表,也就是位于硬盘第一个扇区中的DPT,可以有一项记录扩展分区的起始位置柱面,类似于指针的概念,指向扩展分区(图3),根据这项记录我们可以找到扩展分区的某柱面0磁头1扇区(CHS),而这个扇区中又存放了第二个分区表,第二个分区表第一项记录一般表述了当前所在的逻辑分区的起始/终止柱面,第二项记录表述了下一个逻辑分区所在的0磁头1扇区(CHS),第三、第四项记录不存任何信息(图4)。

  请看下图,主引导记录/分区表所在的是硬盘第一个分区,基本分区1、基本分2、基本分区3都是主分区、扩展分区内有2个逻辑分区,每个逻辑分区的第一个扇区都是分区表,至于引导扇区(DBR),在系统启动一节中会提及。

 

系统启动:

 之前提到MBR中安装的引导加载程序,他的作用是什么?

①    提供开机菜单选项:可以供用户选择启动哪个操作系统,这是多重引导功能。

②    加载操作系统内核:每个操作系统都有自己的内核,需要引导程序来加载

③    转交给其他引导程序:可以将工作移交给其他引导程序来进行上述操作。

  其实引导加载程序除了可以安装在MBR中,还可以直接安装在每个分区的引导扇区(DBR)中,注意下,每个分区(主分区、逻辑分区)都有一个自己的启动扇区,专门用来安装引导加载程序,如上图标3结构图。

系统启动过程:

①    首先,BIOS启动后,读取硬盘第一个扇区MBR中的引导加载程序(可能是windows或者linux的grub)

②    MBR中的引导程序提供开机菜单,你可以选择1)直接加载windows 内核 2)将工作转交给windows 分区内的引导扇区中的加载程序,让他自己去加载内核 3)转交给linux分区内引导扇区,让他去加载linux.

③    根据用户选择的选项和引导加载程序中记录的分区,到分区表找对应的分区柱面号等分区信息,启动内核或者分区加载程序。

Window安装时默认会自动将MBR和windows所在分区的引导扇区都装上引导程序,而不会提供任何选项给用户选择,因此如果之前装过其他操作系统,然后再另外装一个windows时,会把公用的MBR覆盖掉,如此,原来的操作系统就无法启动了。如果先装windows,然后装linux,linux 会覆盖MBR,然后让用户选择是否将windows等其他操作系统的启动项添加进来,如果你选择了添加进来,那么你在开机时就会有两个选项让用户进行选择了。

后记

这里讨论的全部是硬盘相关的东西,光盘不在此列,而且光盘的磁道并不是从外圈到内圈编号,而是从内圈开始编号,这点注意。

硬盘第一个扇区是由MBR和分区表占据,因此0柱面0磁头上剩下的62个扇区一般会空出来保留(这部分保留称为隐藏扇区,因为操作系统读取不到这部分扇区,这部分扇区是提供给BIOS读取的),而系统分区则从0柱面1磁头1扇区开始,折算成LBA=255 × 63 × 0 + 63 × 1 + 1 – 1= 63,即从LBA 63号扇区开始分区。不过查阅有的资料提及到另外一种说法,那就是有的硬盘可能0柱面全部空下来,如果真是这样,那浪费可就真的大了。

对于扩展分区的分区表我们知道也是由扩展分区的第一个扇区开始写,而且是写到每个逻辑驱动器的第一个扇区,同样,扩展分区内的第一个扇区所在的磁道剩余的扇区也会全部空余出来,这些保留的扇区操作系统也是无法读取的,注意在扩展分区的第一个扇区里面是没有引导加载记录的。引导加载记录都是放在隐藏扇区后面的。可以看图3,图4