Skip to content

Commit

Permalink
Merge PR #229 into next and adjust it to new config system
Browse files Browse the repository at this point in the history
  • Loading branch information
phil-opp committed Apr 10, 2022
2 parents 09fc7bd + f890cc1 commit 3aef58c
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 31 deletions.
8 changes: 5 additions & 3 deletions api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ fn main() {
(49, 9),
(58, 10),
(68, 10),
(78, 9),
(87, 9),
(96, 1),
(78, 1),
(79, 9),
(88, 9),
(97, 9),
(106, 9),
];

let mut code = String::new();
Expand Down
87 changes: 69 additions & 18 deletions api/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl BootloaderConfig {
0x3D,
];
#[doc(hidden)]
pub const SERIALIZED_LEN: usize = 97;
pub const SERIALIZED_LEN: usize = 115;

/// Creates a new default configuration with the following values:
///
Expand Down Expand Up @@ -69,12 +69,14 @@ impl BootloaderConfig {
pre_release,
} = version;
let Mappings {
aslr,
kernel_stack,
boot_info,
framebuffer,
physical_memory,
page_table_recursive,
aslr,
dynamic_range_start,
dynamic_range_end,
} = mappings;
let FrameBuffer {
minimum_framebuffer_height,
Expand Down Expand Up @@ -107,21 +109,36 @@ impl BootloaderConfig {
Option::Some(m) => concat_1_9([1], m.serialize()),
},
);
let buf = concat_78_9(
let buf = concat_78_1(buf, [(*aslr) as u8]);
let buf = concat_79_9(
buf,
match dynamic_range_start {
Option::None => [0; 9],
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
},
);
let buf = concat_88_9(
buf,
match dynamic_range_end {
Option::None => [0; 9],
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
},
);

let buf = concat_97_9(
buf,
match minimum_framebuffer_height {
Option::None => [0; 9],
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
},
);
let buf = concat_87_9(
let buf = concat_106_9(
buf,
match minimum_framebuffer_width {
Option::None => [0; 9],
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
},
);
let buf = concat_96_1(buf, [(*aslr) as u8]);

buf
}
Expand Down Expand Up @@ -177,13 +194,12 @@ impl BootloaderConfig {
let (&page_table_recursive_some, s) = split_array_ref(s);
let (&page_table_recursive, s) = split_array_ref(s);
let (&[alsr], s) = split_array_ref(s);
let (&dynamic_range_start_some, s) = split_array_ref(s);
let (&dynamic_range_start, s) = split_array_ref(s);
let (&dynamic_range_end_some, s) = split_array_ref(s);
let (&dynamic_range_end, s) = split_array_ref(s);

let mappings = Mappings {
aslr: match alsr {
1 => true,
0 => false,
_ => return Err(()),
},
kernel_stack: Mapping::deserialize(&kernel_stack)?,
boot_info: Mapping::deserialize(&boot_info)?,
framebuffer: Mapping::deserialize(&framebuffer)?,
Expand All @@ -197,6 +213,21 @@ impl BootloaderConfig {
[1] => Option::Some(Mapping::deserialize(&page_table_recursive)?),
_ => return Err(()),
},
aslr: match alsr {
1 => true,
0 => false,
_ => return Err(()),
},
dynamic_range_start: match dynamic_range_start_some {
[0] if dynamic_range_start == [0; 8] => Option::None,
[1] => Option::Some(u64::from_le_bytes(dynamic_range_start)),
_ => return Err(()),
},
dynamic_range_end: match dynamic_range_end_some {
[0] if dynamic_range_end == [0; 8] => Option::None,
[1] => Option::Some(u64::from_le_bytes(dynamic_range_end)),
_ => return Err(()),
},
};
(mappings, s)
};
Expand Down Expand Up @@ -314,12 +345,6 @@ impl Default for ApiVersion {
#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
#[non_exhaustive]
pub struct Mappings {
/// Whether to randomize non-statically configured addresses.
/// The kernel base address will be randomized when it's compiled as
/// a position independent executable.
///
/// Defaults to `false`.
pub aslr: bool,
/// Configures how the kernel stack should be mapped.
pub kernel_stack: Mapping,
/// Specifies where the [`crate::BootInfo`] struct should be placed in virtual memory.
Expand All @@ -338,6 +363,20 @@ pub struct Mappings {
///
/// Defaults to `None`, i.e. no recursive mapping.
pub page_table_recursive: Option<Mapping>,
/// Whether to randomize non-statically configured addresses.
/// The kernel base address will be randomized when it's compiled as
/// a position independent executable.
///
/// Defaults to `false`.
pub aslr: bool,
/// The lowest virtual address for dynamic addresses.
///
/// Defaults to `0`.
pub dynamic_range_start: Option<u64>,
/// The highest virtual address for dynamic addresses.
///
/// Defaults to `0xffff_ffff_ffff_f000`.
pub dynamic_range_end: Option<u64>,
}

impl Mappings {
Expand All @@ -346,12 +385,14 @@ impl Mappings {
/// enabled.
pub const fn new_default() -> Self {
Self {
aslr: false,
kernel_stack: Mapping::new_default(),
boot_info: Mapping::new_default(),
framebuffer: Mapping::new_default(),
physical_memory: Option::None,
page_table_recursive: Option::None,
aslr: false,
dynamic_range_start: None,
dynamic_range_end: None,
}
}

Expand All @@ -360,7 +401,6 @@ impl Mappings {
let phys = rand::random();
let recursive = rand::random();
Self {
aslr: rand::random(),
kernel_stack: Mapping::random(),
boot_info: Mapping::random(),
framebuffer: Mapping::random(),
Expand All @@ -374,6 +414,17 @@ impl Mappings {
} else {
Option::None
},
aslr: rand::random(),
dynamic_range_start: if rand::random() {
Option::Some(rand::random())
} else {
Option::None
},
dynamic_range_end: if rand::random() {
Option::Some(rand::random())
} else {
Option::None
},
}
}
}
Expand Down
24 changes: 23 additions & 1 deletion common/src/level_4_entries.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{entropy, BootInfo};
use bootloader_api::{config, info::MemoryRegion, BootloaderConfig};
use core::{alloc::Layout, convert::TryInto};
use core::{alloc::Layout, iter::Step};
use rand::{
distributions::{Distribution, Uniform},
seq::IteratorRandom,
Expand Down Expand Up @@ -73,6 +73,28 @@ impl UsedLevel4Entries {
used.mark_range_as_used(framebuffer_address, framebuffer_size);
}

// Mark everything before the dynamic range as unusable.
if let Some(dynamic_range_start) = config.mappings.dynamic_range_start {
let dynamic_range_start = VirtAddr::new(dynamic_range_start);
let start_page: Page = Page::containing_address(dynamic_range_start);
if let Some(unusable_page) = Step::backward_checked(start_page, 1) {
for i in 0..=u16::from(unusable_page.p4_index()) {
used.mark_p4_index_as_used(PageTableIndex::new(i));
}
}
}

// Mark everything after the dynamic range as unusable.
if let Some(dynamic_range_end) = config.mappings.dynamic_range_end {
let dynamic_range_end = VirtAddr::new(dynamic_range_end);
let end_page: Page = Page::containing_address(dynamic_range_end);
if let Some(unusable_page) = Step::forward_checked(end_page, 1) {
for i in u16::from(unusable_page.p4_index())..512 {
used.mark_p4_index_as_used(PageTableIndex::new(i));
}
}
}

used
}

Expand Down
1 change: 1 addition & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![no_std]
#![feature(step_trait)]
#![deny(unsafe_op_in_unsafe_fn)]

use crate::legacy_memory_region::{LegacyFrameAllocator, LegacyMemoryRegion};
Expand Down
4 changes: 2 additions & 2 deletions tests/test_kernels/higher_half/src/bin/basic_boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

use bootloader_api::{entry_point, BootInfo};
use core::panic::PanicInfo;
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};

entry_point!(kernel_main);
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);

fn kernel_main(_boot_info: &'static mut BootInfo) -> ! {
exit_qemu(QemuExitCode::Success);
Expand Down
4 changes: 2 additions & 2 deletions tests/test_kernels/higher_half/src/bin/check_boot_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

use bootloader_api::{entry_point, info::PixelFormat, BootInfo};
use core::panic::PanicInfo;
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};

entry_point!(kernel_main);
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);

fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
// check memory regions
Expand Down
4 changes: 2 additions & 2 deletions tests/test_kernels/higher_half/src/bin/should_panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

use bootloader_api::{entry_point, BootInfo};
use core::panic::PanicInfo;
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};

