diff --git a/kernel/src/arch/x86_64/memory/allocation/foundry_kalloc.rs b/kernel/src/arch/x86_64/memory/allocation/foundry_kalloc.rs deleted file mode 100644 index 8b13789..0000000 --- a/kernel/src/arch/x86_64/memory/allocation/foundry_kalloc.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/kernel/src/arch/x86_64/memory/allocation/allocator.rs b/kernel/src/arch/x86_64/memory/allocation/heap_alloc.rs similarity index 100% rename from kernel/src/arch/x86_64/memory/allocation/allocator.rs rename to kernel/src/arch/x86_64/memory/allocation/heap_alloc.rs diff --git a/kernel/src/arch/x86_64/memory/allocation/mod.rs b/kernel/src/arch/x86_64/memory/allocation/mod.rs index 184e946..74b817c 100644 --- a/kernel/src/arch/x86_64/memory/allocation/mod.rs +++ b/kernel/src/arch/x86_64/memory/allocation/mod.rs @@ -1,2 +1,2 @@ -pub mod allocator; -mod foundry_kalloc; +pub mod heap_alloc; +pub mod stack_alloc; diff --git a/kernel/src/arch/x86_64/memory/allocation/stack_alloc.rs b/kernel/src/arch/x86_64/memory/allocation/stack_alloc.rs new file mode 100644 index 0000000..a5c21ca --- /dev/null +++ b/kernel/src/arch/x86_64/memory/allocation/stack_alloc.rs @@ -0,0 +1,59 @@ +use x86_64::structures::paging::{mapper, FrameAllocator, Mapper, Page, Size4KiB}; +use x86_64::VirtAddr; + +fn reserve_stack_memory(size_in_pages: u64) -> Page { + use core::sync::atomic::{AtomicU64, Ordering}; + static STACK_ALLOC_NEXT: AtomicU64 = AtomicU64::new(0x_5555_5555_0000); + let start_addr = VirtAddr::new(STACK_ALLOC_NEXT.fetch_add( + size_in_pages * Page::::SIZE, + Ordering::Relaxed, + )); + Page::from_start_address(start_addr) + .expect("`STACK_ALLOC_NEXT` not page aligned") +} + +pub unsafe fn alloc_stack( + size_in_pages: u64, + mapper: &mut impl Mapper, + frame_allocator: &mut impl FrameAllocator, +) -> Result> { + use x86_64::structures::paging::PageTableFlags as Flags; + + let guard_page = reserve_stack_memory(size_in_pages + 1); + let stack_start = guard_page + 1; + let stack_end = stack_start + size_in_pages; + + for page in Page::range(stack_start, stack_end) { + let frame = frame_allocator + .allocate_frame() + .ok_or(mapper::MapToError::FrameAllocationFailed)?; + let flags = Flags::PRESENT | Flags::WRITABLE; + mapper.map_to(page, frame, flags, frame_allocator)?.flush(); + } + + Ok(StackBounds { + start: stack_start.start_address(), + end: stack_end.start_address(), + }) +} + + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct StackBounds { + start: VirtAddr, + end: VirtAddr, +} + +impl StackBounds { + pub fn new(start: VirtAddr, end: VirtAddr) -> Self { + Self { start, end } + } + + pub fn start(&self) -> VirtAddr { + self.start + } + + pub fn end(&self) -> VirtAddr { + self.end + } +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/processing/threading/deprecated.rs b/kernel/src/arch/x86_64/processing/threading/deprecated.rs index 4a1de27..9d1e3c3 100644 --- a/kernel/src/arch/x86_64/processing/threading/deprecated.rs +++ b/kernel/src/arch/x86_64/processing/threading/deprecated.rs @@ -71,43 +71,43 @@ impl ThreadContext { let mut context = Self::default(); unsafe { asm!( - "mov {0}, rax", - "mov {1}, rbx", - "mov {2}, rcx", - "mov {3}, rdx", - "mov {4}, rsi", - "mov {5}, rdi", - "mov {6}, rbp", - "mov {7}, rsp", - "mov {8}, r8", - "mov {9}, r9", - "mov {10}, r10", - "mov {11}, r11", - "mov {12}, r12", - "mov {13}, r13", - "mov {14}, r14", - "mov {15}, r15", - "lea {16}, [rip]", - "pushf", - "pop {17}", - out(reg) context.rax, - out(reg) context.rbx, - out(reg) context.rcx, - out(reg) context.rdx, - out(reg) context.rsi, - out(reg) context.rdi, - out(reg) context.rbp, - out(reg) context.rsp, - out(reg) context.r8, - out(reg) context.r9, - out(reg) context.r10, - out(reg) context.r11, - out(reg) context.r12, - out(reg) context.r13, - out(reg) context.r14, - out(reg) context.r15, - out(reg) context.rip, - out(reg) context.rflags, + "mov {0}, rax", + "mov {1}, rbx", + "mov {2}, rcx", + "mov {3}, rdx", + "mov {4}, rsi", + "mov {5}, rdi", + "mov {6}, rbp", + "mov {7}, rsp", + "mov {8}, r8", + "mov {9}, r9", + "mov {10}, r10", + "mov {11}, r11", + "mov {12}, r12", + "mov {13}, r13", + "mov {14}, r14", + "mov {15}, r15", + "lea {16}, [rip]", + "pushf", + "pop {17}", + out(reg) context.rax, + out(reg) context.rbx, + out(reg) context.rcx, + out(reg) context.rdx, + out(reg) context.rsi, + out(reg) context.rdi, + out(reg) context.rbp, + out(reg) context.rsp, + out(reg) context.r8, + out(reg) context.r9, + out(reg) context.r10, + out(reg) context.r11, + out(reg) context.r12, + out(reg) context.r13, + out(reg) context.r14, + out(reg) context.r15, + out(reg) context.rip, + out(reg) context.rflags, ); } diff --git a/kernel/src/arch/x86_64/processing/threading/mod.rs b/kernel/src/arch/x86_64/processing/threading/mod.rs index d217792..b6f6476 100644 --- a/kernel/src/arch/x86_64/processing/threading/mod.rs +++ b/kernel/src/arch/x86_64/processing/threading/mod.rs @@ -1,4 +1,5 @@ use x86_64::VirtAddr; +use crate::arch::x86_64::memory::allocation::stack_alloc::StackBounds; mod switch; @@ -9,25 +10,7 @@ pub struct Thread { stack_bounds: Option, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct StackBounds { - start: VirtAddr, - end: VirtAddr, -} -impl StackBounds { - pub fn new(start: VirtAddr, end: VirtAddr) -> Self { - Self { start, end } - } - - pub fn start(&self) -> VirtAddr { - self.start - } - - pub fn end(&self) -> VirtAddr { - self.end - } -} #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct ThreadId(u64); diff --git a/kernel/src/arch/x86_64/processing/threading/switch.asm b/kernel/src/arch/x86_64/processing/threading/switch.asm new file mode 100644 index 0000000..ff06e90 --- /dev/null +++ b/kernel/src/arch/x86_64/processing/threading/switch.asm @@ -0,0 +1,13 @@ +.intel_syntax noprefix + +switch_thread: + pushfq + + mov rax, rsp + mov rsp, rdi + + mov rdi, rax + call add_paused_thread + + popfq + ret \ No newline at end of file diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 125a541..f5e8e32 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -16,7 +16,7 @@ use crate::{ arch::x86_64::memory::{init_frame_allocator, init_page_table}, prelude::*, }; -use arch::x86_64::memory::allocation::allocator::init_heap; +use arch::x86_64::memory::allocation::heap_alloc::init_heap; use arch::x86_64::memory::memory_map; use core::arch::asm; use limine::BaseRevision;