在複製磁碟映像後找出 GRUB / GRUB 的確切位置不工作
我用 VirtualBox 準備了一個 Ubuntu 伺服器映像。要將映像傳輸到伺服器的 SSD,我首先
dd
編輯了 MBR(512 字節),然後是 LVM 分區(包含根分區的 PV 縮小到 3GB)。伺服器無法引導,因為缺少 GRUB 的某些部分。grub 救援提示出現了。正如我從 GRUB 的文件中了解到的,這是有道理的,因為它的一部分(通常)儲存在 MBR 和第一個分區之間的磁碟空間中。
但是我怎麼知道到底在哪裡呢?
我知道我可以只複製第一個分區前面的整個空間,但我很好奇是否有一些命令可以顯示 GRUB 各個部分的確切位置。
澄清:沒有單獨的引導分區。只有 LVM 物理卷只包含根分區(帶有 /boot 文件夾)。引導問題也可以通過
chroot
進入複製的映像並執行來修復grub-install
。
在 GRUB2 創建的 MBR 中,從偏移量 0x5c 開始,有一個 little-endian 64 位值,指示要載入的下一個磁碟塊的編號。這通常是塊 0x00000000 00000001,即 MBR 之後的下一個塊。
(按照古老的 DOS 慣例,第一個分區將從 #1 柱面的開頭開始,因此在 MBR 之後的柱面 #0 上通常有許多未使用的塊可用。在現代系統上,第一個分區通常對齊從塊#2048,即距離磁碟開頭正好1 MB。這使得在第一個分區開始之前有更多的空閒塊。)
第二個塊包含更多的 GRUB 核心程式碼,以及一個塊列表,它指定要從中載入其餘 GRUB 核心映像的塊。阻止列表位於此塊的最後。每個阻止列表條目長 12 個字節,結構如下:
struct __attribute__ ((packed)) g2_blist_entry { uint64_t start_lba; # the LBA block number of the first block covered by this entry uint16_t num_blocks; # number of blocks to read uint16_t startseg; # segment address in memory to write them to };
通常,阻止列表只有一個條目,它涵蓋了要讀取的所有剩餘塊,從塊 0x00000000 00000002 開始。
GRUB 核心映像的長度根據 GRUB 版本和附加到 GRUB 核心的模組數量而有所不同。
例如,在我使用傳統 MBR 引導的 Debian 9 系統上,GRUB 在 MBR 之後總共包含 103 個塊。在 RHEL 7.4 VM 上,總長度是 MBR 之後的 107 個塊。