Compare commits

...

1 Commits

Author SHA1 Message Date
Adrian 5b95b6fc70 New Hybrid Boot documentation 2019-01-08 00:14:59 +01:00
7 changed files with 243 additions and 136 deletions

View File

@ -0,0 +1,191 @@
# 3-in-1 Hybrid Boot Disk (BIOS/UEFI)
This guide shows how to prepare a disk on Ubuntu
to be bootable from BIOS, 32-bit and 64-bit UEFI
with Secure Boot enabled.
The intention is to create a bootable USB stick
that can be used to boot a rescue system.
All commands should be executed as root.
For more technical information, see the [notes section](#notes) at the end.
Grub will be used as the bootloader.
Install the following packages:
apt install grub-efi-amd64-bin grub-efi-ia32-bin grub-pc-bin
apt install grub-efi-amd64-signed # grub-efi-ia32-signed not available on Ubuntu
## Partitioning
* The GUIDs are fixed for easier setup with Windows
* The last partition is optional: it can be used to make changes of Ubuntu persistent
* Set the `dev` variable accordingly
<!-- -->
dev=/path/to/dev
sgdisk --disk-guid=4b534944-4949-4949-b741-44495858580a $dev
sgdisk --new=1:1M:+1M --typecode=1:ef02 --partition-guid=1:42555247-4949-4949-b741-44495858580a $dev
sgdisk --new=2:2M:+14M --typecode=2:ef00 --partition-guid=2:49494645-4949-4949-b741-44495858580a $dev
sgdisk --new=3:16M:+496M --typecode=3:2700 --partition-guid=3:524e4957-4945-4949-b741-44495858580a $dev
sgdisk --new=4:512M:+2048M --typecode=4:8300 --partition-guid=4:4e554255-5554-4949-b741-44495858580a $dev
sgdisk --new=5:2560M:4G --typecode=5:8300 --partition-guid=5:50534143-5245-4949-b741-44495858580a $dev
## Format
* Run `partprobe` before working with the disk references below
* The labels are set for easier configuration of GRUB
* The first partition is not formatted as it will be used by GRUB to store its executable code
<!-- -->
mkdosfs -F 16 -n hybrid-boot /dev/disk/by-partuuid/49494645-4949-4949-b741-44495858580a
mkntfs -Q -L hybrid-winre /dev/disk/by-partuuid/524e4957-4945-4949-b741-44495858580a
mkfs.ext4 -L hybrid-ubuntu /dev/disk/by-partuuid/4e554255-5554-4949-b741-44495858580a
mkfs.ext4 -L casper-rw /dev/disk/by-partuuid/50534143-5245-4949-b741-44495858580a
## Install GRUB
* Set the `mnt` variable accordingly
<!-- -->
mnt=/path/to/mount
mount /dev/disk/by-partuuid/4e554255-5554-4949-b741-44495858580a $mnt
mkdir -p $mnt/boot/efi
mount /dev/disk/by-partuuid/49494645-4949-4949-b741-44495858580a $mnt/boot/efi
grub-install --root=$mnt --removable --no-nvram --uefi-secure-boot --target=x86_64-efi $dev
grub-install --root=$mnt --removable --no-nvram --uefi-secure-boot --target=i386-efi $dev
grub-install --root=$mnt --modules='ext2 part_gpt' --target=i386-pc $dev
Place the following configuration snippets in `$mnt/boot/grub/grub.cfg`.
### Ubuntu
menuentry 'Ubuntu' {
search --set --label hybrid-ubuntu
linux /casper/vmlinuz boot=casper ignore_uuid persistent
initrd /casper/initrd
}
The `persistent` parameter is only useful, if the persistence partition was created.
### Windows
menuentry 'Windows (UEFI)' {
search --set --label hybrid-boot
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
menuentry 'Windows (BIOS)' {
search --set --label hybrid-winre
ntldr /Boot/bootmgr
}
## Copy OS Files
### Ubuntu
* Set the `cdrom` variable accordingly
<!-- -->
cdrom=/path/to/ubuntu-iso
cp -r $cdrom/casper $cdrom/preseed $mnt
### Windows
* Set the `cdrom` and `winre` variables accordingly
<!-- -->
cdrom=/path/to/windows-iso
winre=/path/to/winre-mnt
mount /dev/disk/by-partuuid/524e4957-4945-4949-b741-44495858580a $winre
wim=$cdrom/sources/install.wim
dir=$winre/Recovery
mkdir $dir
7z e -o$dir $wim 1/Windows/System32/Recovery/Winre.wim
7z e -o$dir $wim 1/Windows/System32/boot.sdi
dir=$winre/Boot
mkdir $dir
7z e -o$dir $wim 1/Windows/Boot/PCAT/bootmgr
dir=$mnt/boot/efi/EFI/Microsoft/Boot
mkdir -p $dir
7z e -o$dir $wim 1/Windows/Boot/EFI/bootmgfw.efi
#### BCD
Copy [winre-uefi.bcd](winre-uefi.bcd) and [winre-bios.bcd](winre-bios.bcd):
cp winre-uefi.bcd $mnt/boot/efi/EFI/Microsoft/Boot/BCD
cp winre-bios.bcd $winre/Boot/BCD
## Windows Hybrid Boot
Windows can not be booted from BIOS and UEFI with the same configuration.
The above procedure enables Windows to boot using UEFI.
Do *not* use `sgdisk` for MBR modifications,
because it wipes the MBR boot code of GRUB.
### Boot from BIOS
Windows needs an MBR to boot from BIOS:
printf 'label-id:0x4b534944\n1,0x7fff,ee\n0x8000,0xf8000,27' | sfdisk -Y dos $dev
If you try to boot without the above configuration,
the following message appears in the blink of an eye:
ata1 master: Unknown device
### Boot from UEFI
Remove the hybrid MBR:
printf 'label-id:0x00000000\n1,,ee' | sfdisk -Y dos $dev
If you try to boot without the above configuration,
the following message appears:
BlInitializeLibrary failed 0xc00000bb
## Notes
### Windows Bootloaders
The Windows bootloader is configured using a file called `BCD` (Boot Configuration Data).
The file is a binary Windows Registry file and references IDs from the partition table.
This can make Windows boot problems cumbersome to fix.
The above BCD files are usable if the disks were created using the described IDs.
They were created in a VM using BCDEdit:
[create-winre-uefi.bat](create-winre-uefi.bat) and
[create-winre-bios.bat](create-winre-bios.bat).
The UEFI bootloader `bootmgfw.efi` uses the disk and partition GUIDs from the GPT.
The BIOS bootloader `bootmgr` uses the disk signature and partition start offsets in the MBR.
To change GUIDs in a BCD, partitions with the same GUIDs can be recreated in a VM
and BCDEdit can be used to recreate a BCD: [create-minimal.bat](create-minimal.bat).
Alternatively `hivexsh` can be used to change the GUIDs in an existing BCD.
### Casper Persistence
The casper manual mentions the use of a file,
but this only works on FAT, see
[find_cow_device in casper-helpers](https://git.launchpad.net/ubuntu/+source/casper/tree/scripts/casper-helpers).

View File

@ -0,0 +1,14 @@
@echo off
bcdedit /createstore minimal.bcd
bcdedit /store minimal.bcd /create {bootmgr}
bcdedit /store minimal.bcd /create {2f4e4957-0d58-11e9-8000-080027414449} /application osloader /d "Windows 10"
bcdedit /store minimal.bcd /set {bootmgr} default {2f4e4957-0d58-11e9-8000-080027414449}
bcdedit /store minimal.bcd /set {bootmgr} displayorder {default}
bcdedit /store minimal.bcd /set {default} device partition=C:
bcdedit /store minimal.bcd /set {default} osdevice partition=C:
bcdedit /store minimal.bcd /set {default} path \Windows\System32\winload.efi
bcdedit /store minimal.bcd /set {default} systemroot \Windows

View File

@ -0,0 +1,19 @@
@echo off
bcdedit /createstore winre-bios.bcd
bcdedit /store winre-bios.bcd /create {bootmgr}
bcdedit /store winre-bios.bcd /create {2e455257-0d58-11e9-8000-080027414449} /application osloader /d "Windows Recovery Environment"
bcdedit /store winre-bios.bcd /create {2e564544-0d58-11e9-8000-080027414449} /device
bcdedit /store winre-bios.bcd /set {bootmgr} default {2e455257-0d58-11e9-8000-080027414449}
bcdedit /store winre-bios.bcd /set {bootmgr} displayorder {default}
bcdedit /store winre-bios.bcd /set {default} device ramdisk=[C:]\Recovery\Winre.wim,{2e564544-0d58-11e9-8000-080027414449}
bcdedit /store winre-bios.bcd /set {default} osdevice ramdisk=[C:]\Recovery\Winre.wim,{2e564544-0d58-11e9-8000-080027414449}
bcdedit /store winre-bios.bcd /set {default} path \Windows\System32\winload.exe
bcdedit /store winre-bios.bcd /set {default} systemroot \Windows
bcdedit /store winre-bios.bcd /set {default} winpe yes
bcdedit /store winre-bios.bcd /set {2e564544-0d58-11e9-8000-080027414449} ramdisksdidevice partition=C:
bcdedit /store winre-bios.bcd /set {2e564544-0d58-11e9-8000-080027414449} ramdisksdipath \Recovery\boot.sdi

View File

@ -0,0 +1,19 @@
@echo off
bcdedit /createstore winre-uefi.bcd
bcdedit /store winre-uefi.bcd /create {bootmgr}
bcdedit /store winre-uefi.bcd /create {2f455257-0d58-11e9-8000-080027414449} /application osloader /d "Windows Recovery Environment"
bcdedit /store winre-uefi.bcd /create {2f564544-0d58-11e9-8000-080027414449} /device
bcdedit /store winre-uefi.bcd /set {bootmgr} default {2f455257-0d58-11e9-8000-080027414449}
bcdedit /store winre-uefi.bcd /set {bootmgr} displayorder {default}
bcdedit /store winre-uefi.bcd /set {default} device ramdisk=[C:]\Recovery\Winre.wim,{2f564544-0d58-11e9-8000-080027414449}
bcdedit /store winre-uefi.bcd /set {default} osdevice ramdisk=[C:]\Recovery\Winre.wim,{2f564544-0d58-11e9-8000-080027414449}
bcdedit /store winre-uefi.bcd /set {default} path \Windows\System32\winload.efi
bcdedit /store winre-uefi.bcd /set {default} systemroot \Windows
bcdedit /store winre-uefi.bcd /set {default} winpe yes
bcdedit /store winre-uefi.bcd /set {2f564544-0d58-11e9-8000-080027414449} ramdisksdidevice partition=C:
bcdedit /store winre-uefi.bcd /set {2f564544-0d58-11e9-8000-080027414449} ramdisksdipath \Recovery\boot.sdi

Binary file not shown.

Binary file not shown.

View File

@ -1,136 +0,0 @@
# Introduction
This guide describes how to create a bootable medium
for the following purpose:
* Boot in BIOS (Legacy/CSM) mode
* Boot in UEFI mode using Secure Boot
* Start Ubuntu or a Windows 7, 8, or 10 installation
Set the following variables accordingly:
FULLDEV=/dev/sdb
DEV=${FULLDEV}1
MNT=/mnt
# Preparation
## Partition An Empty Medium
parted "$FULLDEV"
mklabel msdos
mkpart pri fat32 1MiB -1s
set 1 boot on
quit
mkdosfs -F 32 -R 8 "$DEV"
## Create Directory Structure
See below for the config files `syslinux.cfg` and `grub.cfg`
mount -o shortname=winnt "$DEV" "$MNT"
mkdir -p "$MNT"/boot/syslinux
mkdir -p "$MNT"/boot/grub
mkdir -p "$MNT"/efi/boot
cp syslinux.cfg "$MNT"/boot/syslinux
cp grub.cfg "$MNT"/boot/grub
# BIOS
syslinux -i -d boot/syslinux "$DEV"
cd /usr/lib/syslinux
for f in libutil libcom32 menu chain; do cp modules/bios/$f.c32 "$MNT"/boot/syslinux; done
sh -c "cat mbr/mbr.bin > $FULLDEV"
Note: If a `Boot error` gets reported, try this:
* Try a 3.xx version
* `mkdiskimage -4 $FULLDEV 0 64 32`
# UEFI
grub-install --target=x86_64-efi --uefi-secure-boot \
--efi-directory="$MNT" --boot-directory="$MNT"/boot \
--bootloader-id=boot --no-nvram "$DEV"
cp /usr/lib/shim/shim.efi.signed "$MNT"/efi/boot/bootx64.efi
Note: Due to [a bug](https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1450783),
the config file needs to be in efi/ubuntu:
mkdir -p "$MNT"/efi/ubuntu
cp -a "$MNT"/efi/boot/grub.cfg "$MNT"/efi/ubuntu
# Copy OS files
## Ubuntu
Execute the following commands in the directory of the mounted ISO:
rsync -Pa casper preseed "$MNT"/
## Windows
Execute the following commands in the directory of the mounted ISO:
rsync -Pa sources boot efi "$MNT"/
rm "$MNT"/sources/ei.cfg # To enable Edition selection
cp bootmgr "$MNT"/boot
7z e -o"$MNT"/efi/microsoft/boot sources/boot.wim 1/Windows/Boot/EFI/bootmgfw.efi
When copying Windows 8, the default bootloader gets replaced. Install Shim again:
cp /usr/lib/shim/shim.efi.signed "$MNT"/efi/boot/bootx64.efi
# Config Files
## syslinux.cfg
default menu.c32
prompt 0
menu title Select Operating System
label ubuntu
menu default
menu label Start Ubuntu
kernel /casper/vmlinuz.efi
append initrd=/casper/initrd.lz file=/cdrom/preseed/ubuntu.seed boot=casper ignore_uuid maybe-ubiquity quiet splash --
label win7x64
menu label Install Windows
com32 chain.c32
append fs ntldr=/boot/bootmgr
# grub.cfg
insmod efi_gop
insmod efi_uga
insmod font
menuentry "Start Ubuntu" {
set gfxmode=auto
set gfxpayload=keep
linux /casper/vmlinuz.efi file=/cdrom/preseed/ubuntu.seed boot=casper ignore_uuid maybe-ubiquity quiet splash --
initrd /casper/initrd.lz
}
menuentry "Install Windows" {
insmod part_gpt
insmod chain
set root='(hd0,1)'
chainloader /efi/microsoft/boot/bootmgfw.efi
}
menuentry "UEFI Setup" {
fwsetup
}
# Recommended Disk Partitioning for Multiboot Systems
parted /dev/sda
mklabel gpt
mkpart Boot fat32 1MiB 257MiB
mkpart SysUbuntu ext4 257MiB 12GiB
mkpart SysWin ntfs 12GiB 52GiB
mkpart Data ext4 52GiB -1s
set 1 esp on