diff --git a/README.md b/README.md index a4087f75..d6de5af0 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Blog OS (Advanced Paging) +# Blog OS (Introduction to Paging) -[![Build Status](https://travis-ci.org/phil-opp/blog_os.svg?branch=post-10)](https://travis-ci.org/phil-opp/blog_os/branches) +[![Build Status](https://travis-ci.org/phil-opp/blog_os.svg?branch=post-09)](https://travis-ci.org/phil-opp/blog_os/branches) -This repository contains the source code for the [Advanced Paging][post] post of the [Writing an OS in Rust](https://os.phil-opp.com) series. +This repository contains the source code for the [Introduction to Paging][post] post of the [Writing an OS in Rust](https://os.phil-opp.com) series. -[post]: https://os.phil-opp.com/advanced-paging/ +[post]: https://os.phil-opp.com/paging-introduction/ **Check out the [master branch](https://github.com/phil-opp/blog_os) for more information.** diff --git a/src/lib.rs b/src/lib.rs index 5974e73c..34debc4f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ 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 a6493875..c10b0954 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,15 +3,13 @@ #![cfg_attr(test, allow(unused_imports))] use blog_os::println; -use bootloader::{bootinfo::BootInfo, entry_point}; use core::panic::PanicInfo; -entry_point!(kernel_main); - #[cfg(not(test))] -fn kernel_main(boot_info: &'static BootInfo) -> ! { +#[no_mangle] +pub extern "C" fn _start() -> ! { use blog_os::interrupts::PICS; - use blog_os::memory::{self, create_example_mapping}; + use x86_64::registers::control::Cr3; println!("Hello World{}", "!"); @@ -20,11 +18,11 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! { 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) }; + let (level_4_page_table, _) = Cr3::read(); + println!( + "Level 4 page table at: {:?}", + level_4_page_table.start_address() + ); println!("It did not crash!"); blog_os::hlt_loop(); diff --git a/src/memory.rs b/src/memory.rs deleted file mode 100644 index ddf643be..00000000 --- a/src/memory.rs +++ /dev/null @@ -1,79 +0,0 @@ -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 } -} - -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() - } -}