diff --git a/Changelog.md b/Changelog.md index d2d765ab..d8a0e8a5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Make the physical memory offset configurable through a `BOOTLOADER_PHYSICAL_MEMORY_OFFSET` environment variable ([#58](https://github.com/rust-osdev/bootloader/pull/58)). + # 0.6.0 - **Breaking**: Don't set the `#[cfg(not(test))]` attribute for the entry point function in the `entry_point` macro diff --git a/README.md b/README.md index bbee206d..14b65e9b 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ The bootloader crate can be configured through some cargo features: - `vga_320x200`: This feature switches the VGA hardware to mode 0x13, a graphics mode with resolution 320x200 and 256 colors per pixel. The framebuffer is linear and lives at address `0xa0000`. - `recursive_page_table`: Maps the level 4 page table recursively and adds the [`recursive_page_table_address`](https://docs.rs/bootloader/0.4.0/bootloader/bootinfo/struct.BootInfo.html#structfield.recursive_page_table_addr) field to the passed `BootInfo`. - `map_physical_memory`: Maps the complete physical memory in the virtual address space and passes a [`physical_memory_offset`](https://docs.rs/bootloader/0.4.0/bootloader/bootinfo/struct.BootInfo.html#structfield.physical_memory_offset) field in the `BootInfo`. + - The virtual address where the physical memory should be mapped is configurable by setting the `BOOTLOADER_PHYSICAL_MEMORY_OFFSET` environment variable (supports decimal and hex numbers (prefixed with `0x`)). ## License diff --git a/build.rs b/build.rs index 8b8fc163..f4959d0f 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,7 @@ use std::{ env, + fs::File, + io::Write, path::{Path, PathBuf}, process::{self, Command}, }; @@ -123,6 +125,34 @@ fn main() { process::exit(1); } + // create a file with the `PHYSICAL_MEMORY_OFFSET` constant + let file_path = out_dir.join("physical_memory_offset.rs"); + let mut file = File::create(file_path).expect("failed to create physical_memory_offset.rs"); + let physical_memory_offset = match env::var("BOOTLOADER_PHYSICAL_MEMORY_OFFSET") { + Err(env::VarError::NotPresent) => 0o_177777_770_000_000_000_0000u64, + Err(env::VarError::NotUnicode(_)) => panic!( + "The `BOOTLOADER_PHYSICAL_MEMORY_OFFSET` environment variable must be valid unicode" + ), + Ok(s) => if s.starts_with("0x") { + u64::from_str_radix(&s[2..], 16) + } else { + u64::from_str_radix(&s, 10) + } + .expect(&format!( + "The `BOOTLOADER_PHYSICAL_MEMORY_OFFSET` environment variable must be an integer\ + (is `{}`).", + s + )), + }; + file.write_all( + format!( + "const PHYSICAL_MEMORY_OFFSET: u64 = {:#x};", + physical_memory_offset + ) + .as_bytes(), + ) + .expect("write to physical_memory_offset.rs failed"); + // pass link arguments to rustc println!("cargo:rustc-link-search=native={}", out_dir.display()); println!( @@ -131,6 +161,7 @@ fn main() { ); println!("cargo:rerun-if-env-changed=KERNEL"); + println!("cargo:rerun-if-env-changed=BOOTLOADER_PHYSICAL_MEMORY_OFFSET"); println!("cargo:rerun-if-changed={}", kernel.display()); println!("cargo:rerun-if-changed=build.rs"); } diff --git a/src/main.rs b/src/main.rs index 9d050c46..f9f0c078 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,9 +22,9 @@ use x86_64::structures::paging::{ use x86_64::ux::u9; use x86_64::{PhysAddr, VirtAddr}; -/// The offset into the virtual address space where the physical memory is mapped if -/// the `map_physical_memory` is activated. -const PHYSICAL_MEMORY_OFFSET: u64 = 0o_177777_770_000_000_000_0000; +// The offset into the virtual address space where the physical memory is mapped if +// the `map_physical_memory` is activated. Set by the build script. +include!(concat!(env!("OUT_DIR"), "/physical_memory_offset.rs")); global_asm!(include_str!("stage_1.s")); global_asm!(include_str!("stage_2.s"));