3 - 磁盘分区

各个硬件设备在Linux中的文件名称

在Linux系统当中,每个设备都被当做一个文件来对待。

设备 设备在Linux中的文件名称
SCSI、SATA、USB磁盘驱动器 /dev/sd[a-p]
U盘 /dev/sd[a-p]  (与SATA相同)
Virtio接口 /dev/vd[a-p]  (用于虚拟机内)
软盘驱动器 /dev/fd[0-7]
打印机

/dev/lp[0-2]     (25针打印机)

/dev/usb/lp[0-15]   (USB接口打印机)

鼠标

/dev/input/mouse[0-15]  (通用)

/dev/psaux     (PS/2接口)

/dev/mouse    (USB接口)

CD-ROM、DVD-ROM

/dev/scd[0-1]  (通用)

/dev/sr[0-1]     (通用,CentOS中常见)

/dev/cdrom     (当前CD-ROM)

磁带机

/dev/ht0          (IDE接口)

/dev/st0          (SATA/SCSI接口)

/dev/tape        (当前磁带)

IDE磁盘驱动器 /dev/hd[a-d]   (旧式系统才有)

由于IDE接口的磁盘驱动器几乎被淘汰了,因此现在连IDE接口的磁盘文件名也都被模拟为/dev/sd[a-p]。此外,如果你使用的是虚拟机,虚拟机内的磁盘是使用模拟器产生的,该模拟器产生的磁盘文件名可能为/dev/vd[a-p]系列,需要注意。

 

磁盘连接方式与设备文件名的关系

正常的物理机器大概使用的都是/dev/sd[a-p],而在虚拟环境当中,为了加速,可能会使用/dev/vd[a-p]这种设备文件名。

Linux内核根据检测到磁盘的顺序来对磁盘进行命名,并非是你所插的位置。比如我的主机里面有五个SATA的插槽,插两块硬盘,分别插在SATA1、SATA5插槽上。那么,插在SATA1的磁盘文件名:/dev/sda。插在SATA2的磁盘文件名:/dev/sdb。

磁盘主要有碟片、机械手臂、磁头与主轴马达所组成,而数据的写入就是在磁盘上面。碟片上面可以细分出扇区与磁道两种单位。其中扇区的物理大小设计有两种,分别是512字节和4k字节。

整块磁盘的第一个扇区特别重要,因为它记录了整块磁盘的重要信息。早期磁盘第一个扇区里面含有的重要信息我们称为MBR格式,但是由于近些年来磁盘的容量被不断的扩大,因此后来又多了一个新的磁盘分区格式,称为GPT。

 

MBR与GPT磁盘分区表

通常磁盘可能有多个碟片,所有碟片的第一个磁道我们称为柱面,通常那是文件系统的最小单位,也是分区的最小单位。因为近年来有GPT这个可高达64位记录功能的分区表,所以我们现在也可以使用扇区号码来作为分区单位。

我们是采用参考对照柱面或者扇区号码的方式来处理分区的,所以目前分区表有两种格式。

MBR(MS-DOS)分区表格式

早期的Linux为了兼容Windows,因此使用的是支持Windows的MBR的方式来处理启动引导程序和分区表。启动引导程序和分区表都被放在磁盘的第一个扇区,这个扇区通常是512字节大小。

第一个扇区的512字节主要会有两种东西,主引导记录和分区表。

主引导记录(Master Boot Record,MBR):可以安装启动引导程序的地方,有446字节。

分区表(Partition Table):记录整块硬盘分区状态,有64字节。

由于分区表所在的区块仅有64字节容量,因此最多仅能有四组记录区,每一组记录区都记录了该区域的起始于结束的柱面号码。

其实所谓的分区只是针对那个64字节的分区表进行设置而已。硬盘默认的分区表仅能写入四组分区信息,这四组信息被我们称为主要(Primary)或者扩展(Extended)分区。

分区的最小单位通常为柱面,当系统要写入磁盘的时候,一定会参考磁盘分区表,才能针对某个分区进行处理。假设硬盘有400个柱面,共划分为四个分区,当你有数据要写入某个分区的时候,系统会先查看这个分区是从哪个柱面开始,哪个柱面结束。

