From ce1fdcf7683fce359f38eedcccecf238f32340e6 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 22 Jan 2020 16:15:23 +0100 Subject: [PATCH] Wip --- src/interrupts.rs | 1 + src/lib.rs | 3 +++ src/main.rs | 38 +++++++++++++++++++++++++++++++++++++- src/memory.rs | 30 ++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/interrupts.rs b/src/interrupts.rs index c833af7f..35ab3d66 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -77,6 +77,7 @@ extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: &mut InterruptSt PICS.lock() .notify_end_of_interrupt(InterruptIndex::Timer.as_u8()); } + crate::multitasking::scheduler(); } extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: &mut InterruptStackFrame) { diff --git a/src/lib.rs b/src/lib.rs index e79038ae..170bd639 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,8 @@ #![feature(const_fn)] #![feature(alloc_layout_extra)] #![feature(const_in_array_repeat_expressions)] +#![feature(global_asm)] +#![feature(asm)] #![test_runner(crate::test_runner)] #![reexport_test_harness_main = "test_main"] @@ -17,6 +19,7 @@ pub mod allocator; pub mod gdt; pub mod interrupts; pub mod memory; +pub mod multitasking; pub mod serial; pub mod vga_buffer; diff --git a/src/main.rs b/src/main.rs index 84d42343..2813b4c9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,9 +7,10 @@ extern crate alloc; use alloc::{boxed::Box, rc::Rc, vec, vec::Vec}; -use blog_os::println; +use blog_os::{print, println}; use bootloader::{entry_point, BootInfo}; use core::panic::PanicInfo; +use x86_64::structures::paging::{FrameAllocator, Mapper, Size4KiB}; entry_point!(kernel_main); @@ -54,10 +55,45 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! { #[cfg(test)] test_main(); + create_thread(thread_1, &mut mapper, &mut frame_allocator); + create_thread(thread_2, &mut mapper, &mut frame_allocator); + println!("It did not crash!"); blog_os::hlt_loop(); } +fn create_thread( + f: fn() -> !, + mapper: &mut impl Mapper, + frame_allocator: &mut impl FrameAllocator, +) { + let mut stack = blog_os::memory::alloc_stack(1, mapper, frame_allocator).unwrap(); + stack -= core::mem::size_of::(); + let ptr: *mut u64 = stack.as_mut_ptr(); + unsafe { ptr.write(f as u64) }; + stack -= core::mem::size_of::(); + let ptr: *mut u64 = stack.as_mut_ptr(); + let rflags = 0x200; + unsafe { ptr.write(rflags) }; + unsafe { + blog_os::multitasking::add_thread(stack); + } +} + +fn thread_1() -> ! { + loop { + print!("1"); + x86_64::instructions::hlt(); + } +} + +fn thread_2() -> ! { + loop { + print!("2"); + x86_64::instructions::hlt(); + } +} + /// This function is called on panic. #[cfg(not(test))] #[panic_handler] diff --git a/src/memory.rs b/src/memory.rs index e9380203..c2ebfab0 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -36,6 +36,36 @@ unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut &mut *page_table_ptr // unsafe } +pub fn alloc_stack( + size_in_pages: u64, + mapper: &mut impl Mapper, + frame_allocator: &mut impl FrameAllocator, +) -> Result { + use core::sync::atomic::{AtomicU64, Ordering}; + use x86_64::structures::paging::PageTableFlags as Flags; + + const PAGE_SIZE: u64 = 4096; + static STACK_ALLOC_NEXT: AtomicU64 = AtomicU64::new(0x_5555_5555_0000); + + let guard_page_start = + STACK_ALLOC_NEXT.fetch_add((size_in_pages + 1) * PAGE_SIZE, Ordering::SeqCst); + // skip one page as guard page + let stack_start_addr = VirtAddr::new(guard_page_start + PAGE_SIZE); + let stack_end_addr = stack_start_addr + size_in_pages * PAGE_SIZE; + + let flags = Flags::PRESENT | Flags::WRITABLE; + let stack_start_page = Page::from_start_address(stack_start_addr).unwrap(); + let stack_end_page = Page::from_start_address(stack_end_addr).unwrap(); + for page in Page::range(stack_start_page, stack_end_page) { + let frame = frame_allocator.allocate_frame().ok_or(())?; + mapper + .map_to(page, frame, flags, frame_allocator) + .map_err(|_| ())? + .flush(); + } + Ok(stack_end_addr) +} + /// Creates an example mapping for the given page to frame `0xb8000`. pub fn create_example_mapping( page: Page,