Integrate Red Bear boot and packaging updates

This commit is contained in:
2026-04-22 10:22:09 +01:00
parent dd68c4ba03
commit b5ae8b2760
77 changed files with 259225 additions and 16971 deletions
@@ -0,0 +1,97 @@
diff --git a/src/main.rs b/src/main.rs
index b2e2736..a6a9474 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -500,33 +500,62 @@ pub extern "C" fn main() -> ! {
print!("live: 0/{} MiB", size / MIBI as u64);
- let ptr = os.alloc_zeroed_page_aligned(size as usize);
- if ptr.is_null() {
- panic!("Failed to allocate memory for live");
- }
-
- let live = unsafe { slice::from_raw_parts_mut(ptr, size as usize) };
-
- let mut i = 0;
- for chunk in live.chunks_mut(MIBI) {
- print!("\rlive: {}/{} MiB", i / MIBI as u64, size / MIBI as u64);
- i += unsafe {
- fs.disk
- .read_at(fs.block + i / redoxfs::BLOCK_SIZE, chunk)
- .expect("Failed to read live disk") as u64
- };
- }
- println!("\rlive: {}/{} MiB", i / MIBI as u64, size / MIBI as u64);
-
- println!("Switching to live disk");
- unsafe {
- LIVE_OPT = Some((fs.block, slice::from_raw_parts_mut(ptr, size as usize)));
- }
+ let live_size = match usize::try_from(size) {
+ Ok(live_size) => live_size,
+ Err(_) => {
+ println!("\rlive: disabled (image too large for bootloader address space)");
+ live = false;
+ 0
+ }
+ };
- area_add(OsMemoryEntry {
- base: live.as_ptr() as u64,
- size: live.len() as u64,
- kind: OsMemoryKind::Reserved,
- });
+ let ptr = if live {
+ os.alloc_zeroed_page_aligned(live_size)
+ } else {
+ ptr::null_mut()
+ };
+
+ if live && ptr.is_null() {
+ println!(
+ "\rlive: disabled (unable to allocate {} MiB upfront)",
+ size / MIBI as u64
+ );
+ live = false;
+ }
+
+ let live = if live {
+ Some(unsafe { slice::from_raw_parts_mut(ptr, live_size) })
+ } else {
+ println!("Continuing without live preload");
+ None
+ };
+
+ if let Some(live) = live {
+ let mut i = 0;
+ for chunk in live.chunks_mut(MIBI) {
+ print!("\rlive: {}/{} MiB", i / MIBI as u64, size / MIBI as u64);
+ i += unsafe {
+ fs.disk
+ .read_at(fs.block + i / redoxfs::BLOCK_SIZE, chunk)
+ .expect("Failed to read live disk") as u64
+ };
+ }
+ println!("\rlive: {}/{} MiB", i / MIBI as u64, size / MIBI as u64);
+
+ println!("Switching to live disk");
+ unsafe {
+ LIVE_OPT = Some((fs.block, slice::from_raw_parts_mut(ptr, live_size)));
+ }
+
+ area_add(OsMemoryEntry {
+ base: live.as_ptr() as u64,
+ size: live.len() as u64,
+ kind: OsMemoryKind::Reserved,
+ });
+
+ Some(live)
+ } else {
+ None
+ }
-
- Some(live)
} else {
None
};
@@ -0,0 +1,60 @@
diff --git a/src/os/uefi/device.rs b/src/os/uefi/device.rs
index 4b0bf31..90a97b8 100644
--- a/src/os/uefi/device.rs
+++ b/src/os/uefi/device.rs
@@ -46,6 +46,8 @@ fn device_path_relation(a_path: &DevicePath, b_path: &DevicePath) -> DevicePath
}
fn esp_live_image(esp_handle: Handle, esp_device_path: &DevicePath) -> Option<Vec<u8>> {
+ const MAX_LIVE_IMAGE_PRELOAD: usize = 128 * 1024 * 1024;
+
let mut esp_fs = match FileSystem::handle_protocol(esp_handle) {
Ok(esp_fs) => esp_fs,
Err(err) => {
@@ -87,9 +89,37 @@ fn esp_live_image(esp_handle: Handle, esp_device_path: &DevicePath) -> Option<V
};
let mut buffer = Vec::new();
+ let mut chunk = [0_u8; 64 * 1024];
+
+ loop {
+ let read = match live_image.read(&mut chunk) {
+ Ok(read) => read,
+ Err(err) => {
+ log::warn!(
+ "Failed while reading {}\\redox-live.iso: {:?}",
+ device_path_to_string(esp_device_path),
+ err
+ );
+ return None;
+ }
+ };
+
+ if read == 0 {
+ break;
+ }
- live_image.read_to_end(&mut buffer).unwrap();
+ if buffer.len().saturating_add(read) > MAX_LIVE_IMAGE_PRELOAD {
+ log::warn!(
+ "Skipping {}\\redox-live.iso preload: file exceeds {} MiB safety limit",
+ device_path_to_string(esp_device_path),
+ MAX_LIVE_IMAGE_PRELOAD / 1024 / 1024
+ );
+ return None;
+ }
+
+ buffer.extend_from_slice(&chunk[..read]);
+ }
Some(buffer)
}
@@ -130,7 +160,7 @@ pub fn disk_device_priority() -> Vec<DiskDevice> {
return vec![DiskDevice {
handle: esp_handle,
// Support both a copy of livedisk.iso and a standalone redoxfs partition
- partition_offset: if &buffer[512..520] == b"EFI PART" {
+ partition_offset: if buffer.len() >= 520 && &buffer[512..520] == b"EFI PART" {
//TODO: get block from partition table
2 * crate::MIBI as u64
} else {