USB-Stick mit bootbarem Linux, Ubuntu ISO und Windows Setup

Motivation

Ich habe einen USB-Stick, von welchem ich direkt Ubuntu Linux starten kann. Ich habe einen weiteren USB-Stick mit dem Ubuntu Installer darauf. Gelegentlich muss ich leider auch mal Windows installieren, weshalb ich einen zusätzlichen USB-Stick habe, auf welchem das Windows Setup liegt. Standardmäßig habe ich nie den USB-Stick bei mir, welchen ich gerade brauche. Deswegen kombiniere ich alle Funktionen in einem.

Partitionen

Auch Windows 10 liest - wie Windows das immer tut - von USB-Sticks nur die erste Partition. Das Windows 10 Setup scheint Schwierigkeiten zu haben, sich selbst von Datenträgern zu lesen, welche GPT verwenden. Daher muss der traditionelle MBR verwendet werden. UEFI-Systeme kommen in der Regel damit klar und möchten den EFI Bootloader von einer FAT Partition lesen. Daraus ergibt sich dieses Partitionslayout:

  1. FAT32 für EFI Bootloader, Windows 10 Setup und Ubuntu ISO
  2. ext4 für Ubuntu (optional)

Die Inhalte des Windows 10 ISO werden auf Dateiebene auf die FAT32 Partition kopiert. Außerdem wird das Ubuntu CD Abbild als ubuntu.iso dort abgelegt. In die zweite Partition wird Ubuntu installiert. Dieser Prozess wird hier nicht beschrieben. Der GRUB2 Bootloader wird manuell konfiguriert.

GRUB2 Installieren und Konfigurieren

Diese Schritte können aus dem von dem USB-Stick gestarteten Ubuntu heraus geschehen. Es kann aber auch von einem anderen Linux heraus gemacht werden.

GRUB2 installieren

Als erstes wird GRUB2 zweimal installiert: In den MBR des USB-Sticks und als EFI Bootloader in das Dateisystem. So kann der Stick in Systemen mit UEFI ohne CSM und in Systemen mit BIOS ohne UEFI genutzt werden.

Zuerst ist die erste Partition zu mounten (/dev/sda sei der USB-Stick):

mount /dev/sda1 /mnt

Den GRUB2-Loader in den MBR installieren. GRUB2 und seine Konfiguration soll auf der ersten Partition liegen:

grub-install --target=i386-pc --root=/mnt /dev/sda

GRUB2 als Bootloader für EFI in die erste Partition installieren:

grub-install --target=x86_64-efi --removable --root=/mnt /dev/sda

Die Option --removable ist für den Start von USB-Sticks offenbar wirklich notwendig.

GRUB2 konfigurieren

In /mnt/boot/grub liegt nun die grub.cfg. Sie wird erweitert um diese Einträge:

menuentry "Ubuntu ISO" {
        set isofile="/ubuntu.iso"
        search --file --set=root --no-floppy $isofile
        loopback loop ($root)$isofile
        linux (loop)/casper/vmlinuz.efi boot=casper noprompt noeject setkmap=de iso-scan/filename=$isofile
        initrd (loop)/casper/initrd.lz
}

menuentry "Windows 10 EDU Setup EFI" {
        search --file --set=root --no-floppy /efi/boot/bootx64.efi
        chainloader /efi/boot/bootx64.efi
}

menuentry "Windows 10 EDU Setup BIOS" {
        search --file --set=root --no-floppy /bootmgr
        ntldr /bootmgr
}

Es ist für ntldr und chainloader tatsächlich notwendig, $root zu setzen. Mit search --file und der Suche nach Dateien unter Angabe absoluter (relativ zur Dateiverzeichniswurzel der jeweiligen Partition) Pfade geht das komfortabel. Selbstverständlich kann auch das Label oder die UUID der ersten Partition verwendet werden. Das Laden des Windows Setups mit absolutem Pfad aber ohne Setzen von $root, z.B. ntldr (hd0,0)/bootmgr funktioniert offenbar nicht.

Diese Einträge können alternativ in die /etc/grub.d/40_custom des USB-Stick Ubuntus geschrieben werden. Dann gehen sie nicht verloren, wenn update-grub die grub.cfg neu schreibt.