AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 532422
Accepted
quixotrykd
quixotrykd
Asked: 2019-07-28 00:37:31 +0800 CST2019-07-28 00:37:31 +0800 CST 2019-07-28 00:37:31 +0800 CST

BIOS 引导加载程序如何知道要使用哪个磁盘?

  • 772

据我了解,BIOS 系统上的 GRUB 引导加载程序(以及大多数其他引导加载程序)由 3 个部分组成。第一部分(阶段 1)存储在第一个448字节中,负责将控制传递给所谓的阶段 1.5,它位于内存中稍晚一点的位置。这个阶段最终从 /boot 文件夹加载阶段 2,并将控制权转移给它。

阶段 1 如何知道阶段 1.5 驻留在哪个磁盘上?一旦阶段 1 中的代码开始执行,它就无法知道它是从哪个磁盘加载的(除非此信息以某种方式传递到阶段 1 或者 BIOS 本身也将阶段 1.5 加载到内存中?)

同样,对于阶段 1.5 到阶段 2,阶段 1.5 如何知道 /boot 目录驻留在哪个磁盘(和哪个分区)上?

grub uefi
  • 2 2 个回答
  • 971 Views

2 个回答

  • Voted
  1. telcoM
    2019-07-28T02:08:50+08:002019-07-28T02:08:50+08:00

    第一部分(阶段 1)存储在前 448 个字节中,负责将控制权传递给所谓的阶段 1.5,它位于内存中稍晚一点的位置。这个阶段最终从 /boot 文件夹加载阶段 2,并将控制权转移给它。

    名称“stage1”、“stage1.5”和“stage2”属于 GRUB Legacy,即 GRUB 版本 0.xx。当阶段 1 写入 MBR(或 PBR)时,安装程​​序还将在其中写入下一阶段开始所在的实际磁盘块号。下一阶段的第一个块将包含更多程序代码,以及描述该阶段其余部分所在位置的块列表。阻止列表条目的形式为“从磁盘块 #Y 开始加载 X 块”。如果下一阶段作为连续(非分段)文件写入磁盘,则通常只需要一个阻止列表条目。

    stage1.5 实际上是可选的:完全有可能根本不安装 stage1.5,而只是让 stage1 直接加载 stage2。阶段 1.5 将包含足够的代码来理解单个文件系统类型;stage2 将包含所有受支持的文件系统驱动程序,这将使其更大。这样,stage1.5 可以嵌入到 MBR 和第一个分区开头之间的通常未使用的空间中。

    (现代 MBR 分区磁盘现在从第一个磁盘的开头正好 1 MiB 开始第一个分区,即在块 #2048,以允许大型存储系统的最佳数据对齐。这在 MBR 之间留下了更多未使用的空间并且第一个分区的开头比旧约定在 C/H/S 0/1/1 开始第一个分区。)

    stage1.5 和 stage2 都有一个预先分配的空间,供安装程序写入 GRUB 磁盘标识符和路径名。对于 stage1.5,这将标识实际 stage2 所在的分区和文件名;在 stage2 的情况下,它将识别 GRUB 配置文件的位置。

    与 BIOS 兼容的 GNU GRUB(即 GRUB 版本 1.xx 及更高版本)完全跳过 stage1.5,并使用不同的名称:

    • 过去stage1是现在boot.img
    • 过去stage2是现在core.img

    它boot.img仍然是嵌入到 MBR 中的 448 字节,但是core.img在 GRUB 安装时从kernel.img一组 GRUB 模块动态构建。

    我可以看到这些信息被硬编码到 1.5 阶段,但是这如何处理以不同顺序安装的驱动器(保证 (hd0) 和 (hd1) 将始终是同一个驱动器,所以硬编码类似的东西似乎是一个脆弱的策略。

    事实上的标准 BIOS 约定是,从 BIOS 中选择的任何磁盘作为要从其引导的磁盘都将被分配 ID 0x80 用于 BIOS 磁盘访问功能,并且该 ID 将直接映射到 GRUB (hd0)。(古老的 MS-DOS 同样总是将 BIOS 磁盘 ID 0x80 映射到驱动器C:。)

    幸运的是,BIOS 在枚举不同磁盘控制器的方式上通常非常确定。因此,只要硬件配置和 BIOS 设置保持不变,磁盘检测顺序就会从一次引导到下一次保持不变。

    但是,是的,这绝对是一个脆弱的策略。不幸的是,没有普遍的标准方法可以将 BIOS 的磁盘检测信息从 16 位 BIOS 例程传递到使用 32 位保护模式编程(甚至 64 位)的操作系统。因此,在从基于 BIOS 的引导加载程序切换到完整的 32 位或 64 位模式后,所有 32 位或更好的操作系统都将从头重新检测其磁盘。

    是的,BIOS 增强型磁盘驱动器服务(简称 EDD)包括一个 BIOS 扩展,可用于向受保护模式的操作系统报告 BIOS 磁盘检测的基本细节……但该扩展引入得相当晚,并且报告部分是可选的,因此它的可用性远不能保证。

    在具有多个磁盘控制器的基于 BIOS 的系统上,这基本上是一个令人头疼的问题。

    获胜的策略通常是在第一次遇到特定的硬件型号时彻底测试 BIOS 引导设置(可能会尝试多次安装操作系统),一旦找到好的配置,就将其写下来,不要碰 BIOS之后的启动设置。

    现代 GNU GRUB 包括search可用于通过标签、UUID 和/或特定文件的存在来选择磁盘分区的命令。在现代生成的grub-mkconfigGRUB 2.xx 配置文件中,固定标识符通常应该是最后的选择,仅在早期search命令失败时使用。

    GPT 分区表包括每个磁盘和分区的唯一 UUID 作为标准,UEFI NVRAM 变量实际上使用 ESP 的分区 UUID + ESP 分区内的引导加载程序的路径名指定引导加载程序的位置。这允许更健壮的配置。运行中的操作系统还有一个标准接口,可以从 UEFI 固件读取引导信息,并在需要时修改引导设置。

    • 3
  2. Best Answer
    Janka
    2019-07-28T01:14:40+08:002019-07-28T01:14:40+08:00

    如果您查看 GRUB 的来源,可在此处找到,您会发现 stage1 实际上定义在grub/grub-core/boot/i386/pc/boot.S.

    如果已配置,它可以执行软盘引导。它确实从配置的硬盘启动,并且它需要知道它必须从哪个 C/H/S 加载 stage1.5。它唯一的自动功能是确定从哪个驱动器加载引导扇区,如果没有另外配置的话。在将控制权传递给 stage1 之前,功能性 BIOS 会将该值加载到 DL 中。有些不这样做,grub 会退回到第一个硬盘。

    stage1.5 已经能够理解分区和文件系统,因此它不再依赖 C/H/S 值。它加载的驱动器仍然与上面相同。

    • 2

相关问题

  • 从 BIOS/EFI 进行网络引导 (PXE)

  • 升级发行版会生成新的和不同的启动映像

  • Red Hat 7.4:如何将 kickstart 文件注入仅 UEFI 系统的 USB 介质?

  • /sys/firmware/efi/efivars/ 中的 efi 变量条目

  • GRUB - 不是双启动,为什么它仍然默认显示?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve