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 производим разметку. Сделал скриншот, но вы наверное сами всё знаете и умеете. Пусть будет.
разметка диска
Пояснение что тут сделано:
запускаю fdisk с указанием блочного устройства диска/флэшки для разметки
вывожу на экран текущую таблицу разделов (p — print) и убеждаюсь что она пустая
создаю новый раздел (n — new)
выбираю тип раздела (p — primary), в данном случае просто соглашаюсь нажатием enter
fdisk предлагает использовать первый раздел, согласен — enter
первый сектор не вижу смысла менять. Enter
запрашивает последний сектор раздела, можно указать смещение относительно первого сектора в секторах или единицах измерения дискового пространства. Указал 60 Гб
смотрим планируемую таблицу разделов (p — print) и проверяем корректность
записываю таблицу разделов на диск (w — write)
Следующим этапом формируем файловую систему. В нашем случае требования к файловой системе тоже минимальные — достаточно будет и ext2
формирование файловой системы
Записываем загрузчик и копируем наши образы в каталог iso, который предварительно создадим на нашем мультизагрузочном диске (флэшке). Скриншот прилагается.
запись загрузчика 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
}
Если что упустил, в виду нехватки знаний, или круто заблуждаюсь — пишите, буду втихаря корректировать статью, надеюсь, никто не заметит.