操作系统的系统软件产生,是为了计算机所有硬件系统的资源合理分配。操作系统会控制所有的硬件并且提供核心功能,因此我们的计算机就能够认识硬盘内的文件系统,并且进一步的读取硬盘内的软件文件与执行该软件来达成各项软件的执行目的。
基本上,目前的主机系统在载入硬件驱动方面的程序,主要有早期的 BIOS 与新的 UEFI 两种机制。
BIOS 搭配 MBR/GPT 的开机流程
CMOS是记录各项硬件参数且嵌入在主板上面的储存器,BIOS则是一个写入到主板上的一个固件(再次说明, 固件就是写入到硬件上的一个软件程序)。这个BIOS就是在开机的时候,计算机系统会主动执行的第一个程序。
接下来BIOS会去分析计算机里面有哪些储存设备,我们以硬盘为例,BIOS会依据使用者的设置去取得能够开机的硬盘, 并且到该硬盘里面去读取第一个扇区的MBR位置。 MBR这个仅有446 Bytes的硬盘容量里面会放置最基本的开机管理程序, 此时BIOS就功成圆满,而接下来就是MBR内的开机管理程序的工作了。
这个开机管理程序的目的是在载入(load)核心文件, 由于开机管理程序是操作系统在安装的时候所提供的,所以他会认识硬盘内的文件系统格式,因此就能够读取核心文件, 然后接下来就是核心文件的工作,开机管理程序与 BIOS 也功成圆满,将之后的工作就交给操作系统。
整个开机流程到操作系统的动作是:
1. BIOS:开机主动执行的固件,会认识第一个可开机的设备;
2. MBR:第一个可开机设备的第一个扇区内的主要开机记录区块,内含开机管理程序;
3. 开机管理程序(boot loader):一支可读取核心文件来执行的软件;
4. 核心文件:开始操作系统的功能。
第二点要注意,如果你的分区表为 GPT 格式的话,那么 BIOS 也能够从 LBA0 的 MBR 相容区块读取第一阶段的开机管理程序码, 如果你的开机管理程序能够认识 GPT 的话,那么使用BIOS 同样可以读取到正确的操作系统核心喔!换句话说, 如果开机管理程序不懂 GPT ,例如 Windows XP 的环境,那自然就无法读取核心文件,开机就失败了。
Tips:由于 LBA0 仅提供第一阶段的开机管理程序码,因此如果你使用类似 grub 的开机管理程序的话,那么就得要额外分区出一个“ BIOS boot ”的分区, 这个分区才能够放置其他开机过程所需的程序码!在 CentOS 当中,这个分区通常占用 2MB 左右而已。
由上面的说明我们会知道,BIOS与MBR都是硬件本身会支持的功能,至于Boot loader则是操作系统安装在MBR上面的一套软件了。由于MBR仅有446 Bytes而已,因此这个开机管理程序是非常小而美的。 这个boot loader的主要任务有下面这些项目:
提供菜单:使用者可以选择不同的开机项目,这也是多重开机的重要功能!
载入核心文件:直接指向可开机的程序区段来开始操作系统;
转交其他loader:将开机管理功能转交给其他loader负责。
举个例子,如果个人计算机只有一个硬盘,里面切成四个分区,其中第一、二分区分别安装了Windows及Linux,你要如何在开机的时候选择用Windows还是Linux开机呢?假设MBR内安装的是可同时认识Windows/Linux操作系统的开机管理程序,那么整个流程可以图示如下:
图2.2.8、开机管理程序的工作执行示意图
在上图中我们可以发现,MBR的开机管理程序提供两个菜单,菜单一(M1)可以直接载入Windows的核心文件来开机; 菜单二(M2)则是将开机管理工作交给第二个分区的开机扇区(boot sector)。当使用者在开机的时候选择菜单二时, 那么整个开机管理工作就会交给第二分区的开机管理程序了。 当第二个开机管理程序启动后,该开机管理程序内(上图中)仅有一个开机菜单,因此就能够使用Linux的核心文件来开机啰。 这就是多重开机的工作情况啦!我们将上图作个总结:
每个分区都拥有自己的开机扇区(boot sector)
图中的系统盘为第一及第二分区,
实际可开机的核心文件是放置到各分区内的!
loader只会认识自己的系统盘内的可开机核心文件,以及其他loader而已;
loader可直接指向或者是间接将管理权转交给另一个管理程序。
先安装Windows再安装Linux是因为:
1.Linux在安装的时候,你可以选择将开机管理程序安装在MBR或各别分区的开机扇区, 而且Linux的loader可以手动设置菜单(就是上图的M1, M2...),所以你可以在Linux的bootloader里面加入Windows开机的选项;
2.Windows在安装的时候,他的安装程序会主动的覆盖掉MBR以及自己所在分区的开机扇区,你没有选择的机会, 而且他没有让我们自己选择菜单的功能。
因此,如果先安装Linux再安装Windows的话,那MBR的开机管理程序就只会有Windows的项目,而不会有Linux的项目 (因为原本在MBR内的Linux的开机管理程序就会被覆盖掉)。 那需要重新安装Linux一次吗?当然不需要,你只要用尽各种方法来处理MBR的内容即可。 例如利用Linux的救援模式来挽救MBR。
UEFI BIOS 搭配 GPT 开机的流程
GPT可以提供到64bit的寻址,也可以使用较大的区块来处理开机管理程序。但是BIOS不懂GPT,还是需要通过GPT提供相容模式才能够读写这个磁盘设备,为了解决这个问题,就有了UEFI,这个统一可延伸固件界面的产生。
UEFI 主要是想要取代 BIOS 这个固件界面,因此我们也称 UEFI 为 UEFI BIOS 就是了。UEFI 使用 C 程序语言,比起使用组合语言的传统 BIOS 要更容易开发!也因为使用 C 语言来撰写,因此如果开发者够厉害,甚至可以在 UEFI 开机阶段就让该系统了解 TCP/IP 而直接上网,根本不需要进入操作系统。
基本上,传统 BIOS 与 UEFI 的差异可以用T客帮杂志汇整的表格来说明:
比较项目 | 传统BIOS | UEFI |
使用程序语言 | 组合语言 | C语言 |
硬件资源控制 | 使用中断(IRQ)管理不可变的内存存取不可变的输入、输出存取 | 使用驱动程序与协定 |
处理器运行环境 | 16位 | CPU保护模式 |
扩充方式 | 通过IRQ链接 | 直接载入驱动程序 |
第三方厂商支持 | 较差 | 较佳且可支持多平台 |
图形化能力 | 较差 | 较佳 |
内置简化操作系统前环境 | 不支持 | 支持 |
从上头我们可以发现,与传统的 BIOS 不同,UEFI 简直就像是一个低阶的操作系统~甚至于连主板上面的硬件资源的管理, 也跟操作系统相当类似,只需要载入驱动程序即可控制操作。同时由于程控得宜,一般来说,使用 UEFI 接口的主机,在开机的速度上要比 BIOS 来的快上许多。
UEFI 当初在发展的时候,就制定一些控制在里头,包括硬件资源的管理使用轮询 (polling)的方式来管理,与 BIOS 直接了解 CPU 以中断的方式来管理比较, 这种 polling 的效率是稍微慢一些的,另外,UEFI 并不能提供完整的高速缓存功能,因此执行效率也没有办法提升。不过由于载入所有的 UEFI 驱动程序之后, 系统会打开一个类似操作系统的 shell 环境,使用者可以此环境中执行任意的 UEFI 应用程序,而且效果比MSDOS 更好。
UEFI 大多用来作为启动操作系统之前的硬件检测、开机管理、软件设置等目的,基本上是比较难的。 同时,当载入操作系统后,一般来说,UEFI 就会停止工作,并将系统交给操作系统,这与早期的 BIOS 差异不大。比较特别的是,某些特定的环境下, 这些 UEFI 程序是可以部份继续执行的,以协助某些操作系统无法找到特定设备时,该设备还是可以持续运行。
此外,由于过去 cracker 经常借由 BIOS 开机阶段来破坏系统,并取得系统的控制权,因此UEFI 加入了一个所谓的安全启动 (secure boot) 机制, 这个机制代表着即将开机的操作系统必须要被 UEFI 所验证,否则就无法顺利开机!微软用了很多这样的机制来管理硬件。不过加入这个机制后,许多的操作系统,包括 Linux ,就很有可能无法顺利开机。所以,某些时刻,你可能得要将 UEFI 的 secure boot 功能关闭,才能够顺利的进入 Linux。
另外,与 BIOS 模式相比,虽然 UEFI 可以直接取得 GPT 的分区表,不过最好依旧拥有BIOS boot 的分区支持,同时,为了与 windows 相容,并且提供其他第三方厂商所使用的UEFI 应用程序储存的空间,你必须要格式化一个 vfat 的文件系统,大约提供 512MB 到 1G左右的容量,以让其他 UEFI 执行较为方便。
Tips :由于 UEFI 已经克服了 BIOS 的 1024 柱面的问题,因此你的开机管理程序与核心可以放置在磁盘开始的前 2TB 位置内即可。加上之前提到的 BIOS boot 以及 UEFI 支持的分区,基本上你的 /boot 目录几乎都是 /dev/sda3 之后的号码了。这样开机没有问题。所以要注意,与以前熟悉的分区状况已经不同, /boot 不再是 /dev/sda1。