Skip to content

Commit 5a0ca99

Browse files
committed
Map ramdisk, and fix bios boot issue due to long file name
1 parent 0cc7bf5 commit 5a0ca99

File tree

8 files changed

+75
-31
lines changed

8 files changed

+75
-31
lines changed

bios/stage-2/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
101101
writeln!(screen::Writer, "kernel loaded at {KERNEL_DST:#p}").unwrap();
102102
writeln!(screen::Writer, "Loading ramdisk...").unwrap();
103103
let ramdisk_len = match try_load_file(
104-
"ramdisk-x86_64",
104+
"ramdisk",
105105
RAMDISK_DST,
106106
&mut fs,
107107
&mut disk,

bios/stage-4/src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,17 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
5656
PhysAddr::new(info.kernel.start)
5757
};
5858
let kernel_size = info.kernel.len;
59-
let mut frame_allocator = {
59+
let mut frame_allocator = if info.ramdisk.start == 0 {
6060
let kernel_end = PhysFrame::containing_address(kernel_start + kernel_size - 1u64);
6161
let next_free = kernel_end + 1;
6262
LegacyFrameAllocator::new_starting_at(
6363
next_free,
6464
memory_map.iter().copied().map(MemoryRegion),
6565
)
66+
} else {
67+
let ramdisk_end = PhysFrame::containing_address(PhysAddr::new( info.ramdisk.start + info.ramdisk.len));
68+
let next_free = ramdisk_end+1;
69+
LegacyFrameAllocator::new_starting_at(next_free, memory_map.iter().copied().map(MemoryRegion))
6670
};
6771

6872
// We identity-mapped all memory, so the offset between physical and virtual addresses is 0

common/src/lib.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ where
122122
&mut page_tables,
123123
system_info.framebuffer.as_ref(),
124124
&config,
125+
&system_info
125126
);
126127
let boot_info = create_boot_info(
127128
&config,
@@ -153,6 +154,7 @@ pub fn set_up_mappings<I, D>(
153154
page_tables: &mut PageTables,
154155
framebuffer: Option<&RawFrameBufferInfo>,
155156
config: &BootloaderConfig,
157+
system_info: &SystemInfo
156158
) -> Mappings
157159
where
158160
I: ExactSizeIterator<Item = D> + Clone,
@@ -184,7 +186,6 @@ where
184186
)
185187
.expect("no entry point");
186188
log::info!("Entry point at: {:#x}", entry_point.as_u64());
187-
188189
// create a stack
189190
let stack_start_addr = mapping_addr(
190191
config.mappings.kernel_stack,
@@ -269,6 +270,36 @@ where
269270
} else {
270271
None
271272
};
273+
let ramdisk_slice_len = system_info.ramdisk_len;
274+
let ramdisk_slice_start = if let Some(ramdisk_address) = system_info.ramdisk_addr {
275+
276+
let ramdisk_address_start = mapping_addr(
277+
config.mappings.ramdisk_memory,
278+
system_info.ramdisk_len,
279+
8,
280+
&mut used_entries
281+
);
282+
let physical_address = PhysAddr::new(ramdisk_address);
283+
let ramdisk_physical_start_page: PhysFrame<Size4KiB> = PhysFrame::containing_address(physical_address);
284+
let ramdisk_page_count = (system_info.ramdisk_len - 1 / Size4KiB::SIZE) + 1;
285+
let ramdisk_physical_end_page = ramdisk_physical_start_page + ramdisk_page_count;
286+
let start_page = Page::containing_address(ramdisk_address_start);
287+
288+
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
289+
for (i, frame) in PhysFrame::range_inclusive(ramdisk_physical_start_page, ramdisk_physical_end_page).enumerate() {
290+
let page = start_page + i as u64;
291+
match unsafe { kernel_page_table.map_to(page, frame, flags, frame_allocator) } {
292+
Ok(tlb) => tlb.ignore(),
293+
Err(err) => panic!(
294+
"Failed to map page {:?} to frame {:?}: {:?}",
295+
page, frame, err
296+
),
297+
};
298+
}
299+
Some(ramdisk_address_start)
300+
} else {
301+
None
302+
};
272303

273304
let physical_memory_offset = if let Some(mapping) = config.mappings.physical_memory {
274305
log::info!("Map physical memory");
@@ -343,6 +374,8 @@ where
343374

344375
kernel_slice_start,
345376
kernel_slice_len,
377+
ramdisk_slice_start,
378+
ramdisk_slice_len
346379
}
347380
}
348381

@@ -368,6 +401,8 @@ pub struct Mappings {
368401
pub kernel_slice_start: u64,
369402
/// Size of the kernel slice allocation in memory.
370403
pub kernel_slice_len: u64,
404+
pub ramdisk_slice_start: Option<VirtAddr>,
405+
pub ramdisk_slice_len: u64
371406
}
372407

373408
/// Allocates and initializes the boot info struct and the memory map.
@@ -477,8 +512,8 @@ where
477512
info.recursive_index = mappings.recursive_index.map(Into::into).into();
478513
info.rsdp_addr = system_info.rsdp_addr.map(|addr| addr.as_u64()).into();
479514
info.tls_template = mappings.tls_template.into();
480-
info.ramdisk_addr = system_info.ramdisk_addr.into();
481-
info.ramdisk_len = system_info.ramdisk_len;
515+
info.ramdisk_addr = mappings.ramdisk_slice_start.map(|addr| addr.as_u64()).into();
516+
info.ramdisk_len = mappings.ramdisk_slice_len;
482517
info
483518
});
484519

src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ mod mbr;
1717
mod pxe;
1818