既然分区表只能记录四组数据空间,那么是否代表一个硬盘只能划分出四个分区呢?当然不是。

在Windows与Linux系统当中,我们是通过刚刚谈到的扩展分区的方式来处理的。扩展分区的意思就是,既然第一个扇区只能记录四组,那么我是否可以利用其它的扇区来记录更多的分区。

扩展分区并不是一个区块,而是会分布在每个分区的最前面的几个扇区来记录分区信息。扩展分区的目的是使用额外的分区来记录分区的信息,扩展分区本身不能被拿来格式化。

扩展分区可以继续划分为逻辑分区,逻辑分区的设备名称号码是从五开始,前面的四个号码都是保留给主要分区和扩展分区的。

扩展分区只能有一个,扩展分区本身不能被格式化,但是划分出来的逻辑分区与主要分区一样能够被格式化。逻辑分区的数量依照操作系统而不同,在Linux当中,SATA硬盘已经可以突破63个以上的分区限制。

如果扩展分区被破坏了,那么所有的逻辑分区都会被删除,因为逻辑分区的信息都记录在扩展分区中。

在过去的MBR分区表当中,有一些限制,例如,操作系统无法使用2.2TB以上的磁盘容量。MBR仅有一个区块,如果被破坏后,经常无法或者很难恢复。MBR内存放启动引导程序的区块仅有446字节,无法存储较多的程序代码。

GPT(GUID partition table)分区表

GPT将磁盘所有的区块以LBA(默认为512字节)来规划,第一个LBA称为LBA0。

与MBR仅适用第一个512字节区块来记录不同,GPT使用了34个LBA区块来记录分区信息。同时与过去MBR一个区块出问题,其余无法使用的情况不同。GPT除了前面34个LBA之外,整个磁盘的最后 33 个LBA也拿来做一个备份,这样会比较安全一些。

3 - 磁盘分区

LBA0(MBR兼容区块)

与MBR模式相似,这个兼容区块也被分为两个部分,一个就是与之间446字节相似的区块,存储了第一阶段的启动引导程序,而在原本的分区表的记录区内,这个兼容模式仅仅放入了一个特殊标识符,用来表示此磁盘是GPT格式。如果是不认识GPT分区表的磁盘管理器,除非用户有特别要求,则无权修改这块磁盘,进一步对磁盘进行了保护。

LBA1(GPT表头记录)

这个部分记录了分区表本身的位置和大小,同时记录了备份用的GPT分区放置的位置,同时放置了分区表的校验码,操作系统可以根据这个校验码来判断GPT是否正确。如果有错误,还可以通过这个记录区获取备份的GPT(磁盘最后的那个备份区块)来恢复GPT的运行。

LBA2 - 33(实际记录分区信息处)

从LBA2区块开始,每个LBA都可以记录4组分区记录,所以在默认的情况下,总共可以有4x32=128组分区记录。因为每个LBA有512字节,因此每组记录用到128字节的空间,除了每组记录所需要的标识符与相关的记录之外,GPT在每组记录当中分别提供了64位来记载开始/结束的扇区号码。

因此,GPT分区表对于单一分区而言,它的最大容量就会在【3 - 磁盘分区】,1ZB=3 - 磁盘分区

现在GPT分区默认可以提供多达128组记录,而在Linux本身的内核设备记录当中,针对单一磁盘而言,虽然过去最多只能达到15个分区,不过由于Linux内核通过udev等方式的处理,现在Linux现在已经没有这个限制了。此外,GPT分区没有所谓的主、扩展、逻辑分区的概念,既然每组记录都可以独立存在,当然每个都可以视作主要分区,每一个分区都可以拿来格式化使用。

 

为什么要分区?

数据的安全性

每个分区的数据是分开的。所以,当你需要将某个分区的数据重新整理时,可以将其他的重要数据移动到其他分区。所以善用分区,能够让你的数据更加安全。

系统的性能考虑

由于分区将数据集中在某个柱面区段,而MBR分区表中,假设第一个分区是1~100号,那么如果有数据要读取自该分区,磁盘就只会查找1~100的柱面范围。数据的集中助于数据读取的速度和性能。

 

启动流程中的BIOS与UEFI启动检测程序

