четверг, 21 мая 2015 г.

Мультизагрзочная флешка с GRUB2 + UEFI

<< К статьям по программированию микроконтроллеров


В интернете нашел много разных вариантов как сделать мультизагрузочную флешку с UEFI. Но везде кругом костыли. Всякие ухищрения, чтобы эта гремучая смесь заработала. Сейчас расскажу как сделать ее на базе GRUB2.

1. Для Windows пользователей

Сейчас существуют два стандарта загрузки mbr и UEFI. Grub2 поддерживает оба. Есть такой нюанс, загрузка в этих двух стандартах отличаются, и я выложу сюда два архива. В одном архиве файлы настроены так, что несмотря на то, какой стандарт загрузки использовался (mbr или UEFI), будет подгружаться один и тот же конфигурационный файл (:\boot\grub\grub.cfg) ссылка
либо же будут использованы разные файлы для mbr загрузки (:\boot\grub\grub.cfg) и для UEFI загрузки (:\efi\grub\grub.cfg) ссылка
Для того, чтобы сделать загрузочный диск, просто запускаем скрипт createdisk.bat от имени администратора.

Дальше указываем нашу флешку,

и она готова через минуту.
Скрипт сделан на основе небезызвестной программы RMpartUSB - части проекта RMprepUsb

2. Настройка GRUB2


Grub2 настраивается через файл /boot/grub/grub.cfg

Документация от archlinux: ссылка (русский)

Официальная документация: ссылка

Переменные обозначаются в GRUB2 с помощью $ когда вы к ним обращаетесь.

Примеры загрузки:

Загрузиться с диска 1

menuentry 'boot from hd1' {
set root=hd1
chainloader +1
}

root - это переменная, которая говорит, какая файловая система считается основной. комманда chainloader +1 вызывает загрузчик устройства root

menuentry "Windows 7" {
search -s root --file /bootmgr
ntldr /bootmgr
}

первая комманда ищет раздел с файлом /bootmgr и загружает его

аналогично для загрузки windows 8 UEFI

menuentry "Windows 8 UEFI" {
  search --file --no-floppy --set=root /efi/Microsoft/Boot/bootmgfw.efi
  chainloader /efi/Microsoft/Boot/bootmgfw.efi
}

Для загрузки разных видов Linux'а делаем следующее:

menuentry "Arch Linux" {
 linux /boot/vmlinuz-linux root=LABEL=Arch_root rw
 initrd /boot/initramfs-linux.img
}

Заметьте, что необходимо передать в ядро параметры. Например, root=... В данном примере используется метка тома. Но возможно например указать его UUID

Если вам нужно загрузить ISO файл из GRUB2 то вот тут есть примеры (ссылка). Нужно смонтировать iso файл в loopback устройство и так же запустить ядро. В прниципе, с теми же параметрами, что оно вызывается в iso файле. Например:

menuentry 'ISO Ubuntu ' {
set isofile="/iso/ubuntu-12.04-desktop-amd64.iso"
loopback loop (hd0,5)$isofile
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile noprompt noeject
initrd (loop)/casper/initrd.lz
}

Если вы хотите например загрузить PARTED MAGIC. его версия 2015_03_06 ищет файл \pmagic\pmodules\PMAGIC_2015_03_06.SQFS Вытащите его из образа и скопируйте на флешку. В эти же каталоги. так же нужно вытащить ядро и initrd файл. И запустить их например этими командами

linux /pmagic/bzImage edd=on vga=normal
initrd /pmagic/initrd.img /pmagic/fu.img /pmagic/m32.img

или же еще скопировать grub.cfg и вызвать его:
configfile /EFI/boot/grub.cfg

запустить например GRUB4DOS

menuentry "Grub4Dos" {
linux /boot/grub.exe --config-file=/boot/grub/menu.lst
}

3. Установка из Linux


Установить GRUB2 на флещку:

sudo grub-install --recheck --root-directory=/run/media/user/8260-A46C2 /dev/sdb

конечно, параметры нужно указать от своей системы. Все что после media. Важно правильно задать путь до флешки. без сокращений * и туда, куда она впервые примонтирована. А то GRUB2 выдаст ошибку.

собрать EFI образ:
grub-mkimage --compress=xz -O x86_64-efi -d /usr/lib/grub/x86_64-efi
-o /home/user/bootx64.efi -p "/boot/grub" part_gpt part_msdos
ntfs ntfscomp hfsplus fat ext2 normal chain boot configfile linux
multiboot efi_gop efi_uga font gfxterm

файл будет в /home/user.
опция -p "/boot/grub" говорит о том откуда будет читаться config файл и дополнительные модули, дальше перечисление встроенных модулей.

чтобы собрать efi файл, в который встроена и конфигурация и модули делаем так:

mkdir -p /tmp/grub.temp/boot/grub
создаем /tmp/grub.temp/boot/grub/grub.cfg
cd /tmp/grub.temp/
grub-mkstandalone  --directory="/usr/lib/grub/x86_64-efi/" --format="x86_64-efi" --compress=xz --output=/home/user/bootx64.efi boot/grub/grub.cfg

почему то важен относительный путь boot/grub/grub.cfg

и потом нужно для архитектуры x86_64 скопировать /usr/lib/grub/x86_64-efi в /boot/grub/