Skip to content

Commit b79a009

Browse files
committed
Copy firmware blobs to boot/efi to ensure that the aarch64
system finds the required files to boot
1 parent 5051140 commit b79a009

File tree

1 file changed

+98
-3
lines changed

1 file changed

+98
-3
lines changed

src/efi.rs

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,39 @@ impl Efi {
162162
clear_efi_target(&product_name)?;
163163
create_efi_boot_entry(device, espdir, vendordir, &product_name)
164164
}
165+
166+
/// Copy firmware files from /boot/efi to target directory
167+
fn copy_firmware_blobs(&self, src_root: &openat::Dir, dest_root: &str) -> Result<()> {
168+
let src_efi = "boot/efi";
169+
170+
// Always create destination directory structure
171+
let dest_path = Path::new(dest_root).join("boot/efi");
172+
std::fs::create_dir_all(&dest_path)?;
173+
174+
// Skip if source doesn't exist
175+
if !src_root.exists(src_efi)? {
176+
log::debug!("No EFI directory found at {}", src_efi);
177+
return Ok(());
178+
}
179+
180+
// Open destination directory
181+
let dest_dir = openat::Dir::open(Path::new(dest_root))?;
182+
183+
// Copy all files from source
184+
for entry in src_root.list_dir(src_efi)? {
185+
let entry = entry?;
186+
if let Some(openat::SimpleType::File) = entry.simple_type() {
187+
let src_path = Path::new(src_efi).join(entry.file_name());
188+
let dest_path = Path::new("boot/efi").join(entry.file_name());
189+
src_root
190+
.copy_file_at(&src_path, &dest_dir, &dest_path)
191+
.with_context(|| format!("Failed to copy {:?} to {:?}", src_path, dest_path))?;
192+
log::debug!("Copied firmware file: {:?} to {:?}", src_path, dest_path);
193+
}
194+
}
195+
196+
Ok(())
197+
}
165198
}
166199

167200
#[context("Get product name")]
@@ -304,13 +337,16 @@ impl Component for Efi {
304337
let srcdir_name = component_updatedirname(self);
305338
let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?;
306339
let destdir = &self.ensure_mounted_esp(Path::new(dest_root))?;
307-
308340
let destd = &openat::Dir::open(destdir)
309341
.with_context(|| format!("opening dest dir {}", destdir.display()))?;
310342
validate_esp(destd)?;
311343

312344
// TODO - add some sort of API that allows directly setting the working
313345
// directory to a file descriptor.
346+
347+
// Copy firmware files
348+
self.copy_firmware_blobs(src_root, dest_root)?;
349+
314350
std::process::Command::new("cp")
315351
.args(["-rp", "--reflink=auto"])
316352
.arg(&srcdir_name)
@@ -579,9 +615,8 @@ fn find_file_recursive<P: AsRef<Path>>(dir: P, target_file: &str) -> Result<Vec<
579615

580616
#[cfg(test)]
581617
mod tests {
582-
use cap_std_ext::dirext::CapStdExtDirExt;
583-
584618
use super::*;
619+
use cap_std_ext::dirext::CapStdExtDirExt;
585620

586621
#[test]
587622
fn test_parse_boot_entries() -> Result<()> {
@@ -697,4 +732,64 @@ Boot0003* test";
697732
}
698733
Ok(())
699734
}
735+
#[test]
736+
fn test_copy_firmware_blobs() -> Result<()> {
737+
// Setup temp directory structure
738+
let tmpd = tempfile::tempdir()?;
739+
let tmp_path = tmpd.path();
740+
741+
// Create source structure
742+
std::fs::create_dir_all(tmp_path.join("boot/efi"))?;
743+
std::fs::write(tmp_path.join("boot/efi/fwfile1.bin"), "test1")?;
744+
std::fs::write(tmp_path.join("boot/efi/fwfile2.bin"), "test2")?;
745+
746+
// Destination directory
747+
let dest_tmpd = tempfile::tempdir()?;
748+
let dest_path = dest_tmpd.path();
749+
750+
// Test the copy
751+
let efi = Efi::default();
752+
let src_dir = openat::Dir::open(tmp_path)?;
753+
efi.copy_firmware_blobs(&src_dir, dest_path.to_str().unwrap())?;
754+
755+
// Verify files were copied
756+
assert!(dest_path.join("boot/efi/fwfile1.bin").exists());
757+
assert!(dest_path.join("boot/efi/fwfile2.bin").exists());
758+
759+
// Verify contents
760+
assert_eq!(
761+
std::fs::read_to_string(dest_path.join("boot/efi/fwfile1.bin"))?,
762+
"test1"
763+
);
764+
assert_eq!(
765+
std::fs::read_to_string(dest_path.join("boot/efi/fwfile2.bin"))?,
766+
"test2"
767+
);
768+
769+
Ok(())
770+
}
771+
772+
#[test]
773+
fn test_copy_firmware_blobs_empty() -> Result<()> {
774+
// Source directory (empty)
775+
let tmpd = tempfile::tempdir()?;
776+
let tmp_path = tmpd.path();
777+
778+
// Destination directory
779+
let dest_tmpd = tempfile::tempdir()?;
780+
let dest_path = dest_tmpd.path();
781+
782+
// Test the copy
783+
let efi = Efi::default();
784+
let src_dir = openat::Dir::open(tmp_path)?;
785+
efi.copy_firmware_blobs(&src_dir, dest_path.to_str().unwrap())?;
786+
787+
// Verify directory was created
788+
assert!(dest_path.join("boot/efi").exists());
789+
790+
// Verify directory is empty
791+
assert!(dest_path.join("boot/efi").read_dir()?.next().is_none());
792+
793+
Ok(())
794+
}
700795
}

0 commit comments

Comments
 (0)