Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7c74627

Browse files
committed
Add a test to verify that ramdisk is marked as used in memory map
1 parent 6b23732 commit 7c74627

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

‎tests/ramdisk.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,11 @@ fn check_ramdisk() {
1818
Some(Path::new(RAMDISK_PATH)),
1919
);
2020
}
21+
22+
#[test]
23+
fn memory_map() {
24+
run_test_kernel_with_ramdisk(
25+
env!("CARGO_BIN_FILE_TEST_KERNEL_RAMDISK_memory_map"),
26+
Some(Path::new(RAMDISK_PATH)),
27+
);
28+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#![no_std] // don't link the Rust standard library
2+
#![no_main] // disable all Rust-level entry points
3+
4+
use bootloader_api::{
5+
config::Mapping, entry_point, info::MemoryRegionKind, BootInfo, BootloaderConfig,
6+
};
7+
use core::{fmt::Write, ptr::slice_from_raw_parts};
8+
use test_kernel_ramdisk::{exit_qemu, serial, QemuExitCode, RAMDISK_CONTENTS};
9+
use x86_64::{
10+
structures::paging::{OffsetPageTable, PageTable, PageTableFlags, Translate},
11+
VirtAddr,
12+
};
13+
14+
pub const BOOTLOADER_CONFIG: BootloaderConfig = {
15+
let mut config = BootloaderConfig::new_default();
16+
config.mappings.physical_memory = Some(Mapping::FixedAddress(0x0000_6000_0000_0000));
17+
config
18+
};
19+
20+
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);
21+
22+
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
23+
writeln!(serial(), "Boot info: {boot_info:?}").unwrap();
24+
25+
let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset.into_option().unwrap());
26+
let level_4_table = unsafe { active_level_4_table(phys_mem_offset) };
27+
let page_table = unsafe { OffsetPageTable::new(level_4_table, phys_mem_offset) };
28+
29+
let ramdisk_start_addr = VirtAddr::new(boot_info.ramdisk_addr.into_option().unwrap());
30+
assert_eq!(boot_info.ramdisk_len as usize, RAMDISK_CONTENTS.len());
31+
let ramdisk_end_addr = ramdisk_start_addr + boot_info.ramdisk_len;
32+
33+
let mut next_addr = ramdisk_start_addr;
34+
while next_addr < ramdisk_end_addr {
35+
let phys_addr = match page_table.translate(next_addr) {
36+
x86_64::structures::paging::mapper::TranslateResult::Mapped {
37+
frame,
38+
offset: _,
39+
flags,
40+
} => {
41+
assert!(flags.contains(PageTableFlags::PRESENT));
42+
assert!(flags.contains(PageTableFlags::WRITABLE));
43+
44+
next_addr += frame.size();
45+
46+
frame.start_address()
47+
}
48+
other => panic!("invalid result: {other:?}"),
49+
};
50+
let region = boot_info
51+
.memory_regions
52+
.iter()
53+
.find(|r| r.start <= phys_addr.as_u64() && r.end > phys_addr.as_u64())
54+
.unwrap();
55+
assert_eq!(region.kind, MemoryRegionKind::Bootloader);
56+
}
57+
58+
let actual_ramdisk = unsafe {
59+
&*slice_from_raw_parts(
60+
boot_info.ramdisk_addr.into_option().unwrap() as *const u8,
61+
boot_info.ramdisk_len as usize,
62+
)
63+
};
64+
writeln!(serial(), "Actual contents: {actual_ramdisk:?}").unwrap();
65+
assert_eq!(RAMDISK_CONTENTS, actual_ramdisk);
66+
67+
exit_qemu(QemuExitCode::Success);
68+
}
69+
70+
/// This function is called on panic.
71+
#[cfg(not(test))]
72+
#[panic_handler]
73+
fn panic(info: &core::panic::PanicInfo) -> ! {
74+
let _ = writeln!(test_kernel_ramdisk::serial(), "PANIC: {info}");
75+
exit_qemu(QemuExitCode::Failed);
76+
}
77+
78+
pub unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable {
79+
use x86_64::registers::control::Cr3;
80+
81+
let (level_4_table_frame, _) = Cr3::read();
82+
83+
let phys = level_4_table_frame.start_address();
84+
let virt = physical_memory_offset + phys.as_u64();
85+
let page_table_ptr: *mut PageTable = virt.as_mut_ptr();
86+
87+
&mut *page_table_ptr // unsafe
88+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /