Add Linux-compatible grub-install and grub-mkconfig wrappers

Create grub-install and grub-mkconfig scripts in local/scripts/ that
match GNU GRUB CLI conventions for users migrating from Linux. Support
standard switches: --target, --efi-directory, --bootloader-id,
--removable, -o/--output, --verbose, --help, --version. Unsupported
Linux options are accepted and ignored for script compatibility.

Also fix ESP FAT type: force FAT32 in both with_whole_disk and
with_whole_disk_ext4 (UEFI spec requires FAT32, fatfs auto-selects
FAT16 for partitions under 32 MiB). Fix --write-bootloader to export
GRUB EFI in GRUB mode. Fix CLI example in GRUB plan. Update AGENTS.md
and GRUB-INTEGRATION-PLAN.md with Linux-compatible CLI docs.
This commit is contained in:
2026-04-17 22:47:01 +01:00
parent 7c031f95e4
commit 3bed450071
5 changed files with 496 additions and 21 deletions
+43 -11
View File
@@ -90,7 +90,7 @@ index e3c6700..b1d5d72 100644
"termion",
"uuid",
diff --git a/src/bin/installer.rs b/src/bin/installer.rs
index c3ce487..456efce 100644
index c3ce487..7d3139b 100644
--- a/src/bin/installer.rs
+++ b/src/bin/installer.rs
@@ -20,6 +20,8 @@ Using redox_installer as an installer:
@@ -102,7 +102,18 @@ index c3ce487..456efce 100644
--skip-partition Skip writing GPT partition tables
Use this only if you plan to use other partition tool
--live Use bootloader configured for live disk
@@ -39,6 +41,8 @@ fn main() {
@@ -31,6 +33,10 @@ Using redox_installer as a configuration parser:
--list-packages List packages will be installed
--filesystem-size Output filesystem size in MB
--output-config Path to write the parsed config as another TOML
+
+For GRUB installation with Linux-compatible CLI, use:
+ local/scripts/grub-install --target=x86_64-efi --disk-image=build/x86_64/harddrive.img
+ local/scripts/grub-mkconfig -o local/recipes/core/grub/grub.cfg
"#;
fn main() {
@@ -39,6 +45,8 @@ fn main() {
.add_opt("c", "config")
.add_opt("o", "output-config")
.add_opt("", "write-bootloader")
@@ -111,7 +122,7 @@ index c3ce487..456efce 100644
.add_flag(&["skip-partition"])
.add_flag(&["filesystem-size"])
.add_flag(&["r", "repo-binary"]) // TODO: Remove
@@ -116,6 +120,12 @@ fn main() {
@@ -116,6 +124,12 @@ fn main() {
if parser.found("no-mount") {
config.general.no_mount = Some(true);
}
@@ -180,7 +191,7 @@ index 417ff2d..4ad2202 100644
}
}
diff --git a/src/installer.rs b/src/installer.rs
index 4e077a9..b11d5b8 100644
index 4e077a9..654f6fb 100644
--- a/src/installer.rs
+++ b/src/installer.rs
@@ -3,6 +3,13 @@ use anyhow::{bail, Result};
@@ -569,7 +580,23 @@ index 4e077a9..b11d5b8 100644
}
//TODO: make bootloaders use Option, dynamically create BIOS and EFI partitions
@@ -683,20 +970,58 @@ where
@@ -672,10 +959,13 @@ where
fscommon::StreamSlice::new(&mut disk_file, disk_efi_start, disk_efi_end)?;
eprintln!(
- "Formatting EFI partition with size {:#x}",
+ "Formatting EFI partition as FAT32 (size {:#x})",
disk_efi_end - disk_efi_start
);
- fatfs::format_volume(&mut disk_efi, fatfs::FormatVolumeOptions::new())?;
+ fatfs::format_volume(
+ &mut disk_efi,
+ fatfs::FormatVolumeOptions::new().fat_type(fatfs::FatType::Fat32),
+ )?;
eprintln!("Opening EFI partition");
let fs = fatfs::FileSystem::new(&mut disk_efi, fatfs::FsOptions::new())?;
@@ -683,20 +973,58 @@ where
eprintln!("Creating EFI directory");
let root_dir = fs.root_dir();
root_dir.create_dir("EFI")?;
@@ -640,7 +667,7 @@ index 4e077a9..b11d5b8 100644
}
// Format and install RedoxFS partition
@@ -712,6 +1037,222 @@ where
@@ -712,6 +1040,225 @@ where
with_redoxfs(disk_redoxfs, disk_option.password_opt, callback)
}
@@ -778,10 +805,13 @@ index 4e077a9..b11d5b8 100644
+ fscommon::StreamSlice::new(&mut disk_file, disk_efi_start, disk_efi_end)?;
+
+ eprintln!(
+ "Formatting EFI partition with size {:#x}",
+ "Formatting EFI partition as FAT32 (size {:#x})",
+ disk_efi_end - disk_efi_start
+ );
+ fatfs::format_volume(&mut disk_efi, fatfs::FormatVolumeOptions::new())?;
+ fatfs::format_volume(
+ &mut disk_efi,
+ fatfs::FormatVolumeOptions::new().fat_type(fatfs::FatType::Fat32),
+ )?;
+
+ eprintln!("Opening EFI partition");
+ let fs = fatfs::FileSystem::new(&mut disk_efi, fatfs::FsOptions::new())?;
@@ -863,7 +893,7 @@ index 4e077a9..b11d5b8 100644
#[cfg(not(target_os = "redox"))]
pub fn try_fast_install<D: redoxfs::Disk, F: FnMut(u64, u64)>(
_fs: &mut redoxfs::FileSystem<D>,
@@ -801,6 +1342,24 @@ pub fn try_fast_install<D: redoxfs::Disk, F: FnMut(u64, u64)>(
@@ -801,6 +1348,24 @@ pub fn try_fast_install<D: redoxfs::Disk, F: FnMut(u64, u64)>(
fn install_inner(config: Config, output: &Path) -> Result<()> {
println!("Installing to {}:\n{}", output.display(), config);
@@ -888,7 +918,7 @@ index 4e077a9..b11d5b8 100644
let cookbook = config.general.cookbook.clone();
let cookbook = cookbook.as_ref().map(|p| p.as_str());
if output.is_dir() {
@@ -823,28 +1382,41 @@ fn install_inner(config: Config, output: &Path) -> Result<()> {
@@ -823,28 +1388,42 @@ fn install_inner(config: Config, output: &Path) -> Result<()> {
let live = config.general.live_disk.unwrap_or(false);
let password_opt = config.general.encrypt_disk.clone();
let password_opt = password_opt.as_ref().map(|p| p.as_bytes());
@@ -896,7 +926,9 @@ index 4e077a9..b11d5b8 100644
+ let (bootloader_bios, bootloader_efi, grub_efi, grub_cfg) =
+ fetch_bootloaders(&config, cookbook, live)?;
if let Some(write_bootloader) = &config.general.write_bootloader {
std::fs::write(write_bootloader, &bootloader_efi)?;
- std::fs::write(write_bootloader, &bootloader_efi)?;
+ let primary_efi = grub_efi.as_deref().unwrap_or(&bootloader_efi);
+ std::fs::write(write_bootloader, primary_efi)?;
}
+ let filesystem_type = match config.general.filesystem.as_deref() {
+ Some("ext4") => FilesystemType::Ext4,