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 / 问题 / 542123
Accepted
Andreas
Andreas
Asked: 2019-09-17 14:46:24 +0800 CST2019-09-17 14:46:24 +0800 CST 2019-09-17 14:46:24 +0800 CST

Grub:只安装 MBR 部分,不安装引导目录?

  • 772

似乎我总是必须--boot-directory在使用grub-install.

如果我/boot的分区上已经有现有的 grub 文件怎么办?我不应该只需要安装 grub 的 MBR 部分并将其指向我现有的分区之一/boot/grub吗?我找不到这样的选择。

我已将 GPT 降级为 MBR 并删除了我的 BIOS 引导分区,这意味着如果我没有误解任何内容,我需要将 Grub 重新安装到我的 MBR。如果不这样做,我会留下一个 grub 救援提示,在执行ls. 我意识到在将 grub 重新安装到 MBR 后,我的菜单条目可能仍然无法工作,因为它们引用了类似的分区hd0,gpt5,但是有一个可用的提示就足够了,它可以让我更容易地确认我对 grub 的理解。

每当我想安装 grub 时,我是否必须写入 a --boot-directory,即使目录已经存在?

boot
  • 1 1 个回答
  • 1042 Views

1 个回答

  • Voted
  1. Best Answer
    telcoM
    2019-09-18T00:20:47+08:002019-09-18T00:20:47+08:00

    当 GRUB 从 MBR 引导时,它在引导过程开始时需要执行的遗留 BIOS 兼容性步骤的数量意味着实际在 MBR 中的代码只能加载一个磁盘块,其 LBA 编号已修补到 MBR安装时的代码。该块通常是GRUB 核心映像的第一个块。它包含加载更多块的代码,以及定义其余 GRUB 核心映像所在位置的块编号列表。

    在 MBR 分区的磁盘上,在 MBR 和第一个分区的开头之间通常有未使用的空间。对于 MS-DOS,最初的约定是在下一个磁盘磁道的开始处启动第一个分区,这通常意味着在第一个分区之前至少有 63 个磁盘块,包括 MBR。在现代系统上,第一个 MBR 分区现在更常见地放置在距磁盘开头正好 1MiB 的位置,即块 #2048,以优化可能在内部使用块的磁盘、SSD 和 SAN 存储系统的数据对齐大小大于 512 字节。

    因此,在 MBR 分区的磁盘上,磁盘的开头通常是这样排列的:

    • 块#0:MBR
    • 块 #1:GRUB 核心映像的第一个块,包含块列表
    • 块 #2...#n:GRUB 核心映像的其余部分
    • 块 #2048:第一个分区的开始。

    请注意,GRUB 核心映像的加载仅通过预先确定的块编号进行:在完全加载和提取 GRUB 核心映像之前,GRUB 将不知道分区表或任何类型的文件系统。

    在 GPT 分区磁盘上,块 #0 之后的块被 GPT 分区表占用,因此 GRUB 核心映像嵌入到“BIOS 引导分区”中。这只是意味着嵌入到 MBR 中的块编号不会是 1,而是 BIOS 引导分区的第一个块的编号,并且属于核心映像的其余块将同样移动。因此,在带有 BIOS 样式 GRUB 的 GPT 分区磁盘上,物理布局将是这样的,假设 BIOS 引导分区是磁盘上的第一个分区:

    • 块 #0:GPT 保护 MBR,嵌入了 GRUB MBR 代码
    • blocks #1...#(x-1):实际的 GPT 分区表
    • block #x:BIOS 引导分区的第一个块,包含 GRUB 核心映像的第一个块和块列表
    • 块 #(x+1)...#(x+n):GRUB 核心映像的其余部分

    您仍然可以进入 GRUB 救援模式的事实表明,尽管您说您删除了 BIOS 引导分区,但您还没有覆盖它的块;尽管 BIOS 引导分区占用的空间现在可能是分区之间的未分配空间,或者是另一个调整大小的分区中的未使用空间,但它仍然有它的旧内容,GRUB 仍然可以加载这些块并找到它的核心映像。但是现在没有什么特别能保护这些块不被覆盖:无论出于何种原因,一旦发生这种情况,GRUB 核心映像将被破坏,并且 GRUB 将无法到达救援模式。

    GRUB 核心映像的内容

    GRUB 核心映像包含以下内容:

    • GRUB 内核:这是进入 GRUB 救援模式在技术上唯一需要的部分。
    • 嵌入的初始 GRUB 根路径,以指示其中包含 GRUB 配置文件和 GRUB 模块目录的磁盘、分区和目录。在 Linux 中,这些通常在 Linux 系统正常运行时分别/boot/grub/grub.cfg出现。/boot/grub/i386-pc
    • 一组嵌入式 GRUB 模块,至少包含用于读取和理解分区表的代码以及在初始 GRUB 根路径引用的分区上使用的文件系统类型。由于核心映像可能需要放入少于 63 个磁盘块中,因此这组模块通常在 MBR 系统上保持尽可能少。
    • 可选地,带有一个或多个 GRUB 命令的嵌入式 GRUB 配置文件
    • 可选,嵌入式磁盘映像,类似于memdiskSYSLINUX 引导加载程序系列的工具使用的那些
    • 可选的,用于签署其他 GRUB 模块和操作系统内核的 GPG 公钥以确保安全(并满足对 GRUB 的 UEFI 版本的安全启动接受要求)

    所有这些都是 LZMA 压缩以最小化其大小,因此无法轻松读取或手动修改。

    由于您现在进入救援模式并且无法列出您的分区,这表明 GRUB 核心映像包含 GPT ( part_gpt.mod) 的分区模块,但不包含 MBR ( part_msdos.mod) 的分区模块。如果没有 MBR 分区模块,即使 GRUB 核心映像包含适用于它的文件系统驱动程序模块,它也无法访问包含/boot/grub/i386-pc目录的分区......因此 GRUB 无法加载normal.mod这将使您继续超越救援模式。

    现在需要做什么

    • 可能需要将 GRUB 核心映像重写到一个安全位置,可能是在 MBR 和第一个分区开头之间的空间中,该空间以前被 GPT 分区表的结构占用。由于 BIOS 引导分区已被删除,当前位置并不安全:它可能会被重新分配到另一个分区并在将来被覆盖而不会发出警告。
    • 在重写 GRUB 核心映像时,需要将其中嵌入的 GPT 分区模块替换为 MBR 分区模块。由于所有组件都应该以未压缩的形式(位于/usr/lib/grub/i386-pc或类似目录)在手边,因此最简单的方法是获取所有适当的未压缩组件,从中构建一个新的核心映像并对其进行压缩。解压旧代码并对其进行修改是不值得的麻烦:为什么在重用最初从头安装 GRUB 时使用的代码时编写另一段代码就可以了?
    • 由于 GRUB 核心映像的位置很可能会发生变化,因此也需要重写 MBR 代码。
    • 该grub-install命令需要以某种方式确保normal.mod位于其中的其他 GRUB 模块/boot/grub/i386-pc与新的 GRUB 核心映像具有相同的版本。当然,它可以将现有文件与用于重建核心映像的文件集进行比较,但是再次......为什么在简单地/boot/grub/i386-pc用已经存在的 GRUB 安装例程覆盖现有内容时为另一种特殊情况编写和调试代码工作得好吗?

    所有 GRUB 组件的总未压缩大小i386-pc肯定小于 4 MiB。没什么。如果它已经存在,试图避免重写根本不值得麻烦,除非你正在使用一些特殊的东西,比如旧的第一代 PATA SSD,可用的写入周期数非常有限。

    原生 UEFI 如何做到这一点?

    由于 UEFI 固件包括标准的 FAT32 文件系统支持,因此可以将本机 UEFI 版本的 GRUB 引导加载程序打包为grubx64.efi包含所有必要模块的单个文件,包括 normal.mod如果您愿意的话。它作为常规文件加载:根本不需要在固定磁盘位置摆弄块编号或嵌入代码。

    • 3

相关问题

  • 为什么 `journalctl --list-boots` 与 `uptime` 和 `who -b` 报告的不匹配?

  • 如何在启动时启动控制台程序(在 ../openbox/autostart 内)

  • 系统完好,grub坏了

  • “pacman -Syu”“可能”破坏了我的系统,因为未安装引导

  • 克隆的 SSD 无法启动并打印奇怪的线条

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