Узнать точное местоположение GRUB / GRUB, не работающего после копирования образа диска

Я подготовил образ сервера Ubuntu с VirtualBox. Чтобы передать образ на SSD сервера, я сначала dd редактировал MBR (512 байт), а затем раздел LVM (PV, содержащий корневой раздел, уменьшился до 3 ГБ). Серверу не удалось загрузиться из-за отсутствия некоторых частей GRUB. Появлялась подсказка о спасении grub.

Как я узнал из документации GRUB, это имеет смысл, потому что его части (обычно) хранятся в дисковом пространстве между MBR и первым разделом.

Но как мне узнать, где именно?

Я знаю, что могу просто скопировать все пространство перед первым разделом, но мне любопытно, есть ли какая-нибудь команда, которая показывает точное расположение различных частей GRUB.

Уточнение : Нет отдельный загрузочный раздел. Есть только физический том LVM, содержащий только корневой раздел (с папкой / boot). Проблема с загрузкой также может быть решена с помощью chroot , вставленного в скопированный образ и выполнения grub-install .

1
задан 11 February 2018 в 02:38
1 ответ

В MBR, созданной GRUB2, начиная со смещения 0x5c, существует 64-битное значение с прямым порядком байтов, указывающее номер следующего блока диска, который будет загружен. Часто это блок 0x00000000 00000001, то есть следующий блок после MBR.

(Согласно древнему соглашению DOS, первый раздел начинается в начале цилиндра №1, поэтому обычно в цилиндре №0 после MBR имеется ряд неиспользуемых блоков. В современных системах первый раздел обычно выровнен чтобы начать с блока №2048, т.е. ровно 1 МБ от начала диска. Это дает еще больше свободных блоков перед началом первого раздела.)

Этот второй блок содержит еще немного кода ядра 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.

Например, в моей системе Debian 9, которая использует устаревшую загрузку MBR, GRUB содержит в общей сложности 103 блока после MBR. На виртуальной машине RHEL 7.4 общая длина составляет 107 блоков после MBR.

2
ответ дан 3 December 2019 в 20:16

Теги

Похожие вопросы