Skip to content

Commit ca98936

Browse files
authoredJan 30, 2023
Merge pull request #342 from rust-osdev/fix-config
Fix loading of boot configuration
2 parents baec055 + f03065e commit ca98936

File tree

12 files changed

+46
-28
lines changed

12 files changed

+46
-28
lines changed
 

‎api/src/info.rs

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ pub struct BootInfo {
5656
pub ramdisk_addr: Optional<u64>,
5757
/// Ramdisk image size, set to 0 if addr is None
5858
pub ramdisk_len: u64,
59+
60+
#[doc(hidden)]
61+
pub _test_sentinel: u64,
5962
}
6063

6164
impl BootInfo {
@@ -73,6 +76,7 @@ impl BootInfo {
7376
tls_template: Optional::None,
7477
ramdisk_addr: Optional::None,
7578
ramdisk_len: 0,
79+
_test_sentinel: 0,
7680
}
7781
}
7882
}

‎bios/common/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub struct BiosInfo {
99
pub kernel: Region,
1010
pub ramdisk: Region,
1111
pub config_file: Region,
12+
pub last_used_addr: u64,
1213
pub framebuffer: BiosFramebufferInfo,
1314
pub memory_map_addr: u32,
1415
pub memory_map_len: u16,

‎bios/stage-2/src/main.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
115115
}
116116
let config_file_start = ramdisk_start.wrapping_add(ramdisk_len.try_into().unwrap());
117117
let config_file_len = try_load_file(
118-
"config.json",
118+
"boot.json",
119119
config_file_start,
120120
&mut fs,
121121
&mut disk,
@@ -161,6 +161,7 @@ fn start(disk_number: u16, partition_table_start: *const u8) -> ! {
161161
start: config_file_start as u64,
162162
len: config_file_len,
163163
},
164+
last_used_addr: config_file_start as u64 + config_file_len - 1,
164165
memory_map_addr: memory_map.as_mut_ptr() as u32,
165166
memory_map_len: memory_map.len().try_into().unwrap(),
166167
framebuffer: BiosFramebufferInfo {

‎bios/stage-4/src/main.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,7 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
5454
PhysAddr::new(info.kernel.start)
5555
};
5656
let kernel_size = info.kernel.len;
57-
let next_free_frame = match info.ramdisk.len {
58-
0 => PhysFrame::containing_address(kernel_start + kernel_size - 1u64) + 1,
59-
_ => {
60-
PhysFrame::containing_address(PhysAddr::new(
61-
info.ramdisk.start + info.ramdisk.len - 1u64,
62-
)) + 1
63-
}
64-
};
57+
let next_free_frame = PhysFrame::containing_address(PhysAddr::new(info.last_used_addr)) + 1;
6558
let mut frame_allocator = LegacyFrameAllocator::new_starting_at(
6659
next_free_frame,
6760
memory_map.iter().copied().map(MemoryRegion),
@@ -173,7 +166,7 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
173166
ramdisk_len: info.ramdisk.len,
174167
};
175168

176-
load_and_switch_to_kernel(kernel, frame_allocator, page_tables, system_info);
169+
load_and_switch_to_kernel(kernel, config, frame_allocator, page_tables, system_info);
177170
}
178171

179172
fn init_logger(

‎common/config/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub struct BootConfig {
2222
///
2323
/// Enabled by default.
2424
pub serial_logging: bool,
25+
26+
pub _test_sentinel: u64,
2527
}
2628

2729
impl Default for BootConfig {
@@ -31,6 +33,7 @@ impl Default for BootConfig {
3133
log_level: Default::default(),
3234
frame_buffer_logging: true,
3335
serial_logging: true,
36+
_test_sentinel: 0,
3437
}
3538
}
3639
}

