Files
RedBear-OS/local/patches/bootloader/absorbed/P4-live-large-iso-boot.patch
vasilito 9f4ad484a4 fix: consolidate bootloader patches
Absorb P1-P4 bootloader patches into P5 carrier. Move absorbed
patches to local/patches/bootloader/absorbed/ for reference.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-11 10:08:39 +01:00

216 lines
7.3 KiB
Diff

--- a/src/arch/x86/mod.rs
+++ b/src/arch/x86/mod.rs
@@ -3,10 +3,15 @@
pub(crate) mod x32;
pub(crate) mod x64;
-pub unsafe fn paging_create(os: &impl Os, kernel_phys: u64, kernel_size: u64) -> Option<usize> {
+pub unsafe fn paging_create(
+ os: &impl Os,
+ kernel_phys: u64,
+ kernel_size: u64,
+ identity_map_end: u64,
+) -> Option<usize> {
unsafe {
if crate::KERNEL_64BIT {
- x64::paging_create(os, kernel_phys, kernel_size)
+ x64::paging_create(os, kernel_phys, kernel_size, identity_map_end)
} else {
x32::paging_create(os, kernel_phys, kernel_size)
}
--- a/src/arch/x86/x64.rs
+++ b/src/arch/x86/x64.rs
@@ -29,7 +29,12 @@
const WRITABLE: u64 = 1 << 1;
const LARGE: u64 = 1 << 7;
-pub unsafe fn paging_create(os: &impl Os, kernel_phys: u64, kernel_size: u64) -> Option<usize> {
+pub unsafe fn paging_create(
+ os: &impl Os,
+ kernel_phys: u64,
+ kernel_size: u64,
+ identity_map_end: u64,
+) -> Option<usize> {
unsafe {
// Create PML4
let pml4 = paging_allocate(os)?;
@@ -42,8 +47,14 @@
pml4[0] = pdp.as_ptr() as u64 | WRITABLE | PRESENT;
pml4[256] = pdp.as_ptr() as u64 | WRITABLE | PRESENT;
- // Identity map 8 GiB using 2 MiB pages
- for pdp_i in 0..8 {
+ let mut needed_pdp = identity_map_end.div_ceil(0x4000_0000);
+ if needed_pdp == 0 {
+ needed_pdp = 1;
+ }
+ assert!(needed_pdp <= pdp.len() as u64, "identity map end exceeds paging span");
+
+ // Identity map required physical range using 2 MiB pages
+ for pdp_i in 0..needed_pdp as usize {
let pd = paging_allocate(os)?;
pdp[pdp_i] = pd.as_ptr() as u64 | WRITABLE | PRESENT;
for pd_i in 0..pd.len() {
--- a/src/main.rs
+++ b/src/main.rs
@@ -641,15 +641,34 @@
(memory.len() as u64, memory.as_mut_ptr() as u64)
};
- let page_phys = unsafe { paging_create(os, kernel.as_ptr() as u64, kernel.len() as u64) }
- .expect("Failed to set up paging");
-
let max_env_size = 64 * KIBI;
let mut env_size = max_env_size;
let env_base = os.alloc_zeroed_page_aligned(env_size);
if env_base.is_null() {
panic!("Failed to allocate memory for stack");
}
+
+ let mut identity_map_end = region_end(kernel.as_ptr() as u64, kernel.len() as u64)
+ .max(region_end(stack_base as u64, stack_size as u64))
+ .max(region_end(bootstrap_base, bootstrap_size))
+ .max(region_end(env_base as u64, max_env_size as u64));
+
+ if let Some(ref live) = live_opt {
+ identity_map_end = identity_map_end.max(region_end(
+ live.as_ptr() as u64,
+ live.len() as u64,
+ ));
+ }
+
+ let page_phys = unsafe {
+ paging_create(
+ os,
+ kernel.as_ptr() as u64,
+ kernel.len() as u64,
+ identity_map_end,
+ )
+ }
+ .expect("Failed to set up paging");
{
let mut w = SliceWriter {
--- a/src/os/uefi/device.rs
+++ b/src/os/uefi/device.rs
@@ -26,19 +26,10 @@
}
let mut header_buf = [0u8; 512];
- let lba1_block = block_size / redoxfs::BLOCK_SIZE;
- let header_read_len = if 512 <= redoxfs::BLOCK_SIZE as usize {
- redoxfs::BLOCK_SIZE as usize
- } else {
- 512
- };
- let mut read_buf = vec![0u8; header_read_len];
- if unsafe { disk.read_at(lba1_block, &mut read_buf) }.is_err() {
+ if disk.read_bytes(block_size, &mut header_buf).is_err() {
log::warn!("GPT: failed to read LBA 1");
return 2 * crate::MIBI as u64;
}
- let copy_len = 512.min(read_buf.len());
- header_buf[..copy_len].copy_from_slice(&read_buf[..copy_len]);
if &header_buf[0..8] != b"EFI PART" {
log::warn!("GPT: no valid signature at LBA 1");
@@ -64,19 +55,15 @@
}
let entries_byte_offset = partition_entry_start_lba * block_size;
- let entries_start_block = entries_byte_offset / redoxfs::BLOCK_SIZE;
let total_entries_bytes = num_entries as usize * entry_size as usize;
- let read_size = total_entries_bytes.min(4096);
- let mut entries_buf = vec![0u8; read_size + redoxfs::BLOCK_SIZE as usize];
- let entries_read_blocks = (read_size as u64).div_ceil(redoxfs::BLOCK_SIZE) as usize;
- if unsafe { disk.read_at(entries_start_block, &mut entries_buf[..entries_read_blocks * redoxfs::BLOCK_SIZE as usize]) }.is_err() {
+ let mut entries_buf = vec![0u8; total_entries_bytes];
+ if disk.read_bytes(entries_byte_offset, &mut entries_buf).is_err() {
log::warn!("GPT: failed to read partition entries");
return 2 * crate::MIBI as u64;
}
- let entries_per_chunk = read_size / entry_size as usize;
- for i in 0..entries_per_chunk.min(num_entries as usize) {
+ for i in 0..num_entries as usize {
let off = i * entry_size as usize;
if off + entry_size as usize > entries_buf.len() {
break;
--- a/src/os/uefi/disk.rs
+++ b/src/os/uefi/disk.rs
@@ -117,3 +117,43 @@
Err(Error::new(EIO))
}
}
+
+impl DiskEfi {
+ pub fn media_block_size(&self) -> usize {
+ self.0.Media.BlockSize as usize
+ }
+
+ pub fn read_bytes(&mut self, offset: u64, buffer: &mut [u8]) -> Result<()> {
+ let block_size = self.media_block_size();
+ if block_size == 0 || block_size > self.1.len() {
+ return Err(Error::new(EINVAL));
+ }
+
+ let scratch = &mut self.1[..block_size];
+ let mut copied = 0usize;
+
+ while copied < buffer.len() {
+ let absolute = offset as usize + copied;
+ let lba = (absolute / block_size) as u64;
+ let in_block = absolute % block_size;
+
+ match (self.0.ReadBlocks)(
+ self.0,
+ self.0.Media.MediaId,
+ lba,
+ block_size,
+ scratch.as_mut_ptr(),
+ ) {
+ status if status.is_success() => {
+ let chunk_len = core::cmp::min(block_size - in_block, buffer.len() - copied);
+ buffer[copied..copied + chunk_len]
+ .copy_from_slice(&scratch[in_block..in_block + chunk_len]);
+ copied += chunk_len;
+ }
+ _ => return Err(Error::new(EIO)),
+ }
+ }
+
+ Ok(())
+ }
+}
--- a/src/os/uefi/mod.rs
+++ b/src/os/uefi/mod.rs
@@ -45,19 +45,18 @@
let pages = size.div_ceil(page_size);
let ptr = {
- // Max address mapped by src/arch paging code (8 GiB)
let mut ptr = 0x2_0000_0000;
- status_to_result((std::system_table().BootServices.AllocatePages)(
- 1, // AllocateMaxAddress
- MemoryType::EfiRuntimeServicesData, // Keeps this memory out of free space list
+ if status_to_result((std::system_table().BootServices.AllocatePages)(
+ 0,
+ MemoryType::EfiLoaderData,
pages,
&mut ptr,
))
- .unwrap_or_else(|_| {
- ptr = 0;
- 0
- });
- if ptr == 0 { ptr::null_mut() } else { ptr as *mut u8 }
+ .is_err()
+ {
+ return ptr::null_mut();
+ }
+ ptr as *mut u8
};
if !ptr.is_null() {