multiboot usb-drive. своими руками

Давненько пользуюсь мультизагрузочным внешним жестким диском, набитым различными дистрибутивами Linux. В свете последних событий и очередной волны импортозамещения понадобилось дополнить его и «отечественными» дистрибутивами. Решил сделать для себя небольшое HOWTO, заодно поделиться с сообществом.

Не буду тянуть резину за хвост в долгий ящик, а сразу изложу коротенько суть — на внешнем usb-диске размещаются файлы установочных образов дистрибутивов в формате .iso, а для загрузчика grub2 формируется меню с специфичными параметрами для каждого дистрибутива, которые позволяют произвести загрузку и установку с необходимого образа. Кому стало неинтересно — расходимся. Никаких сакральных знаний тут не будет.

Для остальных поясняю зачем именно так, ведь есть на свете всяческие мультизагрузочные решения вроде ventoy и т.д.? Ну во-первых хочется получить всё самое свежее и не факт, что эти системы будут оперативно добавлять отечественные дистрибутивы при задёргивании железных штор. Во-вторых интересно в этом немного поразбираться самому. В остальных — это удобно использовать, удобно добавлять новые дистрибутивы, легко зачищать устаревшие, на внешнем диске имеется много свободного пространства, доступного системе в процессе установки — можно к примеру брать оттуда специфические драйвера, пакеты или складывать логи.

Приступаем. Приборы и материалы:

Внешний usb-диск без всяких требований к производителю/скорости/формфактору/объёму — флэшка или hdd, как у меня.

Компьютер с операционной системой linux

Установочные образы дистрибутивов linux в формате iso — скачиваем у производителей. Для лабораторной работы заготовлены вот эти файлики:

  • alt-workstation-10.0-x86_64.iso

  • CentOS-8.4.2105-x86_64-dvd1.iso

  • orel-current.iso

  • redos-MUROM-7.3–20210412-Everything-x86_64-DVD1.iso

  • REL-Desktop-DVD-x86_64–7.3.iso

  • ubuntu-21.10-desktop-amd64.iso.

Как видно, четыре из них «отечественные», а два — самые распространённые коммерческие.

Первый шаг.

Мой диск размером 250 Гб был абсолютно пустой, поэтому буду размечать и форматировать без сохранения данных. Более того, по моим прикидкам, для мультибута с данным набором дистрибутивов и планируемым развитием, будет более чем достаточно 60 Гб, а остальному пространству я найду другое применение. Подключаем диск (если система его успела автоматически смонтировать — отмонтируем), далее под рутом или через sudo производим разметку. Сделал скриншот, но вы наверное сами всё знаете и умеете. Пусть будет.

разметка дискаразметка диска

Пояснение что тут сделано:

  1. запускаю fdisk с указанием блочного устройства диска/флэшки для разметки

  2. вывожу на экран текущую таблицу разделов (p — print) и убеждаюсь что она пустая

  3. создаю новый раздел (n — new)

  4. выбираю тип раздела (p — primary), в данном случае просто соглашаюсь нажатием enter

  5. fdisk предлагает использовать первый раздел, согласен — enter

  6. первый сектор не вижу смысла менять. Enter

  7. запрашивает последний сектор раздела, можно указать смещение относительно первого сектора в секторах или единицах измерения дискового пространства. Указал 60 Гб

  8. смотрим планируемую таблицу разделов (p — print) и проверяем корректность

  9. записываю таблицу разделов на диск (w — write)

Следующим этапом формируем файловую систему. В нашем случае требования к файловой системе тоже минимальные — достаточно будет и ext2

формирование файловой системыформирование файловой системы

Записываем загрузчик и копируем наши образы в каталог iso, который предварительно создадим на нашем мультизагрузочном диске (флэшке). Скриншот прилагается.

запись загрузчика grub2 и копирование образов на дискзапись загрузчика grub2 и копирование образов на диск

Далее самое интересное — формирование меню загрузчика и настройка инсталляторов.

 Конфигурационный файл загрузчика называется grub.cfg и предсталяет собой простой текстовый файл, который должен находиться в каталоге /boot/grub2 (/mnt/USB/boot/grub2 в нашем случае). Т.к. его ещё нет, то создадим в любом текстовом редакторе. Полный формат файл рассматривать не буду, если надо, то источников в сети достаточно, здесь же будет только самый минимум необходимый для запуска инсталлятора конкретного дистрибутива.

