Универсальная загрузочная флешка для BIOS/UEFI
В один прекрасный момент я стал обладателем машинки, которая загружалась только с помощью UEFI. Переключателя на классический режим загрузки в BIOS не обнаружилось. Загрузиться с моей любимой Мультизагрузочной Linux-флешки оказалось невозможно. Более того — оказалось невозможно загрузиться и с помощью многих других образов, загрузчик в которых не работал с EFI.
Настало время переделать мультизагрузочную флешку, чтобы она работала на любых системах!
Подготовка
На Ubuntu надо поставить такое:
sudo add-apt-repository universe sudo apt-get install grub-efi-amd64-bin exfat-fuse exfat-utils
Разметка флешки
Полностью переразмечаем диск. Создадим четыре раздела.
disk='/dev/sdX' disk_size=`expr $(sudo sgdisk -p $disk | awk '/Disk \// ')` sudo sgdisk --zap-all $disk sudo sgdisk --mbrtogpt --clear $disk sudo sgdisk --new=1:2048:$(expr $disk_size - 16877568) $disk sudo sgdisk --typecode=1:0700 $disk sudo sgdisk --new=2:$(expr $disk_size - 16875520):$(expr $disk_size - 102401) $disk sudo sgdisk --typecode=2:0700 $disk sudo sgdisk --new=3:$(expr $disk_size - 102400):$(expr $disk_size - 4097) $disk sudo sgdisk --typecode=3:EF00 $disk sudo sgdisk --new=4:$(expr $disk_size - 4096):$(expr $disk_size - 34) $disk sudo sgdisk --typecode=4:EF02 $disk sudo sgdisk --attributes=4:set:2 $disk
Отформатируем разделы и смонтируем их.
Разделы с данными будем форматировать в NTFS. Это позволит работать с флехой из-под Windows и заливать большие файлы (больше 4-х Гб).
Как ни странно, и KNOPPIX и SystemRescueCD нормально загрузились с помощью образов, размещенных на разделах, отформатированных в NTFS.
Стоит отметить, что при использовании ntfs-3g, запись на разделы отформатированные в NTFS в Linux происходит гораздо медленнее, чем на разделы FAT32 или ExFAT. Однако, с этим можно смириться — ведь образы заливаешь один раз, но при этом — сохраняется возможность работать с флехой под виндой и загружаться с больших образов.
sudo mkfs.vfat -F 32 $3 sudo mkfs.ntfs -f $1 sudo mkfs.ntfs -f $2 sudo mkdir /mnt/usb_efi sudo mkdir /mnt/usb_data/ sudo mount -o async,big_writes,noatime $1 /mnt/usb_data/ sudo mount $3 /mnt/usb_efi/
Установим grub и EFI:
sudo grub-install --target=x86_64-efi --recheck --removable --efi-directory=/mnt/usb_efi/ --boot-directory=/mnt/usb_data/boot-grub --verbose sudo grub-install --target=i386-pc --recheck --boot-directory=/mnt/usb_data/boot-grub $disk --verbose
Ну и дальше настраиваем grub, редактируя файлик /mnt/usb_data/boot-grub/grub/grub.cfg:
http://trcmdisk01.tripod.com/linux/s_mmlf01.html
if [ x$feature_all_video_module = xy ]; then insmod all_video else insmod efi_gop insmod efi_uga insmod ieee1275_fb insmod vbe insmod vga insmod video_bochs insmod video_cirrus fi menuentry "Install Kubnuntu 21.04 Desktop" < loopback loop /kubuntu-21.04-desktop-amd64.iso set gfxpayload=keep linux (loop)/casper/vmlinuz iso-scan/filename=/kubuntu-21.04-desktop-amd64.iso file=(loop)/preseed/kubuntu.seed maybe-ubiquity quiet splash --- initrd (loop)/casper/initrd >menuentry "KNOPPIX_V8.2-2018-05-10-EN LiveCD" < loopback loop /KNOPPIX_V8.2-2018-05-10-EN.iso linux (loop)/boot/isolinux/linux bootfrom=/KNOPPIX_V8.2-2018-05-10-EN.iso keyboard=us language-us initrd (loop)/boot/isolinux/minirt.gz >menuentry "KNOPPIX_V7.2.0CD-2013-06-16-EN LiveCD" < loopback loop /KNOPPIX_V7.2.0CD-2013-06-16-EN.iso linux (loop)/boot/isolinux/linux bootfrom=/KNOPPIX_V7.2.0CD-2013-06-16-EN.iso keyboard=us language-us initrd (loop)/boot/isolinux/minirt.gz >menuentry "SystemRescueCd 5.3.1 Live (64bit, cache all files in memory and startX)" < loopback loop /systemrescuecd-x86-5.3.1.iso linux (loop)/isolinux/rescue64 isoloop=/systemrescuecd-x86-5.3.1.iso setkmap=us docache dostartx initrd (loop)/isolinux/initram.igz >menuentry "SystemRescueCd 5.3.1 Live (64bit, default boot options)" < loopback loop /systemrescuecd-x86-5.3.1.iso linux (loop)/isolinux/rescue64 isoloop=/systemrescuecd-x86-5.3.1.iso setkmap=us initrd (loop)/isolinux/initram.igz >menuentry "SystemRescueCd 5.3.1 Live (32bit, default boot options)" < loopback loop /systemrescuecd-x86-5.3.1.iso linux (loop)/isolinux/rescue32 isoloop=/systemrescuecd-x86-5.3.1.iso setkmap=us initrd (loop)/isolinux/initram.igz >menuentry "Install Kubnuntu 18.04.1 Desktop" < loopback loop /kubuntu-18.04.1-desktop-amd64.iso set gfxpayload=keep linux (loop)/casper/vmlinuz iso-scan/filename=/kubuntu-18.04.1-desktop-amd64.iso file=(loop)/preseed/kubuntu.seed boot=casper only-ubiquity quiet splash oem-config/enable=true --- initrd (loop)/casper/initrd >menuentry "Install Kubnuntu 18.04.2 Server" < set isofile="/ubuntu-18.04.2-live-server-amd64.iso" loopback loop $isofile linux (loop)/casper/vmlinuz iso-scan/filename=$isofile boot=casper quiet --- initrd (loop)/casper/initrd >menuentry "Install Kubnuntu 19.04 Desktop" < loopback loop /kubuntu-19.04-desktop-amd64.iso set gfxpayload=keep linux (loop)/casper/vmlinuz iso-scan/filename=/kubuntu-19.04-desktop-amd64.iso file=(loop)/preseed/kubuntu.seed boot=casper only-ubiquity quiet splash oem-config/enable=true --- initrd (loop)/casper/initrd >menuentry "Install Ubnuntu 20.04 Server" < insmod part_gpt insmod ext2 insmod search_fs_uuid rmmod tpm search --no-floppy --set=root --fs-uuid 36c1a912-77c7-4cec-8120-c2088e1e131c set isofile="/ubuntu-20.04-live-server-amd64.iso" set gfxpayload=keep loopback loop ($root)$isofile linux (loop)/casper/vmlinuz iso-scan/filename=$quiet --- initrd (loop)/casper/initrd > menuentry "Install Ubuntu Server 16.04 i386" < loopback loop /ubuntu-16.04.6-server-i386.iso set gfxpayload=keep linux (loop)/install/vmlinuz isoloop=/ubuntu-16.04.6-server-i386.iso file=/cdrom/preseed/ubuntu-server.seed quiet splash --- initrd (loop)/install/initrd.gz >menuentry "Install Ubuntu Server 16.04 x64" < loopback loop /ubuntu-16.04.6-server-amd64.iso set gfxpayload=keep linux (loop)/install/vmlinuz iso-scan/filename=/ubuntu-16.04.6-server-amd64.iso file=/cdrom/preseed/ubuntu-server.seed quiet splash --- initrd (loop)/install/initrd.gz >menuentry 'Debian 10 i386 Install' < set background_color=black loopback loop /debian-edu-10.0.0-i386-netinst.iso linux (loop)/install.386/gtk/vmlinuz findiso=/debian-edu-10.0.0-i386-netinst.iso modules=debian-edu-install-udeb desktop=xfce vga=788 --- quiet initrd (loop)/install.386/gtk/initrd.gz >menuentry "Memtest 86+ (from Kubnuntu 19.04)" < loopback loop /kubuntu-19.04-desktop-amd64.iso set gfxpayload=keep linux16 (loop)/install/mt86plus >
Загрузка образов дискет (FreeDOS, MemTest, MHDD, etc. )
В образе SystemRescueCD в папке /bootdisk есть образы дискет DOS с разными утилитами. Пока что мне не удалось запустить ни один из таких образов. Однако, известно, что для их запуска используется утилита memdisk, которая лежит в папке /isolinux.
Немного информации есть тут: https://www.linux.org.ru/forum/general/9653654
Общий принцип — в качестве ядра указывается memdisk, а в качестве initrd — образ дискеты
linux16 (loop)/isolinux/memdisk initrd16 (loop)/isolinux/fdboot.img
Установка Windows с такой UEFI-флешки
После копирования файлов iso-образа на раздел:
rsync -av /mnt/cdrom/ /mnt/flash/
Выяснилось, что стандартный способ загрузки Windows из grub на такой флешке не работает!
menuentry "Windows 10 Installer" < insmod ntfs search --set=root --file /bootmgr ntldr /bootmgr boot >
Оказалось, что bootmgr, используемый для загрузки компьютеров с BIOS не загружается с GPT-разделов. С GPT-разделов может загружаться только bootx64.efi, для работы которого нужен EFI.
Если попытаться загрузить bootmgr с такой флешки, то комп просто перезагрузится. Без всяких сообщений.
Вариантов загрузки Windows на BIOS-компьютере с GPT-диском несколько.
Первый — DUET (Developer’s UEFI Environment). В этом случае, сначала загружается эмулятор EFI, который загружает bootx64.efi.
Второй — использование режима hybrid MBR. Это можно сделать утилитой gdisk.
Hybrid MBR — гибридный MBR
https://www.rodsbooks.com/gdisk/hybrid.html
Обычный GPT-диск имеет запись MBR с единственным разделом типа 0xEE (EFI GPT), внутри которого размещаются разделы GPT.
Гибридный MBR, помимо основного раздела типа 0xEE (EFI GPT) может содержать сведения о дополнительных (до трех штук) разделах, границы которых совпадают с границами разделов, описанных в GPT.
Таким образом, операционки и утилиты, которые не знают ничего про GPT смогут работать и с GPT-разделов. Просто сведения о них они будут получать из MBR.
Очень важно, не давать таким утилитам и операционкам изменять таблицу разделов. В противном случае — они просто порушат GPT.
Такая конфигурация не описана стандартами и разные ОС обрабатывают её по разному. Поведение различных ОС при встрече с таким чудом описано тут.
Запускаем gdisk:
Переходим в Recovery/transformation меню:
Теперь создаем гибридную запись MBR:
Программа спросит — какие разделы должны быть добавлены в таблицу разделов гибридной записи вводим их номера через пробел:
Type from one to three GPT partition numbers, separated by spaces, to be added to the hybrid MBR, in sequence:1 2 3 4
Дальше — система спросит хотим ли мы разместить первой таблицу EFI, чтобы работал GRUB. Отвечаем yes.
А также — какие коды типов присвоить разделам гибридной таблицы и делать ли их загрузочными.
Загрузочной делаем только 4-ю партицию.
Записываем изменения w.
В двух словах — диск с гибридизированными разделами нельзя модифицировать утилитами, которые к этому не готовы (fdisk).
Мультизагрузочная флешка BIOS + UEFI в Linux
В минувший своей статье я писал как создать мультизагрузочную флешку. Она всем хороша, но из-за индустриального прогресса придется немного ее модернизировать. Дело в том, что следуя инструкциям прошлой статьи сходила флешка, загружающаяся только на компьютерах с BIOS’ом. Сейчас же идет поколение UEFI, поэтому необходимо «доработать» нашу флешку чтобы она стала загрузочной и в UEFI-компьютере. При этом не потеряв возможности по-старинке загружаться в компьютере с BIOS. Помимо этого, при создании новой флешки одним из основных критериев было минимальное внесение изменений относительно «первой» флешки. С такими, немного амбициозными, критериями я и начал свои эксперименты, вооружившись уже знакомой статьей из арчвики. Для загрузки в UEFI необходимо наличие раздела с флагом esp (флаг можно установить в Gparted, создать и отформатировать обличил в нем же). Чтобы изменения были минимальны, разобьем флешку на два раздела, как и в прошлой статье: начальный, чтобы виден был в винде, для файлов и второй загрузочный. Оба с файловой системой fat32. Устроим что флешка в компьютере определилась как диск sdb. Примонтируем второй раздел флешки в mnt:
Далее начались мои эксперименты в ходе которых выяснилось, что если устанавливать груб как обычно:
# grub-install —removable —boot-directory=/mnt /dev/sdb
То флешка берется только в компьютерах с BIOS. Если установить груб так:
# grub-install —target=x86_64-efi —removable —efi-directory=/mnt —boot-directory=/mnt /dev/sdb
То флешка берется только на компьютерах с UEFI. Универсальности не видно…
Но в который раз пробуя всяческие композиции исправления разделов флешки, разных таблиц разделов на ней (mbr и gpt) и установки всевозможных флагов (boot, esp и пр.) я увидел одну интересную особенность: если сначала установить груб для BIOS, а потом слету же для UEFI, то тогда флешка начинает загружаться и в компьютерах с BIOS, и в компьютерах с UEFI.
Не испытываю, баг это или фича, или я просто не нашел этой возможности в документации по груб, но видимо при этом сборка груба для UEFI не затирает сборку для BIOS, а становится рядом, а это как раз то что надо. Дальше уже дело промышленной. Вот, по порядку все необходимые действия:
• Создать на флешке таблицу разделов (Раздел — воздействие по глаголу разделять) mbr;
• Создать два fat32 раздела на ней: первоначальный для файлов, второй для груба;
• Собрать второй раздел в /mnt;
• Установить на флешку (-флеш-накопитель (сленг) груб для BIOS:
# grub-install —removable —boot-directory=/mnt /dev/sdb
При этом на втором разделе флешки появится папка grub. СКкпировать куда-нибудь из нее папку i386-pc. Она требуется в дальнейшем и удалить (для чистоты эксперимента) все из второго раздела флешки (то есть папку grub);
• Теперь установить на флешку груб для UEFI:
# grub-install —target=x86_64-efi —removable —efi-directory=/mnt —boot-directory=/mnt /dev/sdb
Во ином разделе уже появятся две папки: grub и EFI.
• Скопировать ранее сохраненную папку i386-pc в папку grub. Это нужно для возможности загружаться в режиме BIOS (сам загрузчик будет в первом секторе флешки, но без долей груба, находящихся в этой папке загрузка не пойдет).
• Создать рядом с папками grub и EFI папку iso и перекопировать в нее необходимые iso-образы дистрибутивов;
• Взять точно такой же файл конфигурации grub. cfg как и в ранешной статье про мультизагрузочную флешку и положить его в папку grub.
Все, теперь у вас в наличии универсальная мультизагрузочная флешка с графическим и автоматическим меню.
Свою флешку я протестировал на компьютере с UEFI и на компьютере с BIOS — везде загрузка идет как и предполагалось. Попробуйте и вы у себя. Делитесь впечатлениями в комментариях.
PS: флаг esp на иной раздел флешки можно и не ставить, флешка все равно будет работать. Единственное что я увидел — при наличии этого флага флешка в файловых менеджерах отображается как один раздел (виндоподобное воздействие). Второй раздел с файлами груб становится не виден. В принципе, это довольно удобно: не горбят постоянно глаза папки grub, EFI и iso.