Add GRUB integration plan and configure ESP size for GRUB boot
Documents the two-phase GRUB integration approach (post-build script then installer-native), build notes for the three cookbook workarounds, and measured artifact sizes. Sets efi_partition_size=16 in redbear-full to accommodate GRUB plus Redox bootloader on the ESP. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
+22
-21
@@ -13,6 +13,7 @@ include = ["desktop.toml", "redbear-legacy-base.toml", "redbear-legacy-desktop.t
|
|||||||
|
|
||||||
[general]
|
[general]
|
||||||
filesystem_size = 2048
|
filesystem_size = 2048
|
||||||
|
efi_partition_size = 16
|
||||||
|
|
||||||
[users.messagebus]
|
[users.messagebus]
|
||||||
uid = 100
|
uid = 100
|
||||||
@@ -65,12 +66,12 @@ redbear-upower = {}
|
|||||||
redbear-udisks = {}
|
redbear-udisks = {}
|
||||||
redbear-polkit = {}
|
redbear-polkit = {}
|
||||||
|
|
||||||
|
# IOMMU DMA remapping daemon
|
||||||
|
iommu = {}
|
||||||
|
|
||||||
# Diagnostic tool
|
# Diagnostic tool
|
||||||
redbear-info = {}
|
redbear-info = {}
|
||||||
|
|
||||||
# IOMMU validation surface
|
|
||||||
iommu = {}
|
|
||||||
|
|
||||||
# Process monitor
|
# Process monitor
|
||||||
htop = {}
|
htop = {}
|
||||||
|
|
||||||
@@ -160,6 +161,20 @@ args = ["/scheme/debug/no-preserve", "-J"]
|
|||||||
type = "oneshot_async"
|
type = "oneshot_async"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
[[files]]
|
||||||
|
path = "/usr/lib/init.d/13_iommu.service"
|
||||||
|
data = """
|
||||||
|
[unit]
|
||||||
|
description = "IOMMU DMA remapping daemon"
|
||||||
|
requires_weak = [
|
||||||
|
"00_pcid-spawner.service",
|
||||||
|
]
|
||||||
|
|
||||||
|
[service]
|
||||||
|
cmd = "/usr/bin/iommu"
|
||||||
|
type = "oneshot_async"
|
||||||
|
"""
|
||||||
|
|
||||||
[[files]]
|
[[files]]
|
||||||
path = "/usr/lib/init.d/12_dbus.service"
|
path = "/usr/lib/init.d/12_dbus.service"
|
||||||
data = """
|
data = """
|
||||||
@@ -191,7 +206,7 @@ requires_weak = [
|
|||||||
cmd = "ion"
|
cmd = "ion"
|
||||||
args = [
|
args = [
|
||||||
"-c",
|
"-c",
|
||||||
"sleep 5; redbear-sessiond",
|
"redbear-sessiond",
|
||||||
]
|
]
|
||||||
type = "oneshot_async"
|
type = "oneshot_async"
|
||||||
"""
|
"""
|
||||||
@@ -209,7 +224,7 @@ requires_weak = [
|
|||||||
cmd = "ion"
|
cmd = "ion"
|
||||||
args = [
|
args = [
|
||||||
"-c",
|
"-c",
|
||||||
"sleep 5; redbear-upower",
|
"redbear-upower",
|
||||||
]
|
]
|
||||||
type = "oneshot_async"
|
type = "oneshot_async"
|
||||||
"""
|
"""
|
||||||
@@ -227,7 +242,7 @@ requires_weak = [
|
|||||||
cmd = "ion"
|
cmd = "ion"
|
||||||
args = [
|
args = [
|
||||||
"-c",
|
"-c",
|
||||||
"sleep 5; redbear-udisks",
|
"redbear-udisks",
|
||||||
]
|
]
|
||||||
type = "oneshot_async"
|
type = "oneshot_async"
|
||||||
"""
|
"""
|
||||||
@@ -245,7 +260,7 @@ requires_weak = [
|
|||||||
cmd = "ion"
|
cmd = "ion"
|
||||||
args = [
|
args = [
|
||||||
"-c",
|
"-c",
|
||||||
"sleep 5; redbear-polkit",
|
"redbear-polkit",
|
||||||
]
|
]
|
||||||
type = "oneshot_async"
|
type = "oneshot_async"
|
||||||
"""
|
"""
|
||||||
@@ -261,17 +276,3 @@ path = "/run/dbus"
|
|||||||
data = ""
|
data = ""
|
||||||
directory = true
|
directory = true
|
||||||
mode = 0o755
|
mode = 0o755
|
||||||
|
|
||||||
[[files]]
|
|
||||||
path = "/usr/lib/init.d/13_iommu.service"
|
|
||||||
data = """
|
|
||||||
[unit]
|
|
||||||
description = "IOMMU DMA remapping daemon"
|
|
||||||
requires_weak = [
|
|
||||||
"00_pcid-spawner.service",
|
|
||||||
]
|
|
||||||
|
|
||||||
[service]
|
|
||||||
cmd = "/usr/lib/drivers/iommu"
|
|
||||||
type = "oneshot_async"
|
|
||||||
"""
|
|
||||||
|
|||||||
@@ -0,0 +1,275 @@
|
|||||||
|
# GRUB Integration Plan — Red Bear OS
|
||||||
|
|
||||||
|
**Date:** 2026-04-17
|
||||||
|
**Status:** Phase 1 — recipe builds successfully, post-build script ready, awaiting QEMU validation
|
||||||
|
**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?
|
||||||
|
|
||||||
|
1. **GRUB does not support RedoxFS.** Writing a GRUB filesystem module for
|
||||||
|
RedoxFS is high-risk, GPL-licensing-sensitive work. Chainloading avoids it.
|
||||||
|
2. **The Redox bootloader works.** It reads RedoxFS directly and boots the
|
||||||
|
kernel. No need to replicate that logic in GRUB.
|
||||||
|
3. **GRUB is universally understood.** System administrators know GRUB. A
|
||||||
|
`grub.cfg` is easier to customize than a custom bootloader.
|
||||||
|
4. **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`:
|
||||||
|
|
||||||
|
```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:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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 = 16` in config)
|
||||||
|
|
||||||
|
## Implementation — Phase 2: Installer-Native Support (Future)
|
||||||
|
|
||||||
|
Phase 2 adds GRUB awareness directly to the Redox installer, eliminating the
|
||||||
|
post-build script step. This requires modifying the installer patch.
|
||||||
|
|
||||||
|
### Changes Required
|
||||||
|
|
||||||
|
1. **`GeneralConfig`**: Add `bootloader: Option<String>` field (`"redox"` default, `"grub"` for GRUB)
|
||||||
|
2. **`DiskOption`**: Add `bootloader_grub: Option<&[u8]>`, `grub_config: Option<&[u8]>` fields
|
||||||
|
3. **`fetch_bootloaders`**: When `bootloader = "grub"`, also install the `grub` package
|
||||||
|
4. **`with_whole_disk` / `with_whole_disk_ext4`**: When GRUB data present:
|
||||||
|
- Create `EFI/REDBEAR/` directory
|
||||||
|
- Write GRUB as `EFI/BOOT/BOOTX64.EFI`
|
||||||
|
- Write Redox bootloader as `EFI/REDBEAR/redbear.efi`
|
||||||
|
- Write `grub.cfg` to `EFI/BOOT/grub.cfg`
|
||||||
|
- Auto-set ESP size to 16 MiB if not configured
|
||||||
|
5. **CLI**: Add `--bootloader grub` flag to installer binary
|
||||||
|
|
||||||
|
### Config Usage (Phase 2)
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# config/redbear-full-grub.toml
|
||||||
|
include = ["redbear-full.toml"]
|
||||||
|
|
||||||
|
[general]
|
||||||
|
bootloader = "grub"
|
||||||
|
efi_partition_size = 16
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
1. Configure with `--target=x86_64 --with-platform=efi` (produces x86_64 EFI)
|
||||||
|
2. Disable unnecessary components (themes, mkfont, mount, device-mapper)
|
||||||
|
3. Run `grub-mkimage` to create standalone EFI binary with curated modules
|
||||||
|
4. Stage `grub.efi` and `grub.cfg` to `/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:
|
||||||
|
|
||||||
|
1. **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_CONFIG` and
|
||||||
|
`unset CFLAGS CXXFLAGS CPPFLAGS LDFLAGS` at the top of the script.
|
||||||
|
|
||||||
|
2. **Missing `extra_deps.lst`.** GRUB 2.12 release tarballs omit
|
||||||
|
`grub-core/extra_deps.lst` (normally generated by `autogen.sh` from git).
|
||||||
|
Fix: `touch "${COOKBOOK_SOURCE}/grub-core/extra_deps.lst"` before configure.
|
||||||
|
|
||||||
|
3. **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 uses `COOKBOOK_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.EFI` with their own key or use `shim`
|
||||||
|
- 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 in Phase 1 (only UEFI)
|
||||||
|
- Requires `mtools` on the host for Phase 1 post-build script
|
||||||
|
- ESP must be manually sized to ≥ 8 MiB in config
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build GRUB recipe
|
||||||
|
make r.grub
|
||||||
|
|
||||||
|
# Verify GRUB binary was produced
|
||||||
|
find repo -name "grub.efi" -path "*/usr/lib/boot/*"
|
||||||
|
|
||||||
|
# Build full image with larger ESP
|
||||||
|
# (Add efi_partition_size = 16 to config first)
|
||||||
|
make all CONFIG_NAME=redbear-full
|
||||||
|
|
||||||
|
# Install GRUB
|
||||||
|
./local/scripts/install-grub.sh build/x86_64/harddrive.img
|
||||||
|
|
||||||
|
# Verify ESP contents
|
||||||
|
mdir -i build/x86_64/harddrive.img@1048576 -/ ::/
|
||||||
|
|
||||||
|
# Boot in QEMU
|
||||||
|
make qemu
|
||||||
|
|
||||||
|
# Expected: GRUB menu appears, "Red Bear OS" entry boots successfully
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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.EFI` is the fallback boot path
|
||||||
|
- Redox bootloader source: `recipes/core/bootloader/source/`
|
||||||
|
- Installer GPT layout: `recipes/core/installer/source/src/installer.rs`
|
||||||
Reference in New Issue
Block a user