‎common/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use bootloader_api::{
88
info::{FrameBuffer, FrameBufferInfo, MemoryRegion, TlsTemplate},
99
BootInfo, BootloaderConfig,
1010
};
11-
use bootloader_boot_config::LevelFilter;
11+
use bootloader_boot_config::{BootConfig, LevelFilter};
1212
use core::{alloc::Layout, arch::asm, mem::MaybeUninit, slice};
1313
use level_4_entries::UsedLevel4Entries;
1414
use usize_conversions::FromUsize;
@@ -125,6 +125,7 @@ impl<'a> Kernel<'a> {
125125
/// directly to these functions, so see their docs for more info.
126126
pub fn load_and_switch_to_kernel<I, D>(
127127
kernel: Kernel,
128+
boot_config: BootConfig,
128129
mut frame_allocator: LegacyFrameAllocator<I, D>,
129130
mut page_tables: PageTables,
130131
system_info: SystemInfo,
@@ -144,6 +145,7 @@ where
144145
);
145146
let boot_info = create_boot_info(
146147
&config,
148+
&boot_config,
147149
frame_allocator,
148150
&mut page_tables,
149151
&mut mappings,
@@ -435,6 +437,7 @@ pub struct Mappings {
435437
/// are taken from the given `frame_allocator`.
436438
pub fn create_boot_info<I, D>(
437439
config: &BootloaderConfig,
440+
boot_config: &BootConfig,
438441
mut frame_allocator: LegacyFrameAllocator<I, D>,
439442
page_tables: &mut PageTables,
440443
mappings: &mut Mappings,
@@ -539,6 +542,7 @@ where
539542
.map(|addr| addr.as_u64())
540543
.into();
541544
info.ramdisk_len = mappings.ramdisk_slice_len;
545+
info._test_sentinel = boot_config._test_sentinel;
542546
info
543547
});
544548

‎src/uefi/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ impl UefiBoot {
6868
bootloader_path,
6969
self.kernel.as_path(),
7070
self.ramdisk.as_deref(),
71+
self.config.as_deref(),
7172
out_path,
7273
)
7374
.context("failed to create UEFI PXE tftp folder")?;

‎src/uefi/pxe.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use std::path::Path;
22

33
use anyhow::Context;
4+
use bootloader_boot_config::BootConfig;
45

56
pub fn create_uefi_tftp_folder(
67
bootloader_path: &Path,
78
kernel_binary: &Path,
89
ramdisk_path: Option<&Path>,
10+
boot_config: Option<&str>,
911
out_path: &Path,
1012
) -> anyhow::Result<()> {
1113
std::fs::create_dir_all(out_path)
@@ -39,5 +41,10 @@ pub fn create_uefi_tftp_folder(
3941
})?;
4042
}
4143

44+
if let Some(config) = boot_config {
45+
let to = out_path.join("boot.json");
46+
std::fs::write(to, config).context("failed to write boot.json")?;
47+
}
48+
4249
Ok(())
4350
}

‎tests/config_file.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@ use bootloader_test_runner::run_test_kernel_internal;
33
use bootloader::BootConfig;
44

