Skip to content

Commit 3aef58c

Browse files
committedApr 10, 2022
Merge PR #229 into next and adjust it to new config system
2 parents 09fc7bd + f890cc1 commit 3aef58c

File tree

9 files changed

+129
-31
lines changed

9 files changed

+129
-31
lines changed
 

‎api/build.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ fn main() {
1717
(49, 9),
1818
(58, 10),
1919
(68, 10),
20-
(78, 9),
21-
(87, 9),
22-
(96, 1),
20+
(78, 1),
21+
(79, 9),
22+
(88, 9),
23+
(97, 9),
24+
(106, 9),
2325
];
2426

2527
let mut code = String::new();

‎api/src/config.rs

+69-18
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl BootloaderConfig {
3535
0x3D,
3636
];
3737
#[doc(hidden)]
38-
pub const SERIALIZED_LEN: usize = 97;
38+
pub const SERIALIZED_LEN: usize = 115;
3939

4040
/// Creates a new default configuration with the following values:
4141
///
@@ -69,12 +69,14 @@ impl BootloaderConfig {
6969
pre_release,
7070
} = version;
7171
let Mappings {
72-
aslr,
7372
kernel_stack,
7473
boot_info,
7574
framebuffer,
7675
physical_memory,
7776
page_table_recursive,
77+
aslr,
78+
dynamic_range_start,
79+
dynamic_range_end,
7880
} = mappings;
7981
let FrameBuffer {
8082
minimum_framebuffer_height,
@@ -107,21 +109,36 @@ impl BootloaderConfig {
107109
Option::Some(m) => concat_1_9([1], m.serialize()),
108110
},
109111
);
110-
let buf = concat_78_9(
112+
let buf = concat_78_1(buf, [(*aslr) as u8]);
113+
let buf = concat_79_9(
114+
buf,
115+
match dynamic_range_start {
116+
Option::None => [0; 9],
117+
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
118+
},
119+
);
120+
let buf = concat_88_9(
121+
buf,
122+
match dynamic_range_end {
123+
Option::None => [0; 9],
124+
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
125+
},
126+
);
127+
128+
let buf = concat_97_9(
111129
buf,
112130
match minimum_framebuffer_height {
113131
Option::None => [0; 9],
114132
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
115133
},
116134
);
117-
let buf = concat_87_9(
135+
let buf = concat_106_9(
118136
buf,
119137
match minimum_framebuffer_width {
120138
Option::None => [0; 9],
121139
Option::Some(addr) => concat_1_8([1], addr.to_le_bytes()),
122140
},
123141
);
124-
let buf = concat_96_1(buf, [(*aslr) as u8]);
125142

126143
buf
127144
}
@@ -177,13 +194,12 @@ impl BootloaderConfig {
177194
let (&page_table_recursive_some, s) = split_array_ref(s);
178195
let (&page_table_recursive, s) = split_array_ref(s);
179196
let (&[alsr], s) = split_array_ref(s);
197+
let (&dynamic_range_start_some, s) = split_array_ref(s);
198+
let (&dynamic_range_start, s) = split_array_ref(s);
199+
let (&dynamic_range_end_some, s) = split_array_ref(s);
200+
let (&dynamic_range_end, s) = split_array_ref(s);
180201

181202
let mappings = Mappings {
182-
aslr: match alsr {
183-
1 => true,
184-
0 => false,
185-
_ => return Err(()),
186-
},
187203
kernel_stack: Mapping::deserialize(&kernel_stack)?,
188204
boot_info: Mapping::deserialize(&boot_info)?,
189205
framebuffer: Mapping::deserialize(&framebuffer)?,
@@ -197,6 +213,21 @@ impl BootloaderConfig {
197213
[1] => Option::Some(Mapping::deserialize(&page_table_recursive)?),
198214
_ => return Err(()),
199215
},
216+
aslr: match alsr {
217+
1 => true,
218+
0 => false,
219+
_ => return Err(()),
220+
},
221+
dynamic_range_start: match dynamic_range_start_some {
222+
[0] if dynamic_range_start == [0; 8] => Option::None,
223+
[1] => Option::Some(u64::from_le_bytes(dynamic_range_start)),
224+
_ => return Err(()),
225+
},
226+
dynamic_range_end: match dynamic_range_end_some {
227+
[0] if dynamic_range_end == [0; 8] => Option::None,
228+
[1] => Option::Some(u64::from_le_bytes(dynamic_range_end)),
229+
_ => return Err(()),
230+
},
200231
};
201232
(mappings, s)
202233
};
@@ -314,12 +345,6 @@ impl Default for ApiVersion {
314345
#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
315346
#[non_exhaustive]
316347
pub struct Mappings {
317-
/// Whether to randomize non-statically configured addresses.
318-
/// The kernel base address will be randomized when it's compiled as
319-
/// a position independent executable.
320-
///
321-
/// Defaults to `false`.
322-
pub aslr: bool,
323348
/// Configures how the kernel stack should be mapped.
324349
pub kernel_stack: Mapping,
325350
/// Specifies where the [`crate::BootInfo`] struct should be placed in virtual memory.
@@ -338,6 +363,20 @@ pub struct Mappings {
338363
///
339364
/// Defaults to `None`, i.e. no recursive mapping.
340365
pub page_table_recursive: Option<Mapping>,
366+
/// Whether to randomize non-statically configured addresses.
367+
/// The kernel base address will be randomized when it's compiled as
368+
/// a position independent executable.
369+
///
370+
/// Defaults to `false`.
371+
pub aslr: bool,
372+
/// The lowest virtual address for dynamic addresses.
373+
///
374+
/// Defaults to `0`.
375+
pub dynamic_range_start: Option<u64>,
376+
/// The highest virtual address for dynamic addresses.
377+
///
378+
/// Defaults to `0xffff_ffff_ffff_f000`.
379+
pub dynamic_range_end: Option<u64>,
341380
}
342381

343382
impl Mappings {
@@ -346,12 +385,14 @@ impl Mappings {
346385
/// enabled.
347386
pub const fn new_default() -> Self {
348387
Self {
349-
aslr: false,
350388
kernel_stack: Mapping::new_default(),
351389
boot_info: Mapping::new_default(),
352390
framebuffer: Mapping::new_default(),
353391
physical_memory: Option::None,
354392
page_table_recursive: Option::None,
393+
aslr: false,
394+
dynamic_range_start: None,
395+
dynamic_range_end: None,
355396
}
356397
}
357398

@@ -360,7 +401,6 @@ impl Mappings {
360401
let phys = rand::random();
361402
let recursive = rand::random();
362403
Self {
363-
aslr: rand::random(),
364404
kernel_stack: Mapping::random(),
365405
boot_info: Mapping::random(),
366406
framebuffer: Mapping::random(),
@@ -374,6 +414,17 @@ impl Mappings {
374414
} else {
375415
Option::None
376416
},
417+
aslr: rand::random(),
418+
dynamic_range_start: if rand::random() {
419+
Option::Some(rand::random())
420+
} else {
421+
Option::None
422+
},
423+
dynamic_range_end: if rand::random() {
424+
Option::Some(rand::random())
425+
} else {
426+
Option::None
427+
},
377428
}
378429
}
379430
}

‎common/src/level_4_entries.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{entropy, BootInfo};
22
use bootloader_api::{config, info::MemoryRegion, BootloaderConfig};
3-
use core::{alloc::Layout, convert::TryInto};
3+
use core::{alloc::Layout, iter::Step};
44
use rand::{
55
distributions::{Distribution, Uniform},
66
seq::IteratorRandom,
@@ -73,6 +73,28 @@ impl UsedLevel4Entries {
7373
used.mark_range_as_used(framebuffer_address, framebuffer_size);
7474
}
7575

76+
// Mark everything before the dynamic range as unusable.
77+
if let Some(dynamic_range_start) = config.mappings.dynamic_range_start {
78+
let dynamic_range_start = VirtAddr::new(dynamic_range_start);
79+
let start_page: Page = Page::containing_address(dynamic_range_start);
80+
if let Some(unusable_page) = Step::backward_checked(start_page, 1) {
81+
for i in 0..=u16::from(unusable_page.p4_index()) {
82+
used.mark_p4_index_as_used(PageTableIndex::new(i));
83+
}
84+
}
85+
}
86+
87+
// Mark everything after the dynamic range as unusable.
88+
if let Some(dynamic_range_end) = config.mappings.dynamic_range_end {
89+
let dynamic_range_end = VirtAddr::new(dynamic_range_end);
90+
let end_page: Page = Page::containing_address(dynamic_range_end);
91+
if let Some(unusable_page) = Step::forward_checked(end_page, 1) {
92+
for i in u16::from(unusable_page.p4_index())..512 {
93+
used.mark_p4_index_as_used(PageTableIndex::new(i));
94+
}
95+
}
96+
}
97+
7698
used
7799
}
78100

‎common/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![no_std]
2+
#![feature(step_trait)]
23
#![deny(unsafe_op_in_unsafe_fn)]
34

45
use crate::legacy_memory_region::{LegacyFrameAllocator, LegacyMemoryRegion};

‎tests/test_kernels/higher_half/src/bin/basic_boot.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
use bootloader_api::{entry_point, BootInfo};
55
use core::panic::PanicInfo;
6-
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
6+
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};
77

8-
entry_point!(kernel_main);
8+
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);
99

1010
fn kernel_main(_boot_info: &'static mut BootInfo) -> ! {
1111
exit_qemu(QemuExitCode::Success);

‎tests/test_kernels/higher_half/src/bin/check_boot_info.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
use bootloader_api::{entry_point, info::PixelFormat, BootInfo};
55
use core::panic::PanicInfo;
6-
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
6+
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};
77

8-
entry_point!(kernel_main);
8+
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);
99

1010
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
1111
// check memory regions

‎tests/test_kernels/higher_half/src/bin/should_panic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
use bootloader_api::{entry_point, BootInfo};
55
use core::panic::PanicInfo;
6-
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
6+
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};
77

