Skip to content

Commit fd2e9df

Browse files
committed
fix(autoconfigure): detect kernel and initramfs case-insensitive, even at the root
1 parent f49bbed commit fd2e9df

File tree

5 files changed

+35
-15
lines changed

5 files changed

+35
-15
lines changed

hack/dev/boot/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -
77
WORKDIR /work
88
COPY sprout.efi /work/${EFI_NAME}.EFI
99
COPY sprout.toml /work/SPROUT.TOML
10-
COPY kernel.efi /work/KERNEL.EFI
10+
COPY kernel.efi /work/VMLINUZ
1111
COPY shell.efi /work/SHELL.EFI
1212
COPY xen.efi /work/XEN.EFI
1313
COPY xen.cfg /work/XEN.CFG
@@ -24,7 +24,7 @@ RUN truncate -s128MiB sprout.img && \
2424
mmd -i sprout.img ::/LOADER && \
2525
mmd -i sprout.img ::/LOADER/ENTRIES && \
2626
mcopy -i sprout.img ${EFI_NAME}.EFI ::/EFI/BOOT/ && \
27-
mcopy -i sprout.img KERNEL.EFI ::/EFI/BOOT/ && \
27+
mcopy -i sprout.img VMLINUZ ::/VMLINUZ && \
2828
mcopy -i sprout.img SHELL.EFI ::/EFI/BOOT/ && \
2929
mcopy -i sprout.img XEN.EFI ::/EFI/BOOT/ && \
3030
mcopy -i sprout.img XEN.CFG ::/EFI/BOOT/ && \

hack/dev/configs/all.sprout.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ version = 1
44
default-entry = "kernel"
55

66
[extractors.boot.filesystem-device-match]
7-
has-item = "\\EFI\\BOOT\\kernel.efi"
7+
has-item = "\\vmlinuz"
88

99
[actions.chainload-kernel]
10-
chainload.path = "$boot\\EFI\\BOOT\\kernel.efi"
10+
chainload.path = "$boot\\vmlinuz"
1111
chainload.options = ["console=hvc0"]
1212
chainload.linux-initrd = "$boot\\initramfs"
1313

hack/dev/configs/bls.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
title Boot Linux
2-
linux /efi/boot/kernel.efi
2+
linux /vmlinuz
33
options console=hvc0
44
initrd /initramfs

hack/dev/configs/kernel.sprout.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ default-entry = "kernel"
55
menu-timeout = 0
66

77
[extractors.boot.filesystem-device-match]
8-
has-item = "\\EFI\\BOOT\\kernel.efi"
8+
has-item = "\\vmlinuz"
99

1010
[actions.chainload-kernel]
11-
chainload.path = "$boot\\EFI\\BOOT\\kernel.efi"
11+
chainload.path = "$boot\\vmlinuz"
1212
chainload.options = ["console=hvc0"]
1313
chainload.linux-initrd = "$boot\\initramfs"
1414

src/autoconfigure/linux.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use crate::generators::GeneratorDeclaration;
66
use crate::generators::list::ListConfiguration;
77
use crate::utils;
88
use anyhow::{Context, Result};
9+
use log::info;
910
use std::collections::BTreeMap;
1011
use uefi::CString16;
11-
use uefi::fs::{FileSystem, Path};
12+
use uefi::fs::{FileSystem, Path, PathBuf};
1213
use uefi::proto::device_path::DevicePath;
1314
use uefi::proto::device_path::text::{AllowShortcuts, DisplayOnly};
1415

@@ -17,7 +18,8 @@ const LINUX_CHAINLOAD_ACTION_PREFIX: &str = "linux-chainload-";
1718

1819
/// The locations to scan for kernel pairs.
1920
/// We will check for symlinks and if this directory is a symlink, we will skip it.
20-
const SCAN_LOCATIONS: &[&str] = &["/boot", "/"];
21+
/// The empty string represents the root of the filesystem.
22+
const SCAN_LOCATIONS: &[&str] = &["\\boot", "\\"];
2123

2224
/// Prefixes of kernel files to scan for.
2325
const KERNEL_PREFIXES: &[&str] = &["vmlinuz"];
@@ -39,6 +41,9 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
3941
// All the discovered kernel pairs.
4042
let mut pairs = Vec::new();
4143

44+
// We have to special-case the root directory due to path logic in the uefi crate.
45+
let is_root = path.is_empty() || path == "\\";
46+
4247
// Construct a filesystem path from the path string.
4348
let path = CString16::try_from(path).context("unable to convert path to CString16")?;
4449
let path = Path::new(&path);
@@ -62,6 +67,16 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
6267
return Ok(pairs);
6368
};
6469

70+
// Create a new path used for joining file names below.
71+
// All attempts to derive paths for the files in the directory should use this instead.
72+
// The uefi crate does not handle push correctly for the root directory.
73+
// It will add a second slash, which will cause our path logic to fail.
74+
let path_for_join = if is_root {
75+
PathBuf::new()
76+
} else {
77+
path.clone()
78+
};
79+
6580
// For each item in the directory, find a kernel.
6681
for item in directory {
6782
let item = item.context("unable to read directory item")?;
@@ -74,11 +89,14 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
7489
// Convert the name from a CString16 to a String.
7590
let name = item.file_name().to_string();
7691

92+
// Convert the name to lowercase to make all of this case-insensitive.
93+
let name_for_match = name.to_lowercase();
94+
7795
// Find a kernel prefix that matches, if any.
78-
let Some(prefix) = KERNEL_PREFIXES
79-
.iter()
80-
.find(|prefix| name == **prefix || name.starts_with(&format!("{}-", prefix)))
81-
else {
96+
// This is case-insensitive to ensure we pick up all possibilities.
97+
let Some(prefix) = KERNEL_PREFIXES.iter().find(|prefix| {
98+
name_for_match == **prefix || name_for_match.starts_with(&format!("{}-", prefix))
99+
}) else {
82100
// Skip over anything that doesn't match a kernel prefix.
83101
continue;
84102
};
@@ -96,8 +114,10 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
96114
let initramfs = format!("{}{}", prefix, suffix);
97115
let initramfs = CString16::try_from(initramfs.as_str())
98116
.context("unable to convert initramfs name to CString16")?;
99-
let mut initramfs_path = path.clone();
117+
let mut initramfs_path = path_for_join.clone();
100118
initramfs_path.push(Path::new(&initramfs));
119+
120+
info!("initramfs path: {:?} ({})", initramfs_path, initramfs);
101121
// Check if the initramfs path exists, if it does, break out of the loop.
102122
if filesystem
103123
.try_exists(&initramfs_path)
@@ -108,7 +128,7 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
108128
};
109129

110130
// Construct a kernel path from the kernel name.
111-
let mut kernel = path.clone();
131+
let mut kernel = path_for_join.clone();
112132
kernel.push(Path::new(&item.file_name()));
113133
let kernel = kernel.to_string();
114134
let initramfs = matched_initramfs_path.map(|initramfs_path| initramfs_path.to_string());

0 commit comments

Comments
 (0)