1919
const KERNEL_FILE_NAME: &str = "kernel-x86_64";
20-
const RAMDISK_FILE_NAME: &str = "ramdisk-x86_64";
20+
const RAMDISK_FILE_NAME: &str = "ramdisk";
2121
const BIOS_STAGE_3: &str = "boot-stage-3";
2222
const BIOS_STAGE_4: &str = "boot-stage-4";
2323

@@ -131,8 +131,11 @@ impl UefiBoot {
131131
/// bootloader won't be found.
132132
pub fn create_pxe_tftp_folder(&self, out_path: &Path) -> anyhow::Result<()> {
133133
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
134-
135-
pxe::create_uefi_tftp_folder(bootloader_path, self.kernel.as_path(), out_path)
134+
let ramdisk_path = match self.ramdisk.as_ref() {
135+
Some(rd) => Some(rd.as_path()),
136+
None => None,
137+
};
138+
pxe::create_uefi_tftp_folder(bootloader_path, self.kernel.as_path(), ramdisk_path, out_path)
136139
.context("failed to create UEFI PXE tftp folder")?;
137140

138141
Ok(())

src/pxe.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anyhow::Context;
55
pub fn create_uefi_tftp_folder(
66
bootloader_path: &Path,
77
kernel_binary: &Path,
8+
ramdisk_path: Option<&Path>,
89
out_path: &Path,
910
) -> anyhow::Result<()> {
1011
std::fs::create_dir_all(out_path)
@@ -27,6 +28,16 @@ pub fn create_uefi_tftp_folder(
2728
to.display()
2829
)
2930
})?;
31+
let to = out_path.join("ramdisk");
32+
if let Some(rp) = ramdisk_path {
33+
std::fs::copy(rp, &to).with_context(|| {
34+
format!(
35+
"failed to copy ramdisk from {} to {}",
36+
rp.display(),
37+
to.display()
38+
)
39+
})?;
40+
}
3041

3142
Ok(())
3243
}

tests/ramdisk.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::path::Path;
2-
31
use bootloader_test_runner::run_test_kernel;
42
static RAMDISK_PATH: &str = "tests/ramdisk.txt";
53

tests/test_kernels/ramdisk/src/bin/ramdisk.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,24 @@
22
#![no_main] // disable all Rust-level entry points
33

44
use bootloader_api::{entry_point, BootInfo};
5-
use test_kernel_ramdisk::{exit_qemu, QemuExitCode, RAMDISK_CONTENTS};
5+
use test_kernel_ramdisk::{exit_qemu, QemuExitCode, RAMDISK_CONTENTS, serial};
6+
use core::{fmt::Write, ptr::slice_from_raw_parts};
67

78

89

910
entry_point!(kernel_main);
1011

11-
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
12+
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
13+
writeln!(serial(), "Boot info: {:?}", boot_info).unwrap();
1214
assert!(boot_info.ramdisk_addr.into_option().is_some());
1315
assert_eq!(boot_info.ramdisk_len as usize, RAMDISK_CONTENTS.len());
14-
15-
let ramdisk = boot_info.ramdisk_addr.into_option().unwrap() as *const u8;
16-
compare_ramdisk_contents(ramdisk);
17-
16+
let actual_ramdisk = unsafe { &*slice_from_raw_parts(boot_info.ramdisk_addr.into_option().unwrap() as *const u8, boot_info.ramdisk_len as usize) };
17+
writeln!(serial(), "Actual contents: {:?}", actual_ramdisk).unwrap();
18+
assert_eq!(RAMDISK_CONTENTS, actual_ramdisk);
1819

1920
exit_qemu(QemuExitCode::Success);
2021
}
2122

22-
fn compare_ramdisk_contents(ramdisk: *const u8) {
23-
let expected = RAMDISK_CONTENTS;
24-
for i in 0..expected.len() {
25-
unsafe { assert_eq!(expected[i], *ramdisk.offset(i as isize)); }
26-
}
27-
}
2823
/// This function is called on panic.
2924
#[cfg(not(test))]
3025
#[panic_handler]

uefi/src/main.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,13 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
150150
LegacyFrameAllocator::new(memory_map.copied().map(UefiMemoryDescriptor));
151151

152152
let page_tables = create_page_tables(&mut frame_allocator);
153-
let mut ramdisk_addr = 0u64;
154153
let mut ramdisk_len = 0u64;
155-
if let Some(rd) = ramdisk {
154+
let ramdisk_addr = if let Some(rd) = ramdisk {
156155
ramdisk_len = rd.len() as u64;
157-
ramdisk_addr = rd.as_ptr() as usize as u64;
158-
}
156+
Some(rd.as_ptr() as usize as u64)
157+
} else {
158+
None
159+
};
159160
let system_info = SystemInfo {
160161
framebuffer,
161162
rsdp_addr: {
@@ -168,10 +169,7 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
168169
.or_else(|| config_entries.find(|entry| matches!(entry.guid, cfg::ACPI_GUID)));
169170
rsdp.map(|entry| PhysAddr::new(entry.address as u64))
170171
},
171-
ramdisk_addr: match ramdisk_addr {
172-
0 => None,
173-
v => Some(v),
174-
},
172+
ramdisk_addr: ramdisk_addr,
175173
ramdisk_len: ramdisk_len,
176174
};
177175

@@ -194,7 +192,7 @@ fn load_ramdisk(
194192
st: &mut SystemTable<Boot>,
195193
boot_mode: BootMode,
196194
) -> Option<&'static mut [u8]> {
197-
load_file_from_boot_method(image, st, "ramdisk-x86_64\0", boot_mode)
195+
load_file_from_boot_method(image, st, "ramdisk\0", boot_mode)
198196
}
199197

200198
fn load_kernel(

0 commit comments

Comments
 (0)