Я подготовил образ сервера Ubuntu с VirtualBox. Чтобы передать образ на SSD сервера, я сначала dd
редактировал MBR (512 байт), а затем раздел LVM (PV, содержащий корневой раздел, уменьшился до 3 ГБ). Серверу не удалось загрузиться из-за отсутствия некоторых частей GRUB. Появлялась подсказка о спасении grub.
Как я узнал из документации GRUB, это имеет смысл, потому что его части (обычно) хранятся в дисковом пространстве между MBR и первым разделом.
Но как мне узнать, где именно?
Я знаю, что могу просто скопировать все пространство перед первым разделом, но мне любопытно, есть ли какая-нибудь команда, которая показывает точное расположение различных частей GRUB.
Уточнение : Нет отдельный загрузочный раздел. Есть только физический том LVM, содержащий только корневой раздел (с папкой / boot). Проблема с загрузкой также может быть решена с помощью chroot
, вставленного в скопированный образ и выполнения grub-install
.
В 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.