From e34938837276f0abe967633e5c1acc0da6dea2ae Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 28 Jan 2019 11:59:51 +0100 Subject: [PATCH] Update code to current post-10 branch Latest commit on post-10 branch: e5dfbd4b23ef232b2e2717699a15ea223e2474fb --- .gitignore | 15 +---- Cargo.lock | 69 ++++++++++++++------- Cargo.toml | 12 ++-- src/bin/test-basic-boot.rs | 4 +- src/bin/test-exception-breakpoint.rs | 11 ++-- src/bin/test-panic.rs | 4 +- src/gdt.rs | 3 + src/interrupts.rs | 26 ++------ src/lib.rs | 3 +- src/main.rs | 29 ++++----- src/memory.rs | 90 ++++++++++++++++++++++++++++ src/vga_buffer.rs | 3 +- x86_64-blog_os.json | 28 ++++----- 13 files changed, 193 insertions(+), 104 deletions(-) create mode 100644 src/memory.rs diff --git a/.gitignore b/.gitignore index 30023c2f..f0e3bcac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,2 @@ -# Compiled files -*.o -*.so -*.rlib -*.dll - -# Executables -*.exe - -# Generated by Cargo -/target/ - -bootimage.bin +/target +**/*.rs.bk \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 342fec15..aa9645ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "array-init" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -11,7 +11,7 @@ name = "array-init" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "blog_os" -version = "0.2.0" +version = "0.1.0" dependencies = [ "array-init 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "bootloader 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -35,8 +35,8 @@ dependencies = [ "pic8259_simple 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "volatile 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -101,12 +101,12 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.43" +version = "0.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nodrop" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -137,14 +137,37 @@ dependencies = [ [[package]] name = "rand" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "remove_dir_all" version = "0.5.1" @@ -172,7 +195,7 @@ name = "tempdir" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -197,12 +220,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ux" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "volatile" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -233,20 +256,19 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ux 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "x86_64" -version = "0.3.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ux 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -275,13 +297,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66481dbeb5e773e7bd85b63cd6042c30786f834338288c5ec4f3742673db360a" "checksum pc-keyboard 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fff50ab09ba31bcebc0669f4e64c0952fae1acdca9e6e0587e68e4e8443808ac" "checksum pic8259_simple 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc64b2fd10828da8521b6cdabe0679385d7d2a3a6d4c336b819d1fa31ba35c72" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" -"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" +"checksum rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dee497e66d8d76bf08ce20c8d36e16f93749ab0bf89975b4f8ae5cee660c2da2" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum skeptic 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "061203a849117b0f7090baf8157aa91dac30545208fbb85166ac58b4ca33d89c" "checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" @@ -289,12 +314,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "269f953d8de3226f7c065c589c7b4a3e83d10a419c7c3b5e2e0f197e6acc966e" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5" -"checksum ux 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" -"checksum volatile 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ca391c55768e479d5c2f8beb40c136df09257292a809ea514e82cfdfc15d00" +"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f" +"checksum volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af0edf5b4faacc31fc51159244d78d65ec580f021afcef7bd53c04aeabc7f29" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd647af1614659e1febec1d681231aea4ebda4818bf55a578aff02f3e4db4b4" -"checksum x86_64 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "68db3ce040f52ce6dd3a707004d733a4ebe4e5afbc8bbf36572cfddf5054993f" +"checksum x86_64 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f893c7b302f824d1bb6ab25353e585583fa451c918d950e6f81ff5b4267cc18" "checksum xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58" "checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" diff --git a/Cargo.toml b/Cargo.toml index a3820dcf..af3f7846 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,13 @@ [package] -authors = ["Philipp Oppermann "] name = "blog_os" -version = "0.2.0" +version = "0.1.0" +authors = ["Philipp Oppermann "] edition = "2018" [dependencies] bootloader = "0.3.12" -spin = "0.4.9" volatile = "0.2.3" +spin = "0.4.9" uart_16550 = "0.1.0" x86_64 = "0.4.0" pic8259_simple = "0.1.1" @@ -20,13 +20,11 @@ features = ["spin_no_std"] [dev-dependencies] array-init = "0.0.3" -# the profile used for `cargo build` [profile.dev] -panic = "abort" # disable stack unwinding on panic +panic = "abort" -# the profile used for `cargo build --release` [profile.release] -panic = "abort" # disable stack unwinding on panic +panic = "abort" [package.metadata.bootimage] default-target = "x86_64-blog_os.json" diff --git a/src/bin/test-basic-boot.rs b/src/bin/test-basic-boot.rs index f4acda07..f77d4a02 100644 --- a/src/bin/test-basic-boot.rs +++ b/src/bin/test-basic-boot.rs @@ -1,6 +1,6 @@ -#![no_std] // don't link the Rust standard library +#![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_main)] // disable all Rust-level entry points -#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] +#![cfg_attr(test, allow(unused_imports))] use blog_os::{exit_qemu, serial_println}; use core::panic::PanicInfo; diff --git a/src/bin/test-exception-breakpoint.rs b/src/bin/test-exception-breakpoint.rs index 283d2364..c6bf114a 100644 --- a/src/bin/test-exception-breakpoint.rs +++ b/src/bin/test-exception-breakpoint.rs @@ -2,8 +2,8 @@ #![cfg_attr(not(test), no_main)] #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] -use core::panic::PanicInfo; use blog_os::{exit_qemu, serial_println}; +use core::panic::PanicInfo; #[cfg(not(test))] #[no_mangle] @@ -14,11 +14,12 @@ pub extern "C" fn _start() -> ! { serial_println!("ok"); - unsafe { exit_qemu(); } + unsafe { + exit_qemu(); + } loop {} } - #[cfg(not(test))] #[panic_handler] fn panic(info: &PanicInfo) -> ! { @@ -26,6 +27,8 @@ fn panic(info: &PanicInfo) -> ! { serial_println!("{}", info); - unsafe { exit_qemu(); } + unsafe { + exit_qemu(); + } loop {} } diff --git a/src/bin/test-panic.rs b/src/bin/test-panic.rs index 62ed7d7f..c68ac51d 100644 --- a/src/bin/test-panic.rs +++ b/src/bin/test-panic.rs @@ -1,6 +1,6 @@ -#![no_std] +#![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_main)] -#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] +#![cfg_attr(test, allow(unused_imports))] use blog_os::{exit_qemu, serial_println}; use core::panic::PanicInfo; diff --git a/src/gdt.rs b/src/gdt.rs index 3cfa6cc8..de61a7d8 100644 --- a/src/gdt.rs +++ b/src/gdt.rs @@ -18,6 +18,9 @@ lazy_static! { }; tss }; +} + +lazy_static! { static ref GDT: (GlobalDescriptorTable, Selectors) = { let mut gdt = GlobalDescriptorTable::new(); let code_selector = gdt.add_entry(Descriptor::kernel_code_segment()); diff --git a/src/interrupts.rs b/src/interrupts.rs index 223120e4..83ba18dc 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -4,22 +4,21 @@ // problem we skip compilation of this module on Windows. #![cfg(not(windows))] -use crate::{gdt, print, println}; +use crate::{gdt, hlt_loop, print, println}; use lazy_static::lazy_static; use pic8259_simple::ChainedPics; use spin; use x86_64::structures::idt::{ExceptionStackFrame, InterruptDescriptorTable, PageFaultErrorCode}; - pub const PIC_1_OFFSET: u8 = 32; pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8; -pub static PICS: spin::Mutex = - spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) }); - pub const TIMER_INTERRUPT_ID: u8 = PIC_1_OFFSET; pub const KEYBOARD_INTERRUPT_ID: u8 = PIC_1_OFFSET + 1; +pub static PICS: spin::Mutex = + spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) }); + lazy_static! { static ref IDT: InterruptDescriptorTable = { let mut idt = InterruptDescriptorTable::new(); @@ -30,10 +29,8 @@ lazy_static! { .set_handler_fn(double_fault_handler) .set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); } - idt[usize::from(TIMER_INTERRUPT_ID)].set_handler_fn(timer_interrupt_handler); idt[usize::from(KEYBOARD_INTERRUPT_ID)].set_handler_fn(keyboard_interrupt_handler); - idt }; } @@ -59,25 +56,10 @@ extern "x86-interrupt" fn page_fault_handler( hlt_loop(); } -extern "x86-interrupt" fn page_fault_handler( - stack_frame: &mut ExceptionStackFrame, - _error_code: PageFaultErrorCode, -) { - use crate::hlt_loop; - use x86_64::registers::control::Cr2; - - println!("EXCEPTION: PAGE FAULT"); - println!("Accessed Address: {:?}", Cr2::read()); - println!("{:#?}", stack_frame); - hlt_loop(); -} - extern "x86-interrupt" fn double_fault_handler( stack_frame: &mut ExceptionStackFrame, _error_code: u64, ) { - use crate::hlt_loop; - println!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); hlt_loop(); } diff --git a/src/lib.rs b/src/lib.rs index 5e7519df..5974e73c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,9 @@ -#![cfg_attr(not(test), no_std)] // don't link the Rust standard library +#![cfg_attr(not(test), no_std)] #![feature(abi_x86_interrupt)] pub mod gdt; pub mod interrupts; +pub mod memory; pub mod serial; pub mod vga_buffer; diff --git a/src/main.rs b/src/main.rs index e0bb4e4f..a6493875 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,34 +1,31 @@ -#![no_std] // don't link the Rust standard library -#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points +#![cfg_attr(not(test), no_std)] +#![cfg_attr(not(test), no_main)] #![cfg_attr(test, allow(unused_imports))] +use blog_os::println; +use bootloader::{bootinfo::BootInfo, entry_point}; use core::panic::PanicInfo; -use blog_os::println; -use bootloader::bootinfo::BootInfo; +entry_point!(kernel_main); - -/// This function is the entry point, since the linker looks for a function -/// named `_start` by default. #[cfg(not(test))] -#[no_mangle] // don't mangle the name of this function -pub extern "C" fn _start(boot_info: &BootInfo) -> ! { +fn kernel_main(boot_info: &'static BootInfo) -> ! { use blog_os::interrupts::PICS; - use x86_64::structures::paging::PageTable; + use blog_os::memory::{self, create_example_mapping}; println!("Hello World{}", "!"); - let level_4_table_ptr = 0xffff_ffff_ffff_f000 as *const PageTable; - let level_4_table = unsafe { &*level_4_table_ptr }; - for i in 0..10 { - println!("Entry {}: {:?}", i, level_4_table[i]); - } - blog_os::gdt::init(); blog_os::interrupts::init_idt(); unsafe { PICS.lock().initialize() }; x86_64::instructions::interrupts::enable(); + let mut recursive_page_table = unsafe { memory::init(boot_info.p4_table_addr as usize) }; + let mut frame_allocator = memory::init_frame_allocator(&boot_info.memory_map); + + create_example_mapping(&mut recursive_page_table, &mut frame_allocator); + unsafe { (0xdeadbeaf900 as *mut u64).write_volatile(0xf021f077f065f04e) }; + println!("It did not crash!"); blog_os::hlt_loop(); } diff --git a/src/memory.rs b/src/memory.rs new file mode 100644 index 00000000..612f4209 --- /dev/null +++ b/src/memory.rs @@ -0,0 +1,90 @@ +use bootloader::bootinfo::{MemoryMap, MemoryRegionType}; +use x86_64::structures::paging::{ + FrameAllocator, Mapper, Page, PageTable, PhysFrame, RecursivePageTable, Size4KiB, +}; +use x86_64::{PhysAddr, VirtAddr}; + +/// Creates a RecursivePageTable instance from the level 4 address. +/// +/// This function is unsafe because it can break memory safety if an invalid +/// address is passed. +pub unsafe fn init(level_4_table_addr: usize) -> RecursivePageTable<'static> { + /// Rust currently treats the whole body of unsafe functions as an unsafe + /// block, which makes it difficult to see which operations are unsafe. To + /// limit the scope of unsafe we use a safe inner function. + fn init_inner(level_4_table_addr: usize) -> RecursivePageTable<'static> { + let level_4_table_ptr = level_4_table_addr as *mut PageTable; + let level_4_table = unsafe { &mut *level_4_table_ptr }; + RecursivePageTable::new(level_4_table).unwrap() + } + + init_inner(level_4_table_addr) +} + +/// Create a FrameAllocator from the passed memory map +pub fn init_frame_allocator( + memory_map: &'static MemoryMap, +) -> BootInfoFrameAllocator> { + // get usable regions from memory map + let regions = memory_map + .iter() + .filter(|r| r.region_type == MemoryRegionType::Usable); + // map each region to its address range + let addr_ranges = regions.map(|r| r.range.start_addr()..r.range.end_addr()); + // transform to an iterator of frame start addresses + let frame_addresses = addr_ranges.flat_map(|r| r.into_iter().step_by(4096)); + // create `PhysFrame` types from the start addresses + let frames = frame_addresses.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr))); + + BootInfoFrameAllocator { frames } +} + +/// Returns the physical address for the given virtual address, or `None` if +/// the virtual address is not mapped. +pub fn translate_addr(addr: u64, recursive_page_table: &RecursivePageTable) -> Option { + let addr = VirtAddr::new(addr); + let page: Page = Page::containing_address(addr); + + // perform the translation + let frame = recursive_page_table.translate_page(page); + frame.map(|frame| frame.start_address() + u64::from(addr.page_offset())) +} + +pub fn create_example_mapping( + recursive_page_table: &mut RecursivePageTable, + frame_allocator: &mut impl FrameAllocator, +) { + use x86_64::structures::paging::PageTableFlags as Flags; + + let page: Page = Page::containing_address(VirtAddr::new(0xdeadbeaf000)); + let frame = PhysFrame::containing_address(PhysAddr::new(0xb8000)); + let flags = Flags::PRESENT | Flags::WRITABLE; + + let map_to_result = unsafe { recursive_page_table.map_to(page, frame, flags, frame_allocator) }; + map_to_result.expect("map_to failed").flush(); +} + +/// A FrameAllocator that always returns `None`. +pub struct EmptyFrameAllocator; + +impl FrameAllocator for EmptyFrameAllocator { + fn allocate_frame(&mut self) -> Option { + None + } +} + +pub struct BootInfoFrameAllocator +where + I: Iterator, +{ + frames: I, +} + +impl FrameAllocator for BootInfoFrameAllocator +where + I: Iterator, +{ + fn allocate_frame(&mut self) -> Option { + self.frames.next() + } +} diff --git a/src/vga_buffer.rs b/src/vga_buffer.rs index e2aa57db..dd576afa 100644 --- a/src/vga_buffer.rs +++ b/src/vga_buffer.rs @@ -161,7 +161,8 @@ macro_rules! println { ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); } -/// Prints the given formatted string to the VGA text buffer through the global `WRITER` instance. +/// Prints the given formatted string to the VGA text buffer +/// through the global `WRITER` instance. #[doc(hidden)] pub fn _print(args: fmt::Arguments) { use core::fmt::Write; diff --git a/x86_64-blog_os.json b/x86_64-blog_os.json index 7d2110d2..c1c29f9e 100644 --- a/x86_64-blog_os.json +++ b/x86_64-blog_os.json @@ -1,15 +1,15 @@ { - "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "executables": true, - "linker-flavor": "ld.lld", - "linker": "rust-lld", - "panic-strategy": "abort", - "disable-redzone": true, - "features": "-mmx,-sse,+soft-float" -} + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" + } \ No newline at end of file