RedHat-based дистрибутивы. Здесь их целых 3 варианта — CentOS, ROSA, REDos, но принцип формирования одинаковый т.к. используется штатный инсталлятор RedHat anaconda. Вот пример для CentOS:

menuentry "CentOS-Stream-8-x86_64-20210204" {
    isofile="/iso/CentOS-Stream-8-x86_64-20210204-dvd1.iso"
    loopback loop "${isofile}"
    linux (loop)/isolinux/vmlinuz iso-scan/filename="${isofile}" inst.stage2=hd:LABEL=CentOS-Stream-8-x86_64-dvd
    initrd (loop)/isolinux/initrd.img
}

пояснения как вписать параметры для остальных RedHat-based дистрибутивов:

menuentry — название пункта меню. Придумывайте самостоятельно.

isofile — имя образа с полным путём относительно корня нашего мультизагрузочного диска/флэшки.

Параметр LABEL это метка диска и её мы считываем утилитой blkid, предварительно смонтировав образ iso через loop-device. Если в метке встречаются пробелы, то их следует заменить на \x20.

получаем информацию о метке диска в образеполучаем информацию о метке диска в образе

Дополнительные параметры ядра и инсталлятора я намеренно убрал. В случае необходимости добавить их не составит труда, тем более что документация у RedHat очень качественная и даже переведена на русский язык. Таким же образом вносим пункты меню для RedOS и Rosa Linux (в конце статьи будет полный конфиг)

немного о параметрах ядра

многие новички спрашивают что можно, а что нельзя писать в параметрах к строчке с ядром — боязно что-нибудь сломать и получить большой кирпич. Ничего страшного — прежде всего, grub позволяет при загрузке вручную откорректировать все необходимые строчки (нажмите «e» на нужном пункте меню) и загрузиться с новыми параметрами (после правки — «Ctrl-x»). Ну и дополнительно — ядро при загрузке будет смотреть на параметры которые оно понимает (https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html), всё остальное будет просто пропущено. Полную строчку с параметрами ядро сохранит в /proc/cmdline и она будет доступна остальным процессам — например systemd. Ну и соответственно из этой строчки выбирает знакомые слова инсталлятор системы и корректирует своё поведение. А чтобы вообще хорошо погрузиться — читайте man kernel-command-line.

Debian-based дистрибутивы. Здесь также их 2 вида, но есть небольшие «подводные грабли».

Сначала конфигурация Ubuntu:

menuentry "Ubuntu 21.10 Impish Indri Release amd64 (20211012)" {
    isofile="/iso/ubuntu-21.10-desktop-amd64.iso"
    loopback loop "${isofile}"
    linux (loop)/casper/vmlinuz boot=casper iso-scan/filename="${isofile}" noprompt noeject debug file=/cdrom/preseed/ubuntu.seed maybe-ubiquity splash ---
    initrd (loop)/casper/initrd

вроде не сильно отличается от ранее рассмотренных вариантов и это хорошо. Сразу скажу, что практически всю свою профессиональную деятельность имел дело с RH-based дистрибутивами (ещё Solaris, HP-UX) и особо инсталляторы других систем не изучал. Посему строчка запуска ядра взята с образа и не корректировалась — добавлены только опции debug и iso-scan/filename.

Следующий дистрибутив Astra Linux — тоже дебиан в чистом виде. Конфигурацию привожу:

menuentry "Astra linux common edition (v2.12 OREL)" {
    isofile="/iso/orel-current.iso"
    loopback loop "${isofile}"
    linux (loop)/hd-media/vmlinuz modprobe.blacklist=evbug
    initrd (loop)/hd-media/initrd.gz
}

обращаю внимание, что ядро и рамдиск для загрузки образа находятся в каталоге /hd-media. Далее явный «косяк» (рука не поднимается написать фича) — это поиск файла образа. По документации (также и в скрипте iso-scan — я смотрел, но вникать в логику и править не стал т.к. должны использоваться оригинальные образы) можно указать через iso-scan/filename где находится файл с образом. Однако, что-то там поломано — в процессе инсталляции наблюдаем логи и видим, что и инсталлятор прошарился по всем подкаталогам, iso-scan/filename не приняв во внимание. Ну и самое неприятное в моём случае, это то, что он первым нашёл образ ubuntu и смонтировал его как родного в каталог /hd-media, проигнорировав лежащий рядом orel-current.iso! Как уже написал выше, не стал разбираться как расставить приоритеты (документация дебиана/астры мне тоже не понравилась), сделал образу orel-current.iso хардлинк в корень установочного диска и он теперь всегда находится первым. Несомненно, это костыль.

Очередной пациент — ALT Linux. Инсталлятор собственный и даже немного документирован:

menuentry "ALT Workstation 10.0 x86_64 build 2021-12-10" {
    isofile="/alt-workstation-10.0-x86_64.iso"
    loopback loop "${isofile}"
    linux (loop)/boot/vmlinuz fastboot automatic=method:disk,disk:sdb,partition:sdb1,directory:"${isofile}" stagename=altinst ramdisk_size=475545 vga=normal splash lowmem
    initrd (loop)/boot/full.cz
}

Ключевая опция — automatic. В нашем случае мы указываем метод установки — с жесткого диска (установка с образа возможна только с диска или по nfs), с диска sdb, с партиции sdb1, directory указывает на полное имя образа. Режет глаз жесткое указание диска и партиции. Если у вас в системе более одного жесткого диска, то сразу понятно что наша конфигурация уже не сработает. Тут только можно сделать «пробную» установку, провалиться в консоль и посмотреть реальные названия/пути дисков. Далее запустить повторную установку и в меню grub по нажатию «e» отредактировать параметры установки, следом грузиться по «Ctrl-x». Решение рабочее, но это неправильно и неудобно. Также полагаю что можно поиграться с командой search. Данный метод не пробовал, если кто напишет — поправлю.

Для других дистрибутивов алгоритм действий аналогичный: скачиваем установочный iso-образ и копируем его на наш диск, далее добавляем пункт меню в файл конфигурации загрузчика. Основная задача — выяснить какие опции необходимо передать установщику дистрибутива для его корректной загрузки из образа.

полный текст grub.cfg

menuentry "CentOS-Stream-8-x86_64-20210204" {
    isofile="/iso/CentOS-Stream-8-x86_64-20210204-dvd1.iso"
    loopback loop "${isofile}"
    linux (loop)/isolinux/vmlinuz iso-scan/filename="${isofile}" inst.stage2=hd:LABEL=CentOS-8-4-2105-x86_64-dvd
    initrd (loop)/isolinux/initrd.img
}

menuentry REL-Desktop-DVD-x86_64-7.3 {
    isofile="/iso/REL-Desktop-DVD-x86_64-7.3.iso"
    loopback loop "${isofile}"
    linux (loop)/isolinux/vmlinuz iso-scan/filename="${isofile}" inst.stage2=hd:LABEL=ROSA\x20Linux-7.3-x86_64
    initrd (loop)/isolinux/initrd.img
}

menuentry "RED OS MUROM-7.3" {
    isofile="/iso/redos-MUROM-7.3-20210412-Everything-x86_64-DVD1.iso"
    loopback loop "${isofile}"
    linux (loop)/isolinux/vmlinuz iso-scan/filename="${isofile}" inst.stage2=hd:LABEL=redos-MUROM-7.3\x20x86_64
    initrd (loop)/isolinux/initrd.img
}

menuentry "Astra linux common edition (v2.12 OREL)" {
    set gfxpayload=keep
    isofile="/iso/orel-current.iso"
    loopback loop "${isofile}"
    linux (loop)/hd-media/vmlinuz modprobe.blacklist=evbug
    initrd (loop)/hd-media/initrd.gz
}

menuentry "ALT Workstation 10.0 x86_64 build 2021-12-10" {
    isofile="/iso/alt-workstation-10.0-x86_64.iso"
    loopback loop "${isofile}"
    linux (loop)/boot/vmlinuz fastboot automatic=method:disk,disk:sdb,partition:sdb1,directory:"${isofile}" stagename=altinst ramdisk_size=475545 vga=normal splash lowmem
    initrd (loop)/boot/full.cz
}

menuentry "Ubuntu 21.10 Impish Indri Release amd64 (20211012)" {
    isofile="/iso/ubuntu-21.10-desktop-amd64.iso"
    loopback loop "${isofile}"
    linux (loop)/casper/vmlinuz iso-scan/filename="${isofile}" boot=casper noprompt noeject debug file=/cdrom/preseed/ubuntu.seed maybe-ubiquity splash ---
    initrd (loop)/casper/initrd
}

menuentry "Hard drive" {
    set root=(hd0,1)
    chainloader (hd0,1)+1
}

Если что упустил, в виду нехватки знаний, или круто заблуждаюсь — пишите, буду втихаря корректировать статью, надеюсь, никто не заметит.

© Habrahabr.ru