Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 24a4cae

Browse files
bors[bot]64
andcommittedAug 5, 2019
Merge #72
72: Configurable kernel stack size, better non-x86_64 errors r=phil-opp a=64 Allows the configuration of the kernel stack size through an environment variable. Also makes the errors a bit nicer if you try to use this crate from a non-x86_64 architecture (only works if you build it as a library), as discussed in #70. Co-authored-by: Matt Taylor <mstaveleytaylor@gmail.com>
2 parents 12242da + 2fdd1f2 commit 24a4cae

File tree

3 files changed

+41
-34
lines changed

3 files changed

+41
-34
lines changed
 

‎build.rs

+30-26
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,43 @@
11
#[cfg(not(feature = "binary"))]
2-
fn main() {}
2+
#[allow(unreachable_code)]
3+
fn main() {
4+
#[cfg(target_arch = "x86")]
5+
panic!("This crate currently does not support 32-bit protected mode. \
6+
See https://github.com/rust-osdev/bootloader/issues/70 for more information.");
7+
8+
#[cfg(not(target_arch = "x86_64"))]
9+
panic!("This crate only supports the x86_64 architecture.");
10+
}
311

412
#[cfg(feature = "binary")]
5-
fn address_from_env(env: &'static str) -> Option<u64> {
13+
fn num_from_env(env: &'static str, aligned: bool) -> Option<u64> {
614
use std::env;
715
match env::var(env) {
816
Err(env::VarError::NotPresent) => None,
917
Err(env::VarError::NotUnicode(_)) => {
1018
panic!("The `{}` environment variable must be valid unicode", env,)
1119
}
1220
Ok(s) => {
13-
let addr = if s.starts_with("0x") {
21+
let num = if s.starts_with("0x") {
1422
u64::from_str_radix(&s[2..], 16)
1523
} else {
1624
u64::from_str_radix(&s, 10)
1725
};
1826

19-
let addr = addr.expect(&format!(
27+
let num = num.expect(&format!(
2028
"The `{}` environment variable must be an integer\
2129
(is `{}`).",
2230
env, s
2331
));
2432

25-
if addr % 0x1000 != 0 {
33+
if aligned && num % 0x1000 != 0 {
2634
panic!(
2735
"The `{}` environment variable must be aligned to 0x1000 (is `{:#x}`).",
28-
env, addr
36+
env, num
2937
);
3038
}
3139

32-
Some(addr)
40+
Some(num)
3341
}
3442
}
3543
}
@@ -176,31 +184,26 @@ fn main() {
176184
process::exit(1);
177185
}
178186

179-
// create a file with the `PHYSICAL_MEMORY_OFFSET` constant
180-
let file_path = out_dir.join("physical_memory_offset.rs");
181-
let mut file = File::create(file_path).expect("failed to create physical_memory_offset.rs");
182-
let physical_memory_offset = address_from_env("BOOTLOADER_PHYSICAL_MEMORY_OFFSET");
183-
file.write_all(
184-
format!(
185-
"const PHYSICAL_MEMORY_OFFSET: Option<u64> = {:?};",
186-
physical_memory_offset
187-
)
188-
.as_bytes(),
189-
)
190-
.expect("write to physical_memory_offset.rs failed");
191-
192-
// create a file with the `KERNEL_STACK_ADDRESS` constant
193-
let file_path = out_dir.join("kernel_stack_address.rs");
194-
let mut file = File::create(file_path).expect("failed to create kernel_stack_address.rs");
195-
let kernel_stack_address = address_from_env("BOOTLOADER_KERNEL_STACK_ADDRESS");
187+
// Configure constants for the bootloader
188+
// We leave some variables as Option<T> rather than hardcoding their defaults so that they
189+
// can be calculated dynamically by the bootloader.
190+
let file_path = out_dir.join("bootloader_config.rs");
191+
let mut file = File::create(file_path).expect("failed to create bootloader_config.rs");
192+
let physical_memory_offset = num_from_env("BOOTLOADER_PHYSICAL_MEMORY_OFFSET", true);
193+
let kernel_stack_address = num_from_env("BOOTLOADER_KERNEL_STACK_ADDRESS", true);
194+
let kernel_stack_size = num_from_env("BOOTLOADER_KERNEL_STACK_SIZE", false);
196195
file.write_all(
197196
format!(
198-
"const KERNEL_STACK_ADDRESS: Option<u64> = {:?};",
197+
"const PHYSICAL_MEMORY_OFFSET: Option<u64> = {:?};
198+
const KERNEL_STACK_ADDRESS: Option<u64> = {:?};
199+
const KERNEL_STACK_SIZE: u64 = {};",
200+
physical_memory_offset,
199201
kernel_stack_address,
202+
kernel_stack_size.unwrap_or(512), // size is in number of pages
200203
)
201204
.as_bytes(),
202205
)
203-
.expect("write to kernel_stack_address.rs failed");
206+
.expect("write to bootloader_config.rs failed");
204207

205208
// pass link arguments to rustc
206209
println!("cargo:rustc-link-search=native={}", out_dir.display());
@@ -212,6 +215,7 @@ fn main() {
212215
println!("cargo:rerun-if-env-changed=KERNEL");
213216
println!("cargo:rerun-if-env-changed=BOOTLOADER_PHYSICAL_MEMORY_OFFSET");
214217
println!("cargo:rerun-if-env-changed=BOOTLOADER_KERNEL_STACK_ADDRESS");
218+
println!("cargo:rerun-if-env-changed=BOOTLOADER_KERNEL_STACK_SIZE");
215219
println!("cargo:rerun-if-changed={}", kernel.display());
216220
println!("cargo:rerun-if-changed=build.rs");
217221
}

‎src/main.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ use x86_64::structures::paging::{
2424
use x86_64::ux::u9;
2525
use x86_64::{PhysAddr, VirtAddr};
2626

27-
// The offset into the virtual address space where the physical memory is mapped if
28-
// the `map_physical_memory` is activated. Set by the build script.
29-
include!(concat!(env!("OUT_DIR"), "/physical_memory_offset.rs"));
30-
31-
// The virtual address of the kernel stack. Set by the build script.
32-
include!(concat!(env!("OUT_DIR"), "/kernel_stack_address.rs"));
27+
// The bootloader_config.rs file contains some configuration constants set by the build script:
28+
// PHYSICAL_MEMORY_OFFSET: The offset into the virtual address space where the physical memory
29+
// is mapped if the `map_physical_memory` feature is activated.
30+
//
31+
// KERNEL_STACK_ADDRESS: The virtual address of the kernel stack.
32+
//
33+
// KERNEL_STACK_SIZE: The number of pages in the kernel stack.
34+
include!(concat!(env!("OUT_DIR"), "/bootloader_config.rs"));
3335

3436
global_asm!(include_str!("stage_1.s"));
3537
global_asm!(include_str!("stage_2.s"));
@@ -271,6 +273,7 @@ fn load_elf(
271273
let stack_end = page_table::map_kernel(
272274
kernel_start.phys(),
273275
kernel_stack_address,
276+
KERNEL_STACK_SIZE,
274277
&segments,
275278
&mut rec_page_table,
276279
&mut frame_allocator,

‎src/page_table.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use xmas_elf::program::{self, ProgramHeader64};
1111
pub(crate) fn map_kernel(
1212
kernel_start: PhysAddr,
1313
stack_start: Page,
14+
stack_size: u64,
1415
segments: &FixedVec<ProgramHeader64>,
1516
page_table: &mut RecursivePageTable,
1617
frame_allocator: &mut FrameAllocator,
@@ -20,9 +21,8 @@ pub(crate) fn map_kernel(
2021
}
2122

2223
// Create a stack
23-
let stack_size: u64 = 512; // in pages
2424
let stack_start = stack_start + 1; // Leave the first page unmapped as a 'guard page'
25-
let stack_end = stack_start + stack_size;
25+
let stack_end = stack_start + stack_size; // stack_size is in pages
2626

2727
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
2828
let region_type = MemoryRegionType::KernelStack;

0 commit comments

Comments
 (0)