55
#[test]
6-
fn basic_boot() {
7-
let config: BootConfig = Default::default();
6+
fn default_config() {
87
run_test_kernel_internal(
9-
env!("CARGO_BIN_FILE_TEST_KERNEL_CONFIG_FILE_basic_boot"),
8+
env!("CARGO_BIN_FILE_TEST_KERNEL_CONFIG_FILE_no_config"),
9+
None,
1010
None,
11-
Some(&config),
1211
);
1312
}
1413

1514
#[test]
16-
fn custom_options_boot() {
15+
fn custom_boot_config() {
1716
let config = BootConfig {
1817
frame_buffer: Default::default(),
1918
log_level: Default::default(),
2019
frame_buffer_logging: false,
2120
serial_logging: true,
21+
_test_sentinel: 0xb001b001b001,
2222
};
2323
run_test_kernel_internal(
24-
env!("CARGO_BIN_FILE_TEST_KERNEL_CONFIG_FILE_basic_boot_broken_config_file"),
24+
env!("CARGO_BIN_FILE_TEST_KERNEL_CONFIG_FILE_custom_config"),
2525
None,
2626
Some(&config),
2727
);

‎tests/test_kernels/config_file/src/bin/basic_boot_broken_config_file.rs renamed to ‎tests/test_kernels/config_file/src/bin/custom_config.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ entry_point!(kernel_main);
99

1010
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
1111
writeln!(serial(), "Entered kernel with boot info: {boot_info:?}").unwrap();
12+
assert_eq!(boot_info._test_sentinel, 0xb001b001b001);
1213
exit_qemu(QemuExitCode::Success);
1314
}
1415

‎tests/test_kernels/config_file/src/bin/basic_boot.rs renamed to ‎tests/test_kernels/config_file/src/bin/no_config.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ entry_point!(kernel_main);
99

1010
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
1111
writeln!(serial(), "Entered kernel with boot info: {boot_info:?}").unwrap();
12+
assert_eq!(boot_info._test_sentinel, 0);
1213
exit_qemu(QemuExitCode::Success);
1314
}
1415

‎uefi/src/main.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
7373
}
7474

7575
let mut boot_mode = BootMode::Disk;
76+
77+
let mut kernel = load_kernel(image, &mut st, boot_mode);
78+
if kernel.is_none() {
79+
// Try TFTP boot
80+
boot_mode = BootMode::Tftp;
81+
kernel = load_kernel(image, &mut st, boot_mode);
82+
}
83+
let kernel = kernel.expect("Failed to load kernel");
84+
7685
let config_file = load_config_file(image, &mut st, boot_mode);
7786
let mut error_loading_config: Option<serde_json_core::de::Error> = None;
7887
let mut config: BootConfig = match config_file
@@ -87,14 +96,6 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
8796
}
8897
};
8998

90-
let mut kernel = load_kernel(image, &mut st, boot_mode);
91-
if kernel.is_none() {
92-
// Try TFTP boot
93-
boot_mode = BootMode::Tftp;
94-
kernel = load_kernel(image, &mut st, boot_mode);
95-
}
96-
let kernel = kernel.expect("Failed to load kernel");
97-
9899
#[allow(deprecated)]
99100
if config.frame_buffer.minimum_framebuffer_height.is_none() {
100101
config.frame_buffer.minimum_framebuffer_height =
@@ -105,7 +106,7 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
105106
config.frame_buffer.minimum_framebuffer_width =
106107
kernel.config.frame_buffer.minimum_framebuffer_width;
107108
}
108-
let framebuffer = init_logger(image, &st, config);
109+
let framebuffer = init_logger(image, &st, &config);
109110

110111
unsafe {
111112
*SYSTEM_TABLE.get() = None;
@@ -193,6 +194,7 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
193194

194195
bootloader_x86_64_common::load_and_switch_to_kernel(
195196
kernel,
197+
config,
196198
frame_allocator,
197199
page_tables,
198200
system_info,
@@ -218,7 +220,7 @@ fn load_config_file(
218220
st: &mut SystemTable<Boot>,
219221
boot_mode: BootMode,
220222
) -> Option<&'static mut [u8]> {
221-
load_file_from_boot_method(image, st, "config.json\0", boot_mode)
223+
load_file_from_boot_method(image, st, "boot.json\0", boot_mode)
222224
}
223225

224226
fn load_kernel(
@@ -473,7 +475,7 @@ fn create_page_tables(
473475
fn init_logger(
474476
image_handle: Handle,
475477
st: &SystemTable<Boot>,
476-
config: BootConfig,
478+
config: &BootConfig,
477479
) -> Option<RawFrameBufferInfo> {
478480
let gop_handle = st
479481
.boot_services()

0 commit comments

Comments
 (0)
Please sign in to comment.