Reorganized testing section to cover both Phase 1 (post-build script) and Phase 2 (installer-native) workflows. Added unit test commands. Removed mtools dependency from limitations. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
10 KiB
GRUB Integration Plan — Red Bear OS
Date: 2026-04-17 Status: Phase 2 complete — installer-native GRUB support implemented and compiling Approach: Option A — GRUB as boot manager, chainloading Redox bootloader
Overview
Add GNU GRUB as an optional boot manager for Red Bear OS. GRUB presents a menu at boot and chainloads the existing Redox bootloader, which then boots the kernel normally. This gives users:
- Multi-boot capability alongside Linux, Windows, or other OSes
- Boot menu with timeout and manual selection
- Familiar GRUB rescue shell for debugging
- No changes to the Redox kernel, RedoxFS, or existing boot flow
Architecture
UEFI firmware
→ EFI/BOOT/BOOTX64.EFI (GRUB standalone image)
→ grub.cfg: default entry chainloads Redox bootloader
→ EFI/REDBEAR/redbear.efi (Redox bootloader)
→ Reads RedoxFS partition
→ Loads kernel
→ Boots Red Bear OS
ESP Layout (GRUB mode)
EFI/
├── BOOT/
│ ├── BOOTX64.EFI ← GRUB (primary, loaded by UEFI firmware)
│ └── grub.cfg ← GRUB configuration
└── REDBEAR/
└── redbear.efi ← Redox bootloader (chainload target)
ESP Layout (default, no GRUB)
EFI/
└── BOOT/
└── BOOTX64.EFI ← Redox bootloader (unchanged)
Why GRUB?
- GRUB does not support RedoxFS. Writing a GRUB filesystem module for RedoxFS is high-risk, GPL-licensing-sensitive work. Chainloading avoids it.
- The Redox bootloader works. It reads RedoxFS directly and boots the kernel. No need to replicate that logic in GRUB.
- GRUB is universally understood. System administrators know GRUB. A
grub.cfgis easier to customize than a custom bootloader. - Multi-boot. GRUB can boot Linux, Windows, and other OSes alongside Red Bear OS without any changes to those systems.
GRUB Module Set
The standalone EFI image includes these modules:
| Module | Purpose |
|---|---|
part_gpt |
GPT partition table support |
part_msdos |
MBR partition table support |
fat |
FAT32 filesystem (ESP) |
ext2 |
ext2/3/4 filesystem |
normal |
Normal mode (menu, scripting) |
configfile |
Load configuration files |
search |
Search for files/volumes |
search_fs_uuid |
Search by filesystem UUID |
search_label |
Search by volume label |
chain |
Chainload other bootloaders |
echo |
Print messages |
test |
Conditional expressions |
ls |
List files and devices |
cat |
Display file contents |
halt |
Shut down |
reboot |
Reboot |
No RedoxFS module is needed — GRUB chainloads the Redox bootloader instead.
GRUB Configuration
The default grub.cfg:
# Red Bear OS GRUB Configuration
set default=0
set timeout=5
menuentry "Red Bear OS" {
chainloader /EFI/REDBEAR/redbear.efi
boot
}
menuentry "Reboot" {
reboot
}
menuentry "Shutdown" {
halt
}
Users can customize grub.cfg to add entries for other operating systems,
change the timeout, or add additional Red Bear OS entries (e.g., recovery
mode with different kernel parameters, once supported).
ESP Size Requirements
| Component | Measured Size |
|---|---|
| GRUB EFI binary (with modules) | 540 KiB |
| Redox bootloader | 100–200 KiB |
| grub.cfg | < 1 KiB |
| Total | ~1 MiB |
The default ESP is 1 MiB (too small for GRUB). Configs using GRUB must set:
[general]
efi_partition_size = 16 # 16 MiB, enough for GRUB + Redox bootloader + margin
Implementation — Phase 1: Post-Build Script
Phase 1 uses a post-build script to modify the ESP in an existing disk image. This approach requires no changes to the installer and works immediately.
Files
| File | Purpose |
|---|---|
local/recipes/core/grub/recipe.toml |
Build GRUB from source, produce grub.efi |
local/recipes/core/grub/grub.cfg |
Default GRUB configuration |
local/scripts/install-grub.sh |
Post-build ESP modification script |
local/scripts/fat_tool.py |
Python FAT32 tool (no mtools dependency) |
recipes/core/grub → local/recipes/core/grub |
Symlink for recipe discovery |
Workflow
# 1. Build GRUB recipe
make r.grub
# 2. Build Red Bear OS (with larger ESP)
make all CONFIG_NAME=redbear-full # Must have efi_partition_size = 16
# 3. Install GRUB into disk image
./local/scripts/install-grub.sh build/x86_64/harddrive.img
# 4. Test
make qemu
Requirements
- Python 3 (for
fat_tool.py— no mtools dependency) - GRUB build dependencies:
gcc,make,bison,flex,autoconf,automake - ESP must be ≥ 8 MiB (set
efi_partition_size = 16in config)
Implementation — Phase 2: Installer-Native Support
Phase 2 adds GRUB awareness directly to the Redox installer, eliminating the
post-build script step. The installer reads bootloader = "grub" from config,
fetches the GRUB package alongside the bootloader, and writes the chainload
ESP layout automatically.
Changes Made
-
GeneralConfig(config/general.rs): Addedbootloader: Option<String>field ("redox"default,"grub"for GRUB), with merge support. -
DiskOption(installer.rs): Addedgrub_efi: Option<&[u8]>andgrub_config: Option<&[u8]>fields for optional GRUB data. -
fetch_bootloaders: Whenbootloader = "grub", installs thegrubpackage alongsidebootloaderand returnsgrub.efi+grub.cfgdata. Return type extended to(bios, efi, grub_efi, grub_cfg). -
with_whole_disk/with_whole_disk_ext4: Whengrub_efiandgrub_configare both present, writes the GRUB chainload layout:EFI/BOOT/BOOTX64.EFI← GRUBEFI/BOOT/grub.cfg← GRUB configurationEFI/REDBEAR/redbear.efi← Redox bootloader (chainload target)
-
install_inner: Passes GRUB data fromfetch_bootloadersthroughDiskOption. -
CLI (
bin/installer.rs): Added--bootloader grubflag that setsconfig.general.bootloader. -
TUI (
bin/installer_tui.rs): UpdatedDiskOptionconstruction withgrub_efi: None, grub_config: None.
Config Usage
# config/redbear-full-grub.toml
include = ["redbear-full.toml"]
[general]
bootloader = "grub"
efi_partition_size = 16
Or via CLI:
./target/release/repo cook installer
make all CONFIG_NAME=redbear-full INSTALLER_OPTS="--bootloader grub"
GRUB Recipe Design
The GRUB recipe uses template = "custom" because GRUB must be built for the
host machine (it's a build tool that produces EFI binaries), not for the
Redox target. The cookbook's configure template cross-compiles for Redox,
which is wrong for GRUB.
Key build steps:
- Configure with
--target=x86_64 --with-platform=efi(produces x86_64 EFI) - Disable unnecessary components (themes, mkfont, mount, device-mapper)
- Run
grub-mkimageto create standalone EFI binary with curated modules - Stage
grub.efiandgrub.cfgto/usr/lib/boot/
Build Notes
The recipe uses template = "custom" because the cookbook's default configure
template sets --host="${GNU_TARGET}" for Redox cross-compilation, which is wrong
for GRUB (a host build tool producing EFI binaries).
Two issues required workarounds:
-
Cross-compiler override. The cookbook sets
CC,CXX,CFLAGS, etc. to the Redox cross-toolchain. GRUB must be built with the host compiler. Fix:unset CC CXX CPP LD AR NM RANLIB OBJCOPY STRIP PKG_CONFIGandunset CFLAGS CXXFLAGS CPPFLAGS LDFLAGSat the top of the script. -
Missing
extra_deps.lst. GRUB 2.12 release tarballs omitgrub-core/extra_deps.lst(normally generated byautogen.shfrom git). Fix:touch "${COOKBOOK_SOURCE}/grub-core/extra_deps.lst"before configure. -
grub.cfg location. The config file lives in the recipe directory (
${COOKBOOK_RECIPE}/grub.cfg), not in the extracted source tarball (${COOKBOOK_SOURCE}/). The copy step usesCOOKBOOK_RECIPE.
Security Considerations
- GRUB configuration is on the ESP (FAT32), which is readable/writable by any OS
- Secure Boot: GRUB standalone images are not signed. Users needing Secure Boot
must sign
BOOTX64.EFIwith their own key or useshim - The chainload target (
EFI/REDBEAR/redbear.efi) is also on the ESP - No credentials or secrets are stored in the GRUB configuration
Limitations
- GRUB cannot read RedoxFS (no module exists)
- Cannot pass kernel parameters directly (chainloading bypasses this)
- BIOS boot is not supported (only UEFI)
- ESP must be sized to ≥ 8 MiB in config (16 MiB recommended)
Testing
Phase 1: Post-build script (standalone)
# Build GRUB recipe
make r.grub
# Build image (any config with efi_partition_size >= 16)
make all CONFIG_NAME=redbear-full
# Install GRUB into disk image (uses fat_tool.py, no mtools needed)
./local/scripts/install-grub.sh build/x86_64/harddrive.img
# Verify ESP contents
python3 local/scripts/fat_tool.py ls build/x86_64/harddrive.img 1048576 /
# Boot in QEMU
make qemu
# Expected: GRUB menu appears, "Red Bear OS" entry boots successfully
Phase 2: Installer-native (automatic)
# Build GRUB recipe (must be built before installer runs)
make r.grub
# Build image with GRUB config (installer fetches GRUB automatically)
make all CONFIG_NAME=redbear-full-grub
# Or via CLI flag
make all CONFIG_NAME=redbear-full INSTALLER_OPTS="--bootloader grub"
# Verify ESP contents
python3 local/scripts/fat_tool.py ls build/x86_64/harddrive.img 1048576 /
# Boot in QEMU
make qemu
# Expected: GRUB menu appears, "Red Bear OS" entry boots successfully
Unit tests (no full build required)
# Verify GRUB recipe builds
CI=1 ./target/release/repo cook grub
# Verify host-side installer accepts --bootloader flag
build/fstools/bin/redox_installer --bootloader=grub --config=config/redbear-full-grub.toml --list-packages
# Verify fat_tool.py operations
python3 local/scripts/fat_tool.py --help
References
- GNU GRUB Manual: https://www.gnu.org/software/grub/manual/grub/grub.html
- GRUB EFI standalone image:
grub-mkimage -O x86_64-efi ... - UEFI boot specification:
EFI/BOOT/BOOTX64.EFIis the fallback boot path - Redox bootloader source:
recipes/core/bootloader/source/ - Installer GPT layout:
recipes/core/installer/source/src/installer.rs