我正在尝试理解“启动过程”(不一定是 Linux),如果有人能根据我的一些经验证实我目前的理解,我会很高兴。
BIOS-MBR
据我所知,BIOS 机器上的启动过程如下:BIOS 是一种固件,它使用非易失性存储器来存储计算机启动时尝试从中启动的磁盘顺序。然后它将转到第一个,如果它找到有效的 MBR 代码,它将控制权传递给该代码。然后,MBR 代码将执行加载操作系统的工作。对于 GRUB,阶段 1(boot.img
)将位于 MBR 中,将控制权传递给阶段 2(core.img
将位于 MBR 和第一个分区之间的空白处),后者将定位并加载内核,并将控制权传递给内核。
在 GPT 分区磁盘上,core.img
将位于它自己的分区上。
UEFI - GPT
UEFI 的工作方式不同。它不依赖于磁盘的第一个扇区。相反,在 UEFI 系统中,引导加载程序将采用.efi
文件的形式,放置在 EFI 系统分区中。因此,Windows 将.efi
在此分区中拥有自己的文件,Linux 也将拥有自己的文件。UEFI
固件足够智能,可以理解 FAT 文件系统,因此它可以通过路径名找到这些 efi 文件,而这些引导加载程序将加载适当的内核。
我的经历是这样的:我有一台全新的 PC,上面装有 Windows 10。现在我想在 USB 上安装 Ubuntu 20,这样无论何时我都可以插入 USB 并启动 Ubuntu 而不是 Windows(我只是不想让它占用我的硬盘空间)。使用本指南。当我插入 USB 时,我进入了 GRUB 菜单,让我选择要启动的操作系统。太棒了。当我打开 PC 时没有插入 USB 后,我进入了 GRUB 救援 shell,输入后exit
计算机启动了 Windows。然后我注意到在我的 ESP(驱动器中)中有一个名为 的目录ubuntu
,GRUB 就在那里。
我的 UEFI 按以下顺序配置:
- USB闪存盘
- Ubuntu
- 视窗
因此,尝试根据上述理论来理解这种现象,会发生以下情况:UEFI 固件有其启动目标的顺序(与 BIOS 非常相似),在我的例子中,Ubuntu 在 Windows 之前。UEFI 以某种方式知道这个 Ubuntu 位于 USB 驱动器上,因此当 USB 未连接时,它会提示救援 shell。对吗?
我对这一切有以下疑问:
- GRUB 提供的菜单 - 这是引导程序的一部分吗?如果是,为什么即使 USB 断开连接它也不会显示?只有在我选择后它才应该意识到它已断开连接
ubuntu
- 当我第一次插入
Live CD
安装 ubuntu 时。那个 Live CD 是用 MBR 引导加载程序代码格式化的,对吗?EFI 如何处理它?你能在旧的 BIOS/MBR 方案中使用 EFI 正常启动吗?(即使你的 EFI 没有这样配置,我知道有一种方法可以这样配置它)。
如果有人能证实我对这一切的理解/误解,那就太好了。
编辑 这是输出:
/boot/efi/EFI/ubuntu$ efibootmgr -v
BootCurrent: 0001
Timeout: 0 seconds
BootOrder: 0019,0001,0000,0015,0016,0017,0018,001A,001B,001C,001D
Boot0000* Windows Boot Manager HD(1,GPT,d37539b4-7745-44f3-83b4-59b5ff5dc08f,0x800,0x82000)/File(\EFI\Microsoft\Boot\bootmgfw.efi)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}...e................
Boot0001* ubuntu HD(1,GPT,d37539b4-7745-44f3-83b4-59b5ff5dc08f,0x800,0x82000)/File(\EFI\ubuntu\shimx64.efi)
Boot0010 Setup FvFile(721c8b66-426c-4e86-8e99-3457c46ab0b9)
Boot0011 Boot Menu FvFile(86488440-41bb-42c7-93ac-450fbf7766bf)
Boot0012 Regulatory Information FvFile(e4a83242-deee-f12e-15ff-0102036cc3ce)
Boot0013 Diagnostic Splash FvFile(a7d8d9a6-6ab0-4aeb-ad9d-163e59a7a380)
Boot0014 OilDiagApp FvFile(f8397897-e203-4a62-b977-9e7e5d94d91b)
Boot0015* NVMe: SAMSUNG MZALQ512HALU-000L2 PciRoot(0x0)/Pci(0x1d,0x4)/Pci(0x0,0x0)/NVMe(0x1,00-25-38-A4-01-B7-FE-7B)....2.LN........
Boot0016* MSATA Hard Drive: VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f602)
Boot0017* ATA HDD: VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f601)
Boot0018* ATAPI CD: VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a354)
Boot0019* USB Device: SanDisk Cruzer Snap PciRoot(0x0)/Pci(0x14,0x0)/USB(3,0)3.!..3.G..A.....
Boot001A* PXE Network Boot: EFI Network (IPv4) PciRoot(0x0)/Pci(0x1d,0x0)/Pci(0x0,0x0)/MAC(b4a9fca62a74,0)/IPv4(0.0.0.00.0.0.0,0,0)x.J.+*.N.....=8.
Boot001B* USB CD: VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,86701296aa5a7848b66cd49dd3ba6a55)
答案1
好的,我想我对整个过程有了更好的理解:
UEFI 固件有一个 NVRAM 变量,即“BootOrder”,它定义了目标启动目标。有多种类型的启动目标。例如:
Boot0001* ubuntu HD(1,GPT,d37539b4-7745-44f3-83b4-59b5ff5dc08f,0x800,0x82000)/File(\EFI\ubuntu\shimx64.efi)
此目标指定了设备路径、分区和引导加载程序的文件路径。在本例中,它指向我内部驱动器上的 ESP 上的 grub。
另一种类型是后备路径:
Boot0001* Hard Drive HD(2,0,00)
此目标显示“从此磁盘启动” - 但没有更多信息。在这种情况下,UEFI 将执行的操作是找到 ESP(它将找到的第一个 ESP),然后启动该/EFI/BOOT/BOOTX64.EFI
文件。
一旦安装了操作系统,它就会创建一个 ESP(如果不存在)并在其中安装自己的引导加载程序。然后它在 EFI 引导管理器中添加一个条目,指向它刚刚安装的引导加载程序。
在我的情况下发生的情况如下:Linux Ubiquity 在我的内置硬盘上安装了一个引导加载程序 (efi grub),并如上所述在 UEFI 引导管理器中创建了一个条目。问题是,grub 使用grub.cfg
位于 USB (/boot/grub) 上的配置文件。因此就 UEFI 而言,它确实找到了引导加载程序并将控制权交给了它,因此它没有继续执行下一个目标。但 grub 本身失败了,因为它找不到位于 USB 上的配置文件。
对此的一个合理解决方案是在 USB 上创建一个 ESP,用于efibootmgr
指向ubuntu
从那里启动的条目,因此当拔下 USB 时,它自然会上网并启动 Windows。当插入它时,它将像我梦想的那样启动 Ubuntu :)
感谢:
@oldfred
UEFI 启动:那么它究竟是如何工作的呢?
EFI 系统分区和默认启动行为