entry_point!(kernel_main);
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);

fn kernel_main(_boot_info: &'static mut BootInfo) -> ! {
panic!();
Expand Down
20 changes: 17 additions & 3 deletions tests/test_kernels/higher_half/src/bin/verify_higher_half.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,29 @@

use bootloader_api::{entry_point, BootInfo};
use core::panic::PanicInfo;
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};

entry_point!(kernel_main);
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);

fn kernel_main(_boot_info: &'static mut BootInfo) -> ! {
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
// verify that kernel is really running in the higher half of the address space
// (set in `x86_64-higher_half.json` custom target)
let rip = x86_64::registers::read_rip().as_u64();
assert_eq!(rip & 0xffffffffffff0000, 0xffff800000000000);

// verify that the boot info is located in the higher half of the address space
assert_eq!(
(boot_info as *const _ as usize) & 0xffff800000000000,
0xffff800000000000
);

// verify that the stack is located in the higher half of the address space.
let stack_addr = &rip;
assert_eq!(
(boot_info as *const _ as usize) & 0xffff800000000000,
0xffff800000000000
);

exit_qemu(QemuExitCode::Success);
}

Expand Down
8 changes: 8 additions & 0 deletions tests/test_kernels/higher_half/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
#![no_std]

use bootloader_api::BootloaderConfig;

pub const BOOTLOADER_CONFIG: BootloaderConfig = {
let mut config = BootloaderConfig::new_default();
config.mappings.dynamic_range_start = Some(0xffff_8000_0000_0000);
config
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum QemuExitCode {
Expand Down

0 comments on commit 3aef58c

Please sign in to comment.