admin管理员组

文章数量:1550528

1 前言

本文大概会来帮助大家解惑关于磁盘分区和开机启动的一些知识,会包括目前磁盘分区的格式,分区格式对应的系统启动流程。

2 关于磁盘

相信磁盘对于大家来说都不陌生,磁盘也是广为应用的保存大量数据的存储设备,存储的数量级可以达到M级,G级,甚至是T级别。

  • 传统的磁盘也被称做机械硬盘,需要驱动马达传动磁盘,磁盘由盘片(platter)组成,如图中最左边是盘片的结构,图的右边是多个盘片视图,中间由主轴(spindle)串联多个盘片,盘片的上面和下面都可以存放数据,比较关键的是,盘片表面由磁道(tracks)组成,每个磁道会划分为很多个扇区(sector),那么数据就是存放在扇区里,一般来说每个扇区的大小为存放512字节。每个盘片相同磁道的集合成为柱面(cylinder),寻址的时候需要驱动磁盘转动,通过一个叫做读/写头的固件在磁盘表面进行数据访问。

  • 目前我们有了固态硬盘,是基于闪存的存储技术,目标也是要替代传统的旋转磁盘,传统旋转磁盘需要转动寻址,速度相对来说比较慢,固态硬盘抽象出来的图如下,闪存翻译层充当了磁盘控制器的角色,真正的磁盘结构是下边,由多块(block)组成,每块由多页(page)组成。通常页的大小为512B~4KB,块的大小为16K~512K

3 为什么要分区

上边我们讲了磁盘的内部结构,不过我们仍然可以将磁盘想象为一块连续的存放数据的介质,不过当我们知道了磁盘内部原理,我们处理问题的时候能更好的给出解决方案,且也能很快理解一些原理。不多废话,那么我们为什么要分区呢?

  • 第一个也是必须的,如果你电脑安装多个操作系统,那分区是肯定的,避免多个操作系统打架

  • 也是为了更好的管理数据,不同类型的数据依靠不同分区,这样方便以后的使用和扩充等等

  • 提高寻址效率,之前的机械硬盘中,因为需要传动磁盘转动等,访问固定分区还可以减少磁盘传动和寻址

  • 操作系统单独成盘,避免重装系统时不必要的文件丢失

4 分区格式

目前磁盘分区格式大概分为MBR个GPT两种。

MBR(Master Boot Record)

MBR将开机管理程序记录区与分区表放到第一个扇区,这个扇区通常大小是512字节,开机管理程序用作开机使用,分区表则是记录了这块磁盘的分区详情。

  • 开机管理程序占用446字节

  • 分区表占用64字节 这样看来分区表只有64字节,最多只能记录四条记录,每条记录该分区的起始和结束柱面(cylinder),也就是说MBR分区的最小单位是柱面。如图所示:

那么大家可能会想是不是磁盘分区只能是分四个分区,其实也不是了,磁盘可以分很多个分区的,那么如何达到呢?
是通过叫做扩展(Extended)分区来实现,MBR的分区表记录的是主(Primary)分区扩展(Extended)分区,主分区就是我们上边所说的记录分区的开始和结束柱面。通过扩展分区达到使用其他扇区来记录分区的形式,每个分区会由一块空间来存放分区表,这里的其他扇区又被称作逻辑扇区如图所示: MBR分区表有一些限制:

  • 操作系统无法抓取到 2.2T 以上的磁盘容量

  • MBR 仅有一个区块,若被破坏后,经常无法或很难救援

  • MBR 内的存放开机管理程序的区块仅446bytes,无法容纳较多的程序代码

GPT(GUID partition table)

过去一个扇区大小就是 512bytes 而已,不过目前已经有4K的扇区(例如固态硬盘)设计出现,为了兼容所有磁盘,使用LBA(Logical Block Address),每个LBA预设是512字节,GPT使用了34个LBA区块来纪录分区信息,GPT除了前面34个LBA 之外,整个磁盘的最后33个LBA也拿来作为另一个备份

  • LBA0,兼容MBR格式,存储了开机管理程序和分区表,除此之外放入了标志位来标识这个是GPT分区。

  • LBA1,这个部份纪录了分区表本身的位置与大小,同时纪录了备份用的GPT分区(就是前面谈到的在最后34个LBA 区块) 放置的位置,同时放置了分区表的检验机制码

  • 从 LBA2区块开始,每个LBA都可以纪录4笔分区纪录,所以在默认的情况下,总共可以有 4*32 = 128笔分区记录,因为每个LBA有512bytes,因此每笔纪录用到128bytes 的空间,除了每笔纪录所需要的标识符与相关的纪录之外,GPT 在每笔纪录中分别提供了64bits 来记载开始/结束的扇区号码,这样说来GPT分区的最小单位就是扇区了,和MBR分配最小单位是柱面相比更加详细了。

5 开机流程

上边我们也说到了,特别是MBR中记录一段开机管理程序我们没有很详细的说到,只是谈论了关于分区表一些知识,这里我们来讲一下关于开机流程。
讲到开机流程,我们不得不明确与分区对应的两个概念,BIOS(Basic input output System )和UEFI(Unified Extensible Firmware Interface)。

5.1 BIOS

先来讲bios,基本输入输出系统,主要也是做一些检测初始化硬件,调用开机加载程序来开机,详细一点介绍这个流程吧。

  1. 按下开机键时,第一步就是去加载bios程序,那么如何加载,去哪里加载呢?BIOS其实是写在ROM里,大家也可以理解ROM是一块不会丢失的数据的存储介质。ROM的地址被映射成低端1M内存顶部即(0xF0000~0xFFFF),这里为什么说是1M呢,因为CPU最开始启动是运行在实模式下,那么实模式下内存空间就只有1M,感觉有点扯远~,而且这时cpu也是通过段地址+偏移来寻址,通电瞬间,CPU的cs:ip寄存器强制初始化为0xF000:0xFFF0,就会找到BIOS程序开始运行。

  2. BIOS运行硬件检测,及自检操作(Power On Self Test)

  3. BIOS会找到第一个扇区(MBR)的内容,并加载到内存,第一个扇区中由我们上文提到开机管理程序,将控制权限交由这个程序控制。

  4. 开机管理程序就会进行引导加载内核等等,这样操作系统就起来了

5.2 UEFI

UEFI的出现是为了替代BIOS的,首先UEFI可以理解就是一个小型的操作系统,是由C语言写成。BIOS其实也是不懂GPT,所以使用UEFI来替代。和BIOS比较,说几个突出的点,UEFI可以看懂磁盘分区、可以直接加载驱动程序、UEFI直接就运行在保护模式下。
UEFI的启动流程为: UEFI启动后也会做一些硬件检测,自检等操作,因为可以读懂磁盘分区,所以可以直接找到GPT中的boot loader(开机加载程序),然后加载内核,启动操作系统。

6 linux下的实例

上面说到关于开机启动,稍微有些抽象,我们就拿linux系统来详细说明关于MBR和GPT的开机启动。
linux中启动操作系统, 需要一个启动加载(boot loader)程序, 比较常用是grub,现在grub是version2。

6.1 BIOS && MBR

当使用BIOS开机,如果是MBR分区中,grub2充当了开机管理程序,即存放在第一个扇区中。因为MBR只有446字节,存放不下grub2的整个程序及相关文件,所以grub2分成两部分,boot.img和core.img,boot.img存放其MBR中,boot.img去启动core.img
core.img由于没有了大小的限制,会包含一些基本文件系统驱动(EXT,FAT,NTFS),这样grub2可以定位到/boot的文件系统,读取内容等。而grub2需要的一些文件,包括运行时内核模块,配置文件都是在/boot/grub2文件夹下,内核文件就在/boot/文件夹下,这样grub2就会去加载内核,进一步操作系统就可以启动。差点忘了一个重点,core.img是被存放在MBR与第一个分区(注意这里是分区而不是扇区)之间的。
我们借助这张图来充分理解下:

  • 首先第一个分区从2048扇区开始,0号扇区存放MBR,1~2047扇区如上边所说是留给core.img的。

  • 分区号1-4是留给主分区和扩展分区的,分区号5,6,7...是留给逻辑分区的,所以sdb1,sdb2,sdb5中间会有一个跳跃。

这也是MBR下系统的磁盘的结构:

6.2 BIOS && GPT

因为GPT中是兼容了MBR的(LBA0就是MBR),所以BIOS同样可以开机GPT分区的操作系统。
与BIOS->MBR类似,同样需要boot.img去启动core.img,boot.img同样放在第一个扇区,不一样的是core.img并不是放在第一个分区和mbr之间,而是有一个单独的分区BIOS BOOT(1M的内存空间),下图是我操作系统GPT分区: /dev/sda1就是BIOS boot分区,2048sectors*512bytes=1MB, 同样官方也给了一张图来说明启动的这个过程:

6.3 UEFI && GPT

最后我们来讲UEFI启动GPT分区,我们也已经展示了GPT分区表的图,那么如果使用UEFI是如何启动呢,这里肯定不是使用boot.img和core.img来启动。这里提供一张不兼容MBR启动的分区表的图: 由于没有了bios boot分区,所以就不再支持BIOS启动GPT分区了。这个分区表中比较特殊的一个分区是EFI system这个类型的分区,也被称作EFI System Partition(ESP)。

  1. UEFI可以读取这个分区

  2. 这个分区是VFAT格式的文件系统,UEFI还可以读取这个文件系统,这样就可以使用这个分区的内容了, ESP中包含一些UEFI可以执行的应用程序,以.EFI结尾,我们看下我本机系统

# aa64代表arch是aarch64
[root@localhost ~]# ls -l /boot/efi/EFI/*
/boot/efi/EFI/BOOT:
total 1424
-rwx------ 1 root root 846048 BOOTAA64.EFI 
-rwx------ 1 root root 304904 fallback.efi
-rwx------ 1 root root 304904 fbaa64.efi

/boot/efi/EFI/centos:
total 5090
-rwx------ 1 root root     184 BOOTAA64.CSV
drwx------ 2 root root    2048 fonts
-rwx------ 1 root root 1034000 grubaa64.efi
-rwx------ 1 root root    5780 grub.cfg
-rwx------ 1 root root    1024 grubenv
-rwx------ 1 root root  823720 mmaa64.efi
-rwx------ 1 root root  823720 MokManager.efi
-rwx------ 1 root root  846048 shimaa64.efi
-rwx------ 1 root root  846048 shimaa64-escore.efi
-rwx------ 1 root root  818456 shim.efi

这里就有bootloader(grub2)和一些启动时必须软件。centos系统提供的软件当然就是在centos文件夹下.

  1. centos下包含grubaa64.efi这个程序, 最终UEFI执行grubaa64.efi这个程序。这样就和之前步骤一样了,grub2会去加载内核,启动操作系统。如果会包含多个系统的EFI执行程序,比如还有一个redhat的文件夹,那么UEFI就会提示让你选择一个操作系统来启动。

6.4 为什么第一个分区是从2048开始

最后我们来给大家解惑一下,为什么第一个分区是从2048扇区开始,一个扇区是512字节,2048扇区就是1M。

  • MBR下,大都来说,core.img是25,389 Bytes,即使core.img加到0~2047扇区也用不了呀

  • GPT下,前LBA34都用来记录分区,也只是一个LBA是512字节,34个LBA就是17,408字节,也是用不了呀

    看起来很疑惑哈,其实选择2048作为第一个扇区的目的就是对齐。 过去最开始第一个分区是在63扇区,那就是有63*512=32,256字节,这样其实就可以放的下core.img或者说GPT的分区信息,而且看起来也比较节省空间。大家可能也会疑惑为什么我们都说一个扇区是512字节,固态硬盘可不一定是每页(或者扇区)是512字节哟,其实我们上边所说的512字节是一个逻辑扇区,大家也可以想像是磁盘(HDD&SSD)模拟出来每个扇区是512字节,但问题的关键点就是在这里,SSD的实际工作时每一页(扇区)可能是4096bytes,甚至8192bytes。这时候如果还是选择在63扇区建立第一个分区就会有新的问题了。 看到了吧,第一个分区是横跨了两页,那读写起来肯定时超级不方便了。
    所以为了避免这个情况,大家建议是在1M字节(2048扇区)那里作为边界:

7 总结

本文比较深入讲解了开机启动和磁盘分区,首先讲了磁盘结构及为什么分区,然后讲述磁盘分区的两种方式,再然后讲解如何开机及开机两种启动形式,最后在linux展示了下磁盘分区和开机启动实例。

8 ref

  • 《深入理解操作系统》

  • 《鸟哥的Linux私房菜-基础》

  • 《操作系统真相还原》

  • https://en.wikipedia/wiki/GNU_GRUB

  • https://www.thomas-krenn/en/wiki/Partition_Alignment_detailed_explanation

  • https://opensource/article/17/2/linux-boot-and-startup

  • https://access.redhat/documentation/en-us/red_hat_enterprise_linux/6/html/installation_guide/s2-grub-whatis-booting-uefi

  • https://en.wikipedia/wiki/Unified_Extensible_Firmware_Interface

本文标签: 磁盘分区