CMOS是记录各项硬件参数并且嵌入在主板上面的存储器,BIOS则是一个写入主板的一个固件。这个BIOS就是在启动的时候,计算机会主动执行的第一个程序。

BIOS搭配MBR/GPT的启动流程

以硬盘为例,BIOS会依据用户的设置去获取能够启动的硬盘,并且到该硬盘里面去读取第一个扇区的MBR位置。MBR这个仅有446字节的硬盘容量里面会放置最基本的启动引导程序。此时BIOS就功成圆满,接下来就是MBR的任务了。

这个启动引导程序的目的是加载内核文件。由于启动引导程序是操作系统在安装的时候提供的,所以它会认识硬盘内的文件系统格式,因此就能读取内核文件。接下来就是内核文件的工作,启动引导程序也功成圆满,将之后的工作交接给操作系统。

简单的说,整个启动流程到操作系统之前的过程应该是这样的。

1)BIOS:启动主动执行的固件,会认识第一个可以启动的设备。

2)MBR:第一个可启动的设备的第一个扇区内的主引导程序,内含启动引导代码。

3)启动引导程序(Boot loader):一个可读取内核文件来执行的软件。

4)内核系统:开始启动操作系统。

需要注意,如果分区表为GPT格式,那么BIOS也能够从GPT的兼容区块读取第一阶段的启动引导程序代码。如果启动引导程序支持GPT,那么BIOS同样可以读取到正确的操作系统内核。换句话说,如果启动引导程序不懂GPT,那么自然就无法读取操作系统内核,就无法启动操作系统。

BIOS与MBR都是硬件本身会支持的功能,至于Boot loader则是操作系统安装在MBR上面的一个软件,由于MBR仅有446字节而已,因此这个启动引导程序是非常小而高效的。

Boot loader的主要任务

1)提供选项:用户可以选择不同的启动项,这也是多重引导的重要功能。

2)加载内核文件:直接指向可以使用的程序区段来启动操作系统。

3)转交其他启动引导程序:将启动管理功能转交给其他启动引导程序负责。

启动引导程序出了可以安装在MBR之外,还可以安装在每个分区的启动扇区。假设你的个人计算机只有一个硬盘,里面分为四个区,其中一、二分区分别安装了Windows和Linux。那么你如何在开机的时候选择使用Windows还是Linux启动?

假设MBR内安装的是可以同时认识Windows和Linux操作系统的启动引导程序,那么MBR的启动引导程序会提供两个选项,选项一可以直接加载Windows的内核文件来开机;选项二则是将开机管理工作交给第二个分区的启动扇区。当第二个启动引导程序启动后,该启动引导程序中仅有一个启动选项,因此就能够使用Linux的内核文件来启动。这就是多重引导

启动引导程序可以直接指向或者间接将管理权转交给另一个管理程序,启动引导程序只会认识自己的系统分区内的可以启动的内核文件以及其他启动引导程序而已。

实际上可启动的内核文件是被放置到各个分区的,每个分区都拥有自己的启动扇区。

如果要安装多重引导,那么最好先安装Windows再安装Linux。

Linux在安装的时候,你可以选择将启动引导程序安装在MBR或者其他分区的启动山区,而且Linux的启动引导程序可以手动设置选项,所以你可以在Linux的启动引导程序当中加入Windows启动的选项。

Windows在安装的时候,它的安装程序会自动覆盖MBR以及自己所在分区的启动扇区,你没有选择的机会,而且它没有让我们设置的功能。

因此,如果先安装Linux再安装Windows,那MBR的启动引导程序就只会有Windows的选项,而不会有Linux的选项。

UEFI BIOS搭配GPT启动的流程

我们现在知道GPT可以提供64位的寻址,然后也能够使用较大的区块来处理启动引导程序,但是BIOS其实并不认识GPT,还是要通过GPT的兼容模式才能够读写这个磁盘设备。而且BIOS只是16位的程序,与现阶段新的操作中系统接轨方面有些点弱。为了解决这个问题,因此就有了UEFI这个统一可扩展固件接口的产生。

UEFI主要是想要取代BIOS这个固件接口,因此我们也可以成为UEFI BIOS。UEFI使用C语言编写,比起使用汇编语言的传统BIOS要更加容易开发。也是因为使用C语言编写,因此如果开发者足够厉害,甚至可以在UEFI阶段就让该系统连接上网络,根本不需要进入操作系统。

比较项目 传统BIOS UEFI
使用程序语言 汇编语言 C语言
硬件资源控制

使用中断(IRQ)管理

不可变的内存存取

不可变的输入/输出存取

使用驱动程序与协议
处理器运行环境 16位 CPU保护模式
扩充方式 通过IRQ连接 直接加载驱动程序
第三方厂商支持 较差 较佳并且可支持多平台
图形能力 较差 较佳
内置简化操作系统环境 不支持 支持

从上面我们可以发现,UEFI简直就像一个低级的操作系统,甚至于连主板上面的硬件资源管理都与操作系统类似。只需要加载驱动程序即可控制操作。同时由于其功能特性,一般来说,使用UEFI的主机,在开机的速度也要比BIOS快上很多。

UEFI当初在开发时,制定了一些规则在里面,包括硬件资源使用轮询(Polling)的方式来管理,与BIOS直接使用CPU中断的方式来管理相比较,轮询的效率稍微低了一些。另外,UEFI并不能提供完整的缓存功能,因此执行效率也没有办法提升。

不过由于加载所有的UEFI驱动程序之后,系统还会启动一个类似于操作系统的shell环境,用户可以在此环境中执行任意的UEFI应用程序,而且效果比MS-DOS好。

所以,因为效果华丽但是性能不佳,这个UEFI大多用来实现启动操作系统之前的硬件检测、启动管理、软件设置等目的,基本上是比较难的。同时,当加载操作系统后,一般来说,UEFI就会停止工作,并将系统交给操作系统,这与早期的BIOS差异不大。特别的是,在某些特定的环境下,UEFI程序是可以部分继续执行的,从而在某些操作系统无法找到特定设备时,该设备还可以持续运行。

此外,由于过去骇客经常借由BIOS启动阶段来破坏系统,并取得系统的控制权,因此UEFI加入了一个所谓的安全启动功能,这个功能代表着即将启动的操作系统必须要被UEFI所验证,否则就无法顺利启动。微软用了很多这样的方式来管理硬件。

不过加入这个功能后,许多的操作系统,包括Linux,就很有可能无法顺利启动。所以,某些时刻,你可能需要将UEFI的secure boot功能关闭,才能顺利的进入Linux。

另外,与BIOS模式相比较,虽然UEFI可以直接过去GPT的分区表,不过最好依旧拥有BIOS的分区支持,同时,为了与Windows兼容,并且提供其他第三方厂商所使用的UEFI应用程序存储的空间,则必须要格式化一个FAT格式的文件系统分区,大约提供512MB到1GB的大小,让其他的UEFI执行比较方便。

由于UEFI已经解决了BIOS的1024柱面问题,因此你的启动引导程序与内核可以放置在磁盘开始前的2TB位置。加上之前提到的BIOS boot以及UEFI支持的分区,基本上你的/boot目录几乎都是/dev/sda3之后的号码。

 

Linux磁盘分区的选择

目录树结构(directory tree)

整个Linux系统最重要的的地方就是在目录树结构。所谓的目录树结构就是以根目录为主,然后向下呈现为分支状的目录结构的一种文件架构。

所以,整个目录树架构最重要的的就是那个根目录,这个根目录的表现方式是一条斜线“/”,所有的文件都与目录树有关。所有的文件都是由根目录(/)衍生而来的,而子目录下还能够有其他的数据存在。

文件系统与目录树的关系(挂载)

所谓的“挂载”就是利用一个目录当成进入点,将磁盘分区的数据放置在该目录下;也就是说进入该目录就可以读取该分区的意思。这个操作,我们称为“挂载”,那个进入点的目录,我们称为“挂载点”。

由于整个Linux系统最重要的的是根目录,因此根目录一定要挂载到某个分区,至于其他的目录则可以按照自己的需求挂载到不同的分区。

Windows也用的是挂载概念。判断某个文件在哪个分区之下是很简单的,通过反向追踪即可。看哪个“进入点”先被查到那就是使用的进入点。

/home/vbird/test  : test使用的是/home这个进入点而不是/。