8-
entry_point!(kernel_main);
8+
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);
99

1010
fn kernel_main(_boot_info: &'static mut BootInfo) -> ! {
1111
panic!();

‎tests/test_kernels/higher_half/src/bin/verify_higher_half.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,29 @@
33

44
use bootloader_api::{entry_point, BootInfo};
55
use core::panic::PanicInfo;
6-
use test_kernel_higher_half::{exit_qemu, QemuExitCode};
6+
use test_kernel_higher_half::{exit_qemu, QemuExitCode, BOOTLOADER_CONFIG};
77

8-
entry_point!(kernel_main);
8+
entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);
99

10-
fn kernel_main(_boot_info: &'static mut BootInfo) -> ! {
10+
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
1111
// verify that kernel is really running in the higher half of the address space
1212
// (set in `x86_64-higher_half.json` custom target)
1313
let rip = x86_64::registers::read_rip().as_u64();
1414
assert_eq!(rip & 0xffffffffffff0000, 0xffff800000000000);
15+
16+
// verify that the boot info is located in the higher half of the address space
17+
assert_eq!(
18+
(boot_info as *const _ as usize) & 0xffff800000000000,
19+
0xffff800000000000
20+
);
21+
22+
// verify that the stack is located in the higher half of the address space.
23+
let stack_addr = &rip;
24+
assert_eq!(
25+
(boot_info as *const _ as usize) & 0xffff800000000000,
26+
0xffff800000000000
27+
);
28+
1529
exit_qemu(QemuExitCode::Success);
1630
}
1731

‎tests/test_kernels/higher_half/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
#![no_std]
22

3+
use bootloader_api::BootloaderConfig;
4+
5+
pub const BOOTLOADER_CONFIG: BootloaderConfig = {
6+
let mut config = BootloaderConfig::new_default();
7+
config.mappings.dynamic_range_start = Some(0xffff_8000_0000_0000);
8+
config
9+
};
10+
311
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
412
#[repr(u32)]
513
pub enum QemuExitCode {

0 commit comments

Comments
 (0)
Please sign in to comment.