[*nix] Загрузка Linux с VHD на компьютере с BIOS
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Загрузка Linux с VHD может пригодиться в различных сценариях, например, когда на компьютере установлена Windows и есть необходимость в Linux, но WSL или виртуальной машины с Linux недостаточно, а разбивать диск на разделы нет желания. Microsoft позволяет грузить Windows с VHD «из коробки» начиная со старших редакций Windows 7. Но что делать, если возникла необходимость загрузить таким способом Linux?На форумах часто можно встретить мнение, что загрузить Linux с VHD либо нельзя, либо очень сложно. Полезной информации в интернете на эту тему действительно мало. Базовая идея, как это осуществить, описана тут. Суть в следующем:
- Необходимо убедиться в поддержке NTFS на всех этапах.
- Необходимо убедиться в поддержке loop-устройств.
- Добавить в загрузочные скрипты ОС команду монтирования loop-устройства.
- Перестроить initramfs.
- Убедиться, что все необходимые утилиты добавлены в образ, обновить initramfs внутри VHD.
- В случае legacy-зарузки (BIOS) и использования штатного загрузчика Windows добавить grub4dos в меню bootmgr, а в меню grub4dos добавить пункт для загрузки с VHD.
Практическое применение этой идеи для Arch Linux описано тут. В этой статье я проведу аналогичный эксперимент с Debian. Предполагается, что читатель имеет представление о работе с консолью в Windows и в Linux, умеет работать со стандартными системными утилитами, с ПО для виртуализации и т.п. — элементарные вещи подробно не расписаны.Процесс загрузки будет выглядеть так: bootmgr -> grub4dos -> initramfs -> debian. Рассмотрим подготовку каждого этапа справа налево.Установка Linux на VHDДля начала необходимо создать пустой образ VHD с фиксированным размером. Если нужно минимизировать размер образа, то для экспериментов с CLI достаточно создать диск объемом ~1,5 Гб. Для рабочей системы с GUI можно ограничиться объемом 10 Гб (с условием хранения пользовательских данных вне VHD).Создадим VHD с помощью diskpart.exe:
create vdisk file=<path_to_vhd>\debian.vhd type=fixed maximum=1500
Далее необходимо установить Debian на VHD. Я для этого воспользовался VirtualBox 6.1, устанавливал debian-10.8.0-amd64-netinst.iso. Параметры виртуальной машины — по умолчанию, новый диск создавать не надо, достаточно подключить ранее созданный debian.vhd.Параметры VirtualBox
Установка Debian стандартна, обращу внимание только на некоторые моменты.При разметке диска я создал один загрузочный раздел ext4. Раздел подкачки на VHD я делать не стал, после установки можно разместить файл или раздел подкачки в удобном месте.Разметка диска
При выборе дополнительного ПО для установки я оставил только SSH-сервер и стандартные системные утилиты. Всё остальное можно поставить потом, по необходимости. GRUB установлен в MBR. Если при установке была выбрана русская локаль, то после установки можно добавить локаль en_US командой dpkg-reconfigure locales.Подготовка Linux к загрузке с VHDВ установленную систему необходимо добавить поддержку NTFS и утилиту partprobe, которая позволяет сообщить ядру ОС о необходимости повторного чтения таблицы разделов жёсткого диска.
apt-get install ntfs-3g parted
Затем надо подготовить скрипты для initramfs.
initramfs — это начальная файловая система в оперативной памяти, которая содержит утилиты и скрипты, требуемые для монтирования файловых систем перед вызовом init, располагающегося в корневой файловой системе.
Скрипты для initramfs созданы на основе документации. Наши дополнения для initramfs мы будем размещать в следующих каталогах.
- /etc/initramfs-tools/hooks/ — здесь размещаются скрипты, которые запускаются при генерации initramfs-образа. Тут мы разместим скрипт для добавления в initramfs утилиты partprobe с необходимыми библиотеками.
- /etc/initramfs-tools/scripts/local-top/ — после выполнения этих скриптов загрузчик считает, что root-устройство смонтировано. Т.е. здесь будет скрипт для монтирования VHD.
Скрипт для добавления partprobe в initramfs возьмем из этой статьи с добавлением еще одной библиотеки. Надо создать файл partcopy и сделать его исполняемым:partcopy
#!/bin/sh
cp -p /sbin/partprobe "$DESTDIR/bin/partprobe"
cp -p /lib/x86_64-linux-gnu/libparted.so.2 "$DESTDIR/lib/x86_64-linux-gnu/libparted.so.2"
cp -p /lib/x86_64-linux-gnu/libreadline.so.7 "$DESTDIR/lib/x86_64-linux-gnu/libreadline.so.7"
cp -p /lib/x86_64-linux-gnu/libtinfo.so.6 "$DESTDIR/lib/x86_64-linux-gnu/libtinfo.so.6"
Скрипт для монтирования VHD сделан на основе скрипта для Arch Linux с учетом особенностей выбранного дистрибутива Linux. Скрипт необходимо сохранить под именем loop_boot_vhd и сделать исполняемым:loop_boot_vhd
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
get pre-requisites
prereqs)
prereqs
exit 0
;;
esac
cmdline=$(cat /proc/cmdline)
#cmdline="root=/dev/loop0p1 loop_file_path=/debtst.vhd loop_dev_path=/dev/sda2"
for x in $cmdline; do
value=${x#=}
case ${x} in
root=) value_loop_check=${value#loop}
if [ x$value_loop_check != x$value ]
then loop_dev=${value%p}
loop_part_num=${value##p}
else echo "Root device is not a loop device. loopboot hook will be terminated."; return
fi ;;
loop_file_path=) loop_file_path=$value ;;
loop_dev_path=*) loop_dev_path=$value ;;
esac
done
if [ -z $loop_file_path ] || [ -z $loop_dev_path ]
then echo "Either loop_file_path or loop_dev_path parameter does not specified. loopboot hook will be terminated."; return
fi
#modprobe fuse
modprobe loop max_part=64 max_loop=8
loop_dev_type=$(blkid -s TYPE -o value $loop_dev_path)
if [ ! -d /host ]; then
mkdir /host
fi
if [ "$loop_dev_type" != "ntfs" ]
then mount -t $loop_dev_type $loop_dev_path /host; echo "mount -t $loop_dev_type $loop_dev_path /host"; echo "mounted using mount";
else ntfs-3g $loop_dev_path /host; echo "mounted using ntfs-3g";
fi
losetup $loop_dev /host$loop_file_path
partprobe $loop_dev
Немного подробнее поясню логику работы скрипта. Обработка prereqs рекомендована в документации. В переменную cmdline попадает строка инициализации из grub4dos, например, root=/dev/loop0p1 loop_file_path=/debian.vhd loop_dev_path=/dev/sda2. Далее идет разбор этой строки и из нее определяется номер партиции на loop-устройстве, а в переменные loop_dev_path и loop_file_path сохраняются путь к устройству, на котором хранится VHD-файл, и путь к VHD-файлу на устройстве. Если данные для этих переменных не переданы, то скрипт прекращает работу и система пытается загрузиться в обычном режиме. Если переменные определены, то загружается модуль ядра для подержки loop-устройств с указанием в параметрах максимального количества loop-устройств и максимального количества таблиц разделов на loop-устройстве. Затем командой blkid определяется тип файловой системы диска, на котором хранится VHD-файл. Если VHD лежит на NTFS, то монтирование производится с помощью команды ntfs-3g, иначе — командой mount. Монтирование производится в каталог /host (который при необходимости предварительно создается). После этого VHD подключается в систему командой losetup, а затем partprobe сообщает ядру о новом диске.После размещения скриптов в нужные каталоги (/etc/initramfs-tools/scripts/local-top/loop_boot_vhd и /etc/initramfs-tools/hooks/partcopy) необходимо пересобрать initramfs командой:
update-initramfs -c -k all
Для дальнейшей настройки надо запомнить номер версии ядра: /boot/initrd.img-4.19.0-14-amd64 и /boot/vmlinuz-4.19.0-14-amd64.На этом образ готов к запуску на реальном железе, можно выключать виртуальную машину и приступать к подготовке загрузчика. Готовый образ debian.vhd надо скопировать в корень диска C:, дальнейшие скрипты написаны исходя из предположения, что VHD находится в корне NTFS-раздела.Настройка grub4dosДля начала надо скачать актуальную версию grub4dos. Работа с этой утилитой в различных источниках описана достаточно подробно. Настройка сводится к следующему:
- необходимо найти раздел, в корне которого лежит VHD-файл, и сделать его корневым для всех команд в текущем пункте меню (команда find --set-root);
- затем загрузить образ жесткого диска (команды map ...vhd и map --hook);
- далее подключенный образ указать как корневое устройство (команда root);
- и указать параметры запуска Linux (kernel и initrd).
Получается файл menu.lst с таким содержимым:menu.lst
title debian
find --set-root --ignore-floppies --ignore-cd /debian.vhd
map /debian.vhd (hd3)
map --hook
root (hd3,0)
kernel /boot/vmlinuz-4.19.0-14-amd64 root=/dev/loop0p1 rw loop_file_path=/debian.vhd loop_dev_path=/dev/sda2
initrd /boot/initrd.img-4.19.0-14-amd64
Тут надо обратить внимание на один момент: в команде kernel инициализируются переменные, которые передаются в initramfs и используются в ранее созданном скрипте loop_boot_vhd.В моем примере переменные заполнены исходя из моей конфигурации компьютера: один диск с Windows, разбитый на два раздела (загрузочный "System Reserved" и основной NTFS), а внутри VHD — один раздел ext4.Настройка загрузчика bootmgrОбратите внимание: в зависимости от версии Windows и особенностей установки ОС возможны незначительные отличия.Первое, что надо сделать, — подключить скрытый раздел с bootmgr, в примере ниже я подключаю скрытый раздел "System Reserved" в каталог C:\mnt (каталог должен быть предварительно создан). Команды выполняются в diskpart.exe:
list volume
Volume 1 System Rese NTFS Partition 549 MB Healthy System
Volume 2 C NTFS Partition 49 GB Healthy Boot
select volume 1
assign mount=C:\mnt
После этого надо распаковать в каталог C:\mnt\ файлы из архива с grub4dos: grldr и grldr.mbr. В этот же каталог надо скопировать файл menu.lst, созданный на предыдущем шаге. После этого раздел можно отключить в diskpart.exe:
remove mount=C:\mnt
Чтобы настроить отображение пункта меню при загрузке Windows, надо сделать следующее:
bcdedit.exe -create -d grub4dos -application bootsector
*The entry {GUID} was successfully created.
В ответ будет сообщен GUID нового пункта меню. Полученный GUID используется в следующих командах:
bcdedit.exe -set {GUID} device boot
bcdedit.exe -set {GUID} path \grldr.mbr
bcdedit.exe -displayorder {GUID} -addlast
Тут подробно не останавливаюсь, все команды очевидны и хорошо описаны в документации. Ну, и чтобы не переключаться лишний раз между графическим и текстовым режимами:
bcdedit.exe /set {default} bootmenupolicy legacy
На этом всё: можно перезагрузить компьютер, выбрать в меню загрузки grub4dos, затем Debian, после чего должен загрузиться Linux.Что делать, если не грузится?В этом случае, скорее всего, неверно указаны параметры с путями к устройству, на котором находится VHD-файл, или раздел на loop-устройстве. Если загрузка останавливается на уровне grub4dos, то в консоли надо последовательно вводить команды, перечисленные в menu.lst, и смотреть на результаты, в зависимости от которых правильно указать параметры для загрузки Linux. Если загрузка останавливается в initramfs, то надо проверить доступность необходимых устройств на этом этапе. Проверить можно, последовательно вводя команды из скрипта loop_boot_vhd (основное: смонтировать нужные разделы, найти VHD, подключить его, проверить присвоенный номер партиции с Linux, в моем примере — loop0p1).А как же UEFI?Это немного другая история, надеюсь, позже найду время и проведу аналогичный эксперимент с UEFI.
===========
Источник:
habr.com
===========
Похожие новости:
- [*nix, Разработка под Linux, Интернет вещей, DIY или Сделай сам] Подключаем дисплей SPI LCD ILI9341 к одноплатному компьютеру Banana Pi BPI-M64 или любому другому на ОС Armbian
- [Open source, Системное программирование, Реверс-инжиниринг] Linux для macOS M1: что сделала команда Asahi Linux за январь-февраль 2021 (перевод)
- [Программирование, GTK+, Разработка под Linux] Пишем онлайн-радио на языке Vala
- [Системное администрирование] ossh: параллельное выполнение команд на многих серверах
- [Open source, *nix] FOSS News №60 – дайджест материалов о свободном и открытом ПО за 8-14 марта 2021 года
- [Информационная безопасность, Open source, Системное администрирование, GitHub, Разработка под Linux] Эксперты обнаружили критическую уязвимость в подсистеме iSCSI ядра Linux, баг в коде был с 2006 года
- [Python, *nix, C, Разработка под Linux] C и Python: мост между мирами
- Уязвимость в подсистеме iSCSI ядра Linux, позволяющая поднять свои привилегии
- [Программирование, C++, C, Разработка под Linux] Неблокирующие паттерны: атомарные операции и частичные барьеры памяти (перевод)
- Весеннее обновление стартовых наборов ALT p9
Теги для поиска: #_*nix, #_vhd, #_linux, #_debian, #_grub4dos, #_blog_kompanii_domklik (
Блог компании ДомКлик
), #_*nix
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:35
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Загрузка Linux с VHD может пригодиться в различных сценариях, например, когда на компьютере установлена Windows и есть необходимость в Linux, но WSL или виртуальной машины с Linux недостаточно, а разбивать диск на разделы нет желания. Microsoft позволяет грузить Windows с VHD «из коробки» начиная со старших редакций Windows 7. Но что делать, если возникла необходимость загрузить таким способом Linux?На форумах часто можно встретить мнение, что загрузить Linux с VHD либо нельзя, либо очень сложно. Полезной информации в интернете на эту тему действительно мало. Базовая идея, как это осуществить, описана тут. Суть в следующем:
create vdisk file=<path_to_vhd>\debian.vhd type=fixed maximum=1500
Установка Debian стандартна, обращу внимание только на некоторые моменты.При разметке диска я создал один загрузочный раздел ext4. Раздел подкачки на VHD я делать не стал, после установки можно разместить файл или раздел подкачки в удобном месте.Разметка диска При выборе дополнительного ПО для установки я оставил только SSH-сервер и стандартные системные утилиты. Всё остальное можно поставить потом, по необходимости. GRUB установлен в MBR. Если при установке была выбрана русская локаль, то после установки можно добавить локаль en_US командой dpkg-reconfigure locales.Подготовка Linux к загрузке с VHDВ установленную систему необходимо добавить поддержку NTFS и утилиту partprobe, которая позволяет сообщить ядру ОС о необходимости повторного чтения таблицы разделов жёсткого диска. apt-get install ntfs-3g parted
initramfs — это начальная файловая система в оперативной памяти, которая содержит утилиты и скрипты, требуемые для монтирования файловых систем перед вызовом init, располагающегося в корневой файловой системе.
#!/bin/sh
cp -p /sbin/partprobe "$DESTDIR/bin/partprobe" cp -p /lib/x86_64-linux-gnu/libparted.so.2 "$DESTDIR/lib/x86_64-linux-gnu/libparted.so.2" cp -p /lib/x86_64-linux-gnu/libreadline.so.7 "$DESTDIR/lib/x86_64-linux-gnu/libreadline.so.7" cp -p /lib/x86_64-linux-gnu/libtinfo.so.6 "$DESTDIR/lib/x86_64-linux-gnu/libtinfo.so.6" #!/bin/sh
PREREQ="" prereqs() { echo "$PREREQ" } case $1 in get pre-requisites prereqs) prereqs exit 0 ;; esac cmdline=$(cat /proc/cmdline) #cmdline="root=/dev/loop0p1 loop_file_path=/debtst.vhd loop_dev_path=/dev/sda2" for x in $cmdline; do value=${x#=} case ${x} in root=) value_loop_check=${value#loop} if [ x$value_loop_check != x$value ] then loop_dev=${value%p} loop_part_num=${value##p} else echo "Root device is not a loop device. loopboot hook will be terminated."; return fi ;; loop_file_path=) loop_file_path=$value ;; loop_dev_path=*) loop_dev_path=$value ;; esac done if [ -z $loop_file_path ] || [ -z $loop_dev_path ] then echo "Either loop_file_path or loop_dev_path parameter does not specified. loopboot hook will be terminated."; return fi #modprobe fuse modprobe loop max_part=64 max_loop=8 loop_dev_type=$(blkid -s TYPE -o value $loop_dev_path) if [ ! -d /host ]; then mkdir /host fi if [ "$loop_dev_type" != "ntfs" ] then mount -t $loop_dev_type $loop_dev_path /host; echo "mount -t $loop_dev_type $loop_dev_path /host"; echo "mounted using mount"; else ntfs-3g $loop_dev_path /host; echo "mounted using ntfs-3g"; fi losetup $loop_dev /host$loop_file_path partprobe $loop_dev update-initramfs -c -k all
title debian
find --set-root --ignore-floppies --ignore-cd /debian.vhd map /debian.vhd (hd3) map --hook root (hd3,0) kernel /boot/vmlinuz-4.19.0-14-amd64 root=/dev/loop0p1 rw loop_file_path=/debian.vhd loop_dev_path=/dev/sda2 initrd /boot/initrd.img-4.19.0-14-amd64 list volume
Volume 1 System Rese NTFS Partition 549 MB Healthy System Volume 2 C NTFS Partition 49 GB Healthy Boot select volume 1 assign mount=C:\mnt remove mount=C:\mnt
bcdedit.exe -create -d grub4dos -application bootsector
*The entry {GUID} was successfully created. bcdedit.exe -set {GUID} device boot
bcdedit.exe -set {GUID} path \grldr.mbr bcdedit.exe -displayorder {GUID} -addlast bcdedit.exe /set {default} bootmenupolicy legacy
=========== Источник: habr.com =========== Похожие новости:
Блог компании ДомКлик ), #_*nix |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:35
Часовой пояс: UTC + 5