Skip to content

BushidoCyb3r/multus

Repository files navigation

Multus

Version Boot menu preview Documentation

Multus — put many Linux install/live ISOs on one USB stick and pick which to boot, by copying files, with no reinstall and no extraction. Clean-room build on GRUB2. Linux only.

The Multus boot menu

At boot you get a graphical, arrow-key menu (the picture above) listing every ISO on the stick, each tagged with the distro family Multus detected. Pick one, press Enter, and it boots. Works on UEFI and legacy BIOS.

How it works

The USB has three partitions:

# Size FS Purpose
1 1 MiB BIOS boot (GRUB core for legacy BIOS)
2 128 MiB FAT32 EFI System — GRUB + the boot menu
3 rest ext4 (default) or exFAT Your ISOs live in /ISO (installer asks)

At boot, GRUB scans /ISO (and one level of subfolders), inspects each .iso to detect its distro family, and builds the menu on the fly. Add an ISO → it appears next boot. No regeneration step.

Data filesystem — the installer asks; pick ext4 (the recommended default). casper (Ubuntu/Mint/Pop), live-boot (Debian/Kali/MX), dracut (Fedora/RHEL) and Debian-installer all need ext4 — their initrds can't mount exFAT/NTFS, so on exFAT they can't re-find the ISO and won't boot. ext4 also holds >4 GiB ISOs. Its only downside is that Windows/macOS can't natively write to it (copy ISOs from a Linux box). exFAT only buys cross-OS copy convenience and only suits a minority of ISOs (e.g. Arch); most Linux ISOs won't boot from it. Choose ext4 unless you specifically need exFAT and only use exFAT-compatible ISOs.

Install

The Multus desktop app (app/, Tauri) is the recommended way on both macOS and Linux — an Etcher-style window to build a stick, add ISOs, and manage what's on it. It drives the same engine described below. Download the unsigned .dmg (macOS) or the native .deb/.rpm (Linux) from CI (or build it: see app/README.md).

Prefer a terminal? On Linux there's a headless multus-cli tool (packaged as .deb/.rpm) — see Command-line tool (Linux) below. The installer/install.sh script shown further down is the underlying Linux build engine (macOS uses installer/install-macos.sh); the app and the multus-cli tool both drive it.

Linux is the primary platform; macOS is supported (UEFI-only) via the app or installer/install-macos.sh — see docs/MACOS.md.

The old SwiftUI macOS app and the legacy GTK Linux GUI have both been removed, superseded by the cross-platform app/; the macOS privileged helper now lives in helper/.

The Linux installer needs grub-install/grub2-install, sfdisk, mkfs.vfat, and mkfs.ext4 or mkfs.exfat for the data partition. On macOS the command-line installer uses a Homebrew GRUB toolchain + native diskutil (run ./setup.sh); the desktop app bundles these tools, so it needs no Homebrew.

sudo installer/install.sh /dev/sdX     # /dev/sdX = your USB, ALL DATA ERASED

Then copy ISOs onto the MULTUSDATA partition's ISO/ folder and boot the target machine from the USB.

Command-line tool (Linux)

For headless boxes / servers there's a multus-cli tool — a thin wrapper over the same engine the app drives (so installer staging and behaviour are identical). It's packaged from CI as a .deb and .rpm; the package and the installed command are both multus-cli (at /usr/bin/multus-cli, distinct from the desktop app's /usr/bin/multus so you can install both). Installing it pulls the engine's tools (GRUB, xorriso, e2fsprogs, …) from your distro's repos:

sudo dnf install ./multus-cli-*.rpm     # Fedora / RHEL / Rocky
sudo apt install ./multus-cli_*.deb     # Debian / Ubuntu

Use apt install ./… / dnf install ./… (note the leading ./) — not dpkg -i / rpm -i. Only the package manager resolves the declared dependencies (xorriso, grub, e2fsprogs, dosfstools, …); dpkg -i installs without them and Multus then can't stage installers or classify ISOs ("xorriso not found — skipping…"). Already used dpkg -i? Run sudo apt-get install -f (Debian/Ubuntu) to pull the missing dependencies.

RHEL / Rocky / AlmaLinux: every required dependency (xorriso, grub2, e2fsprogs, dosfstools, …) is in the default AppStream base repo, so the single dnf install ./… resolves them with no EPEL. EPEL is only needed for the optional exFAT data partition (exfatprogs, a weak dependency): sudo dnf install -y epel-release.

Usage:

multus-cli --build /dev/sdX --iso path/to.iso --yes   # build a stick (ERASES /dev/sdX)
multus-cli --add-iso path/to.iso                       # copy ISO(s) into /ISO + stage installers
multus-cli --remove-iso NAME.iso                        # delete ISO(s) from /ISO
multus-cli --list                                       # list ISOs on a Multus stick
multus-cli --list-drives                                # show removable / USB disks
multus-cli --sync-installers                            # re-stage installers + rebuild the manifest
multus-cli --help                                       # full synopsis

--build takes optional --fs ext4|exfat and --yes (skip the typed-ERASE prompt). The drive is auto-detected when exactly one Multus stick is plugged in, or pass --drive /dev/sdX. Privileged actions re-run themselves under sudo.

Distro support status

Verified families boot end-to-end under QEMU/KVM with real ISOs; the generic fallback is best-effort for ISO layouts without a dedicated strategy.

Family Detect by Status
Ubuntu / Mint / Pop /casper/vmlinuz ✅ verified (24.04.4 + 26.04 desktop, ext4 data)
Debian / Kali / MX /live/vmlinuz ✅ verified (Debian 13.5 live, ext4 data)
Arch / Endeavour /arch/boot ✅ verified (Arch 2026.06.01, img_dev/img_loop, ext4)
Fedora / RHEL /LiveOS/squashfs.img ✅ verified (Fedora 44 WS, ext4)
Anaconda installers /images/install.img ✅ verified (Security Onion 3.1.0, ext4)
Debian-installer /install.amd/vmlinuz ✅ verified (Debian 13.5 netinst, ext4)
Proxmox VE/PBS/PMG /boot/linux26 ✅ verified (PVE 9.2, QEMU; whole-ISO-in-RAM — see note)
loopback.cfg ISOs /boot/grub/loopback.cfg ✅ verified (SystemRescue 13.01)
Generic Linux kernel hunt best-effort

Verified casper/live-boot families need an ext4 data partition (their initrd can't mount exFAT/NTFS); the installer prompts for this.

Anaconda installer ISOs (Security Onion, Rocky, RHEL, Fedora Everything) boot via inst.stage2=hd:LABEL=MULTUSDATA:/ISO/<name>.iso. To run the vendor's automated install (kickstart) rather than the bare interactive installer, the ISO's /ks.cfg is staged to the ESP at install time — pass the ISOs to install.sh, or run installer/sync-installers.sh /dev/sdX after copying them on. Without it you still get the interactive installer.

Debian-installer ISOs (Debian netinst/DVD) can't find a loopback ISO with their on-ISO initrd (it uses cdrom-detect, no iso-scan). Multus boots the ISO's own kernel with the matching hd-media initrd (which ships iso-scan), staged to the ESP and fetched from the Debian mirror at install time — so this step needs network. Pass the ISO to install.sh, or run installer/sync-installers.sh /dev/sdX after copying it on. Needs an ext4 data partition (iso-scan can't read exFAT).

Proxmox ISOs (Proxmox VE, Backup Server, Mail Gateway) ship no iso-scan/findiso — their installer can't re-find a loopback ISO the usual way (its block-device CD scan can't see a GRUB loopback). Instead Multus uses Proxmox's own PXE path: it assembles the whole ISO into the installer's initramfs as /proxmox.iso, which Proxmox's init loop-mounts as the install medium. Multus stages the ISO's own kernel + base initrd and a small cpio header/trailer onto the data partition (/multus/pve), then GRUB boots them and concatenates base-initrd + header + the raw ISO + trailer as the initramfs. (Plain initrd concatenation — GRUB's newc: wrapping is not used because RHEL/Rocky's GRUB can't parse it. No network.) Staging happens on build, and on add/sync for an existing stick. Because the whole ISO unpacks into an initramfs tmpfs (~half of RAM), the target needs RAM ≳ 2× the ISO size — for a ~1.7 GiB Proxmox VE ISO that's ≥ ~4 GiB, 6 GiB+ comfortable. Upside: the booted kernel never reads the data partition, so Proxmox boots from an exFAT data stick too.

Roadmap / not yet done

Verified under QEMU/OVMF only, and Secure Boot must be OFF. Design + plans for the work that needs real signing/boot/hardware testing live in docs/: Secure Boot, persistence, hardware testing, verification queue, classification.

Layout

src/grub/grub.cfg     the runtime menu + discovery/classification logic
src/grub/theme/       the graphical gfxmenu theme (logo, fonts, layout)
installer/            the shell engine: install.sh (Linux), install-macos.sh,
                      add-isos*.sh, remove-isos*.sh, index-macos.sh, lib.sh
app/                  the cross-platform desktop app (Tauri) — the GUI
helper/               the macOS privileged helper (root launchd daemon + FDA shim)
test/render-menu.sh   render the real boot menu to a PNG (no root, no USB)
test/render-theme.sh  preview just the theme with demo entries
test/run.sh           QEMU boot test: discovery + classification assertions
docs/                 design notes + menu preview

Requirements

  • GRUB 2.12+ (earlier versions can't read exFAT)
  • A Linux host to run the installer
  • sfdisk (in util-linux on Fedora/RHEL; in the fdisk package on Debian/Ubuntu), plus util-linux, dosfstools, exfatprogs, grub2

License

Multus is licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later) — see LICENSE. Third-party software Multus bundles or writes onto a stick (GRUB, e2fsprogs, e2tools, xorriso, DejaVu fonts) and its source locations are documented in THIRD-PARTY-LICENSES.md.


Badges verified rendering on GitHub: both shields.io images return HTTP 200 SVG through GitHub's camo image proxy, GitHub's GFM renderer parses the badge markup correctly, and the relative links (docs/menu-preview.png, docs/DESIGN.md) resolve on the default branch.

About

Turn a USB stick into a GRUB2 multiboot launcher: drop in multiple Linux ISOs (live + installer-class) and boot any of them via UEFI or BIOS. Cross-platform desktop app (macOS + Linux) plus a headless CLI.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors