From d53661b9a02228779f3915506b7dc1630ee3a3ce Mon Sep 17 00:00:00 2001 From: Jacob Hinchliffe Date: Tue, 4 Mar 2025 23:06:47 +0000 Subject: [PATCH] Ran cargo fmt, clippy fixes, suppressed some warns I will start working on stack traces tonight and tomorrow. We need to be able to 'unwind' by finding calling functions. --- kernel/src/arch/x86_64/drivers/ascii/mod.rs | 29 +++++-- .../arch/x86_64/drivers/framebuffer/colour.rs | 13 ++- .../x86_64/drivers/framebuffer/display.rs | 27 ++++--- kernel/src/arch/x86_64/drivers/keyboard.rs | 27 ++++--- kernel/src/arch/x86_64/interrupts.rs | 37 ++++++--- .../x86_64/memory/allocation/heap_alloc.rs | 37 ++++++--- .../src/arch/x86_64/memory/allocation/mod.rs | 2 +- .../x86_64/memory/allocation/page_alloc.rs | 70 ++++++++++------ .../x86_64/memory/allocation/stack_alloc.rs | 79 ++++++++++--------- kernel/src/arch/x86_64/memory/mapping.rs | 3 +- kernel/src/arch/x86_64/memory/mod.rs | 21 ++--- kernel/src/arch/x86_64/memory/units.rs | 4 +- .../arch/x86_64/processing/async_io/task.rs | 12 +-- kernel/src/arch/x86_64/processing/mod.rs | 3 +- .../arch/x86_64/processing/taskrunner/mod.rs | 6 +- .../arch/x86_64/processing/threading/mod.rs | 4 +- kernel/src/lib.rs | 21 ++--- kernel/src/std/application.rs | 5 +- kernel/src/std/application/frame.rs | 19 ++++- kernel/src/std/application/window.rs | 3 +- kernel/src/std/ascii.rs | 6 +- kernel/src/std/io.rs | 19 ++--- kernel/src/util/editor.rs | 18 +++-- libm/src/lib.rs | 7 +- rustfmt.toml | 4 + 25 files changed, 300 insertions(+), 176 deletions(-) create mode 100644 rustfmt.toml diff --git a/kernel/src/arch/x86_64/drivers/ascii/mod.rs b/kernel/src/arch/x86_64/drivers/ascii/mod.rs index 6e3cb37..d380b76 100644 --- a/kernel/src/arch/x86_64/drivers/ascii/mod.rs +++ b/kernel/src/arch/x86_64/drivers/ascii/mod.rs @@ -2,14 +2,17 @@ use core::fmt; use spin::{Lazy, Mutex}; use x86_64::instructions::interrupts; -use crate::arch::x86_64::drivers::framebuffer::{colour::Colour, display::FRAMEBUFFER_WRITER}; +use crate::arch::x86_64::drivers::framebuffer::{ + colour::Colour, display::FRAMEBUFFER_WRITER, +}; use crate::resources::font::{FONT_SPLEEN_8X16, Font}; static FONT_WIDTH: u32 = 8; static FONT_HEIGHT: u32 = 16; -pub static WRITER: Lazy> = Lazy::new(|| Mutex::new(Writer::new())); +pub static WRITER: Lazy> = + Lazy::new(|| Mutex::new(Writer::new())); pub fn screensize_chars() -> (u32, u32) { let writer = WRITER.lock(); @@ -71,21 +74,31 @@ impl Writer { return; } - // Get the character data from the font array. -- each byte is a row of pixels + // Get the character data from the font array. -- each byte is a row of + // pixels let data: &[u8] = self.font.glyph_for(c as u16); if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() { for (row, line) in data.iter().enumerate().take(16) { for col in 0..8 { let pixel_x: u32 = self.text_col * FONT_WIDTH + col; - let pixel_y: u32 = self.text_line * FONT_HEIGHT + row as u32; + let pixel_y: u32 = + self.text_line * FONT_HEIGHT + row as u32; if line & (0x80 >> col) != 0 { // Write the foreground color - writer.write_pixel(pixel_x as usize, pixel_y as usize, self.fg_color); + writer.write_pixel( + pixel_x as usize, + pixel_y as usize, + self.fg_color, + ); } else { // Write the background color - writer.write_pixel(pixel_x as usize, pixel_y as usize, self.bg_color); + writer.write_pixel( + pixel_x as usize, + pixel_y as usize, + self.bg_color, + ); } } } @@ -117,8 +130,8 @@ impl Writer { } } - /// Handles the backspace character. TODO: Implement VT-100 style terminal control - /// codes alongside a shell. Not simple. + /// Handles the backspace character. TODO: Implement VT-100 style terminal + /// control codes alongside a shell. Not simple. pub fn backspace(&mut self) { if self.text_col > 0 { self.text_col -= 1; diff --git a/kernel/src/arch/x86_64/drivers/framebuffer/colour.rs b/kernel/src/arch/x86_64/drivers/framebuffer/colour.rs index 2d6c0b6..f6ccb7d 100644 --- a/kernel/src/arch/x86_64/drivers/framebuffer/colour.rs +++ b/kernel/src/arch/x86_64/drivers/framebuffer/colour.rs @@ -19,9 +19,14 @@ impl From for u32 { fn from(val: Colour) -> Self { match val { Colour::ARGB(a, r, g, b) => { - (a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32) + (a as u32) << 24 + | (r as u32) << 16 + | (g as u32) << 8 + | (b as u32) + } + Colour::RGB(r, g, b) => { + ((r as u32) << 16) | (g as u32) << 8 | (b as u32) } - Colour::RGB(r, g, b) => ((r as u32) << 16) | (g as u32) << 8 | (b as u32), Colour::HexARGB(hex) => hex, Colour::Black => 0xFF000000, Colour::Blue => 0xFF0000FF, @@ -38,7 +43,9 @@ impl From for u32 { impl core::fmt::Display for Colour { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - Self::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a), + Self::ARGB(r, g, b, a) => { + write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a) + } Self::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b), Self::HexARGB(hex) => write!(f, "Hex(#{:x})", hex), Self::Black => write!(f, "Black"), diff --git a/kernel/src/arch/x86_64/drivers/framebuffer/display.rs b/kernel/src/arch/x86_64/drivers/framebuffer/display.rs index 576b77b..49d2726 100644 --- a/kernel/src/arch/x86_64/drivers/framebuffer/display.rs +++ b/kernel/src/arch/x86_64/drivers/framebuffer/display.rs @@ -10,17 +10,19 @@ use core::panic; use limine::framebuffer::Framebuffer; use spin::{Lazy, Mutex}; -pub static FRAMEBUFFER_WRITER: Lazy>> = Lazy::new(|| { - Mutex::new(FRAMEBUFFER_REQUEST.get_response().map_or_else( - || { - panic!("Framebuffer request failed"); - }, - |framebuffer_response| { - let framebuffer = framebuffer_response.framebuffers().next().unwrap(); - Some(FramebufferWriter::new(framebuffer)) - }, - )) -}); +pub static FRAMEBUFFER_WRITER: Lazy>> = + Lazy::new(|| { + Mutex::new(FRAMEBUFFER_REQUEST.get_response().map_or_else( + || { + panic!("Framebuffer request failed"); + }, + |framebuffer_response| { + let framebuffer = + framebuffer_response.framebuffers().next().unwrap(); + Some(FramebufferWriter::new(framebuffer)) + }, + )) + }); /// The updated writer stores necessary fields from the [Framebuffer]. /// This ensures that the contained types are Send, as Framebuffer was @@ -28,7 +30,8 @@ pub static FRAMEBUFFER_WRITER: Lazy>> = Lazy::ne /// /// It also avoids the requirement for lifetimes. /// -/// Note this does not implement Writer as these functions only handle drawing pixels. +/// Note this does not implement Writer as these functions only handle drawing +/// pixels. pub struct FramebufferWriter { pitch: u64, bpp: u16, diff --git a/kernel/src/arch/x86_64/drivers/keyboard.rs b/kernel/src/arch/x86_64/drivers/keyboard.rs index 928d17a..90929ba 100644 --- a/kernel/src/arch/x86_64/drivers/keyboard.rs +++ b/kernel/src/arch/x86_64/drivers/keyboard.rs @@ -6,20 +6,24 @@ use core::{ use crate::println; use crossbeam::queue::ArrayQueue; use futures_util::{Stream, StreamExt, task::AtomicWaker}; -use pc_keyboard::{DecodedKey, HandleControl, KeyCode, Keyboard, ScancodeSet1, layouts::Uk105Key}; +use pc_keyboard::{ + DecodedKey, HandleControl, KeyCode, Keyboard, ScancodeSet1, + layouts::Uk105Key, +}; use spin::{Lazy, Mutex, Once}; static KBD_QUEUE: Once> = Once::new(); static WAKER: AtomicWaker = AtomicWaker::new(); -pub static KEYBOARD: Lazy>> = Lazy::new(|| { - Mutex::new(Keyboard::new( - ScancodeSet1::new(), - // TODO: Expose an API to change the default KB layout. - Uk105Key, - HandleControl::Ignore, - )) -}); +pub static KEYBOARD: Lazy>> = + Lazy::new(|| { + Mutex::new(Keyboard::new( + ScancodeSet1::new(), + // TODO: Expose an API to change the default KB layout. + Uk105Key, + HandleControl::Ignore, + )) + }); pub static SCANCODE_STREAM: Lazy> = Lazy::new(|| Mutex::new(ScancodeStream::new())); @@ -59,7 +63,10 @@ impl Default for ScancodeStream { impl Stream for ScancodeStream { type Item = u8; - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { let queue = KBD_QUEUE.get().unwrap(); if let Some(scancode) = queue.pop() { diff --git a/kernel/src/arch/x86_64/interrupts.rs b/kernel/src/arch/x86_64/interrupts.rs index 0e385f3..b869aa6 100644 --- a/kernel/src/arch/x86_64/interrupts.rs +++ b/kernel/src/arch/x86_64/interrupts.rs @@ -1,9 +1,13 @@ use crate::serial_print; use pic8259::ChainedPics; use x86_64::registers::control::Cr2; -use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}; +use x86_64::structures::idt::{ + InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode, +}; use x86_64::structures::paging::mapper::MapperFlushAll; -use x86_64::structures::paging::{FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB}; +use x86_64::structures::paging::{ + FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB, +}; use super::gdt; use crate::arch::x86_64::memory::{FRAME_ALLOCATOR, OFFSET_PAGE_TABLE}; @@ -25,7 +29,8 @@ static IDT: Lazy = Lazy::new(|| { idt.page_fault.set_handler_fn(page_fault_handler); idt[InterruptIndex::Timer.as_u8()].set_handler_fn(timer_interrupt_handler); - idt[InterruptIndex::Keyboard.as_u8()].set_handler_fn(keyboard_interrupt_handler); + idt[InterruptIndex::Keyboard.as_u8()] + .set_handler_fn(keyboard_interrupt_handler); idt }); @@ -90,19 +95,22 @@ extern "x86-interrupt" fn double_fault_handler( panic!("Exception: Double Fault\n{:#?}", stack_frame); } -extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) { +extern "x86-interrupt" fn keyboard_interrupt_handler( + _stack_frame: InterruptStackFrame, +) { use pc_keyboard::{HandleControl, Keyboard, ScancodeSet1, layouts}; // use pc_keyboard::DecodedKey; use spin::Mutex; use x86_64::instructions::port::Port; - static KEYBOARD: Lazy>> = Lazy::new(|| { - Mutex::new(Keyboard::new( - ScancodeSet1::new(), - layouts::Uk105Key, - HandleControl::Ignore, - )) - }); + static KEYBOARD: Lazy>> = + Lazy::new(|| { + Mutex::new(Keyboard::new( + ScancodeSet1::new(), + layouts::Uk105Key, + HandleControl::Ignore, + )) + }); let _keyboard = KEYBOARD.lock(); let mut port = Port::new(0x60); @@ -116,7 +124,9 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac } } -extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) { +extern "x86-interrupt" fn timer_interrupt_handler( + _stack_frame: InterruptStackFrame, +) { unsafe { PICS.lock() .notify_end_of_interrupt(InterruptIndex::Timer.as_u8()); @@ -137,7 +147,8 @@ extern "x86-interrupt" fn page_fault_handler( let frame = f.allocate_frame().unwrap(); let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE; - let page: Page = Page::containing_address(Cr2::read().unwrap()); + let page: Page = + Page::containing_address(Cr2::read().unwrap()); unsafe { let mut mapper = OFFSET_PAGE_TABLE.get().unwrap().lock(); diff --git a/kernel/src/arch/x86_64/memory/allocation/heap_alloc.rs b/kernel/src/arch/x86_64/memory/allocation/heap_alloc.rs index 96c5274..41baa41 100644 --- a/kernel/src/arch/x86_64/memory/allocation/heap_alloc.rs +++ b/kernel/src/arch/x86_64/memory/allocation/heap_alloc.rs @@ -1,19 +1,27 @@ +use crate::arch::x86_64::memory::{HEAP_SIZE, HEAP_VIRTUAL_SPACE}; use core::alloc::{GlobalAlloc, Layout}; use core::ptr; use spin::{Mutex, MutexGuard}; use x86_64::structures::paging::{Size4KiB, mapper::MapToError}; -use crate::arch::x86_64::memory::{HEAP_SIZE, HEAP_VIRTUAL_SPACE}; -/// We are currently using a linked list heap allocator which uses our underlying page allocator. +/// We are currently using a linked list heap allocator which uses our +/// underlying page allocator. #[global_allocator] -/// This is now Rust's global allocator, so we can use stuff requiring heap allocations. -static ALLOCATOR: Locked = Locked::new(FoundryAllocator::new()); - +/// This is now Rust's global allocator, so we can use stuff requiring heap +/// allocations. +static ALLOCATOR: Locked = + Locked::new(FoundryAllocator::new()); /// Sets up the heap using the backing page frame allocator. +/// +/// # Safety +/// +/// We do not check whether the given heap start address and size are actually +/// valid. pub unsafe fn init_heap() -> Result<(), MapToError> { unsafe { - // code to allocate frames is now done in the page fault interrupt handler! + // The code to allocate frames is now done in the page fault interrupt + // handler! ALLOCATOR.lock().init(HEAP_VIRTUAL_SPACE, HEAP_SIZE); Ok(()) } @@ -60,11 +68,13 @@ impl FoundryAllocator { fallback: Locked::new(FoundryFallbackAllocator::new()), } } - /// Initializes the fallback allocator with the given heap start address and size. + /// Initializes the fallback allocator with the given heap start address and + /// size. /// /// # Safety /// - /// This function is unsafe because it does not check whether the given heap start address and size are valid. + /// This function is unsafe because it does not check whether the given heap + /// start address and size are valid. pub unsafe fn init(&mut self, heap_start: usize, heap_size: usize) { unsafe { self.fallback.lock().init(heap_start, heap_size); @@ -97,7 +107,9 @@ unsafe impl GlobalAlloc for Locked { let block_size = BLOCK_SIZES[index]; // only works if all block sizes are a power of 2 let block_align = block_size; - let layout = Layout::from_size_align(block_size, block_align).unwrap(); + let layout = + Layout::from_size_align(block_size, block_align) + .unwrap(); unsafe { allocator.fallback_alloc(layout) } } } @@ -183,7 +195,9 @@ impl FoundryFallbackAllocator { let mut current = &mut self.head; // look for a large enough memory region in linked list while let Some(ref mut region) = current.next { - if let Ok(alloc_start) = Self::alloc_from_region(region, size, align) { + if let Ok(alloc_start) = + Self::alloc_from_region(region, size, align) + { // region suitable for allocation -> remove node from list let next = region.next.take(); let ret = Some((current.next.take().unwrap(), alloc_start)); @@ -236,7 +250,8 @@ unsafe impl GlobalAlloc for Locked { // perform layout adjustments let (size, align) = FoundryFallbackAllocator::size_align(layout); - if let Some((region, alloc_start)) = allocator.find_region(size, align) { + if let Some((region, alloc_start)) = allocator.find_region(size, align) + { let alloc_end = alloc_start.checked_add(size).expect("overflow"); let excess_size = region.end_addr() - alloc_end; if excess_size > 0 { diff --git a/kernel/src/arch/x86_64/memory/allocation/mod.rs b/kernel/src/arch/x86_64/memory/allocation/mod.rs index 6877073..979df58 100644 --- a/kernel/src/arch/x86_64/memory/allocation/mod.rs +++ b/kernel/src/arch/x86_64/memory/allocation/mod.rs @@ -1,3 +1,3 @@ pub mod heap_alloc; -pub mod stack_alloc; pub(crate) mod page_alloc; +pub mod stack_alloc; diff --git a/kernel/src/arch/x86_64/memory/allocation/page_alloc.rs b/kernel/src/arch/x86_64/memory/allocation/page_alloc.rs index 3fa9aae..e0c87f8 100644 --- a/kernel/src/arch/x86_64/memory/allocation/page_alloc.rs +++ b/kernel/src/arch/x86_64/memory/allocation/page_alloc.rs @@ -1,10 +1,12 @@ -use x86_64::structures::paging::{FrameAllocator, Mapper, Page, PageTableFlags, PhysFrame, Size4KiB}; +use crate::arch::x86_64::memory::{FRAME_ALLOCATOR, OFFSET_PAGE_TABLE}; +use limine::memory_map::EntryType; use limine::response::MemoryMapResponse; use spin::Mutex; -use limine::memory_map::EntryType; -use x86_64::{PhysAddr, VirtAddr}; use x86_64::structures::paging::mapper::MapToError; -use crate::arch::x86_64::memory::{FRAME_ALLOCATOR, OFFSET_PAGE_TABLE}; +use x86_64::structures::paging::{ + FrameAllocator, Mapper, Page, PageTableFlags, PhysFrame, Size4KiB, +}; +use x86_64::{PhysAddr, VirtAddr}; pub struct FoundryOSFrameAllocator { memory_map: &'static MemoryMapResponse, @@ -14,14 +16,17 @@ pub struct FoundryOSFrameAllocator { impl FoundryOSFrameAllocator { /// Creates a new `FoundryOSFrameAllocator` from a memory map. /// - /// This function takes a reference to a `MemoryMapResponse` and initializes a - /// `FoundryOSFrameAllocator` with it. The `next` field is set to 0, indicating that - /// the first frame to be allocated is the first frame in the memory map. + /// This function takes a reference to a `MemoryMapResponse` and initializes + /// a `FoundryOSFrameAllocator` with it. The `next` field is set to 0, + /// indicating that the first frame to be allocated is the first frame + /// in the memory map. pub fn init(memory_map: &'static MemoryMapResponse) { - FRAME_ALLOCATOR.call_once(|| Mutex::new(Self { - memory_map, - next: 0, - })); + FRAME_ALLOCATOR.call_once(|| { + Mutex::new(Self { + memory_map, + next: 0, + }) + }); } pub fn count_usable_frames(&self) -> u32 { @@ -29,7 +34,7 @@ impl FoundryOSFrameAllocator { } pub fn available_memory(&self) -> u64 { - ( self.memory_map.entries().len() * 4096 ) as u64 // multiply the number of physical frames by 4096 to get the memory size + (self.memory_map.entries().len() * 4096) as u64 // multiply the number of physical frames by 4096 to get the memory size } /// An iterator over all usable frames in the memory map. @@ -39,20 +44,35 @@ impl FoundryOSFrameAllocator { /// This function is used to allocate frames for the pagemap. fn usable_frames(&self) -> impl Iterator + use<> { let regions = self.memory_map.entries().iter(); - let usable_regions = regions.filter(|region| region.entry_type == EntryType::USABLE); - let addr_ranges = usable_regions.map(|region| region.base..region.base + region.length); + let usable_regions = + regions.filter(|region| region.entry_type == EntryType::USABLE); + let addr_ranges = usable_regions + .map(|region| region.base..region.base + region.length); let frame_addresses = addr_ranges.flat_map(|r| r.step_by(4096)); - frame_addresses.map(|addr| PhysFrame::from_start_address(PhysAddr::new(addr)).unwrap()) + frame_addresses.map(|addr| { + PhysFrame::from_start_address(PhysAddr::new(addr)).unwrap() + }) } - - - fn allocate_page(&mut self, start_addr: VirtAddr, flags: PageTableFlags) -> Result<(), MapToError> { - let page = Page::from_start_address(start_addr).map_err(|_| MapToError::FrameAllocationFailed)?; - let frame = self.allocate_frame().ok_or(MapToError::FrameAllocationFailed)?; + #[expect(unused)] + fn allocate_page( + &mut self, + start_addr: VirtAddr, + flags: PageTableFlags, + ) -> Result<(), MapToError> { + let page = Page::from_start_address(start_addr) + .map_err(|_| MapToError::FrameAllocationFailed)?; + let frame = self + .allocate_frame() + .ok_or(MapToError::FrameAllocationFailed)?; let _ = unsafe { let mut mapper = OFFSET_PAGE_TABLE.get().unwrap().lock(); - mapper.map_to(page, frame, flags, &mut *FRAME_ALLOCATOR.get().unwrap().lock())? + mapper.map_to( + page, + frame, + flags, + &mut *FRAME_ALLOCATOR.get().unwrap().lock(), + )? }; Ok(()) } @@ -61,9 +81,9 @@ impl FoundryOSFrameAllocator { unsafe impl FrameAllocator for FoundryOSFrameAllocator { /// Allocates a frame from the list of usable frames. /// - /// This function returns the next available `PhysFrame` from the memory map, - /// if one exists. Once a frame is allocated, the internal counter is incremented - /// to point to the next frame for future allocations. + /// This function returns the next available `PhysFrame` from the memory + /// map, if one exists. Once a frame is allocated, the internal counter + /// is incremented to point to the next frame for future allocations. /// /// # Returns /// @@ -74,4 +94,4 @@ unsafe impl FrameAllocator for FoundryOSFrameAllocator { self.next += 1; frame } -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/memory/allocation/stack_alloc.rs b/kernel/src/arch/x86_64/memory/allocation/stack_alloc.rs index 513b9fe..1665f22 100644 --- a/kernel/src/arch/x86_64/memory/allocation/stack_alloc.rs +++ b/kernel/src/arch/x86_64/memory/allocation/stack_alloc.rs @@ -1,33 +1,39 @@ -use x86_64::structures::paging::{mapper, FrameAllocator, Mapper, Page, Size4KiB}; -use x86_64::VirtAddr; use crate::arch::x86_64::memory::STACK_VIRTUAL_SPACE; +use x86_64::VirtAddr; +use x86_64::structures::paging::{ + FrameAllocator, Mapper, Page, Size4KiB, mapper, +}; fn reserve_stack_memory(size_in_pages: u64) -> Page { use core::sync::atomic::{AtomicU64, Ordering}; - static STACK_ALLOC_NEXT: AtomicU64 = AtomicU64::new(STACK_VIRTUAL_SPACE as u64); - let start_addr = VirtAddr::new(STACK_ALLOC_NEXT.fetch_add( - size_in_pages * Page::::SIZE, - Ordering::Relaxed, - )); + static STACK_ALLOC_NEXT: AtomicU64 = + AtomicU64::new(STACK_VIRTUAL_SPACE as u64); + 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") } /// Allocates a stack in the virtual address space, mapped to physical pages. /// -/// This function allocates a stack in the virtual address space, mapped to physical pages. -/// The stack is allocated as a sequence of pages, with the first page allocated as a guard page. -/// The stack is then mapped to the allocated physical frame. +/// This function allocates a stack in the virtual address space, mapped to +/// physical pages. The stack is allocated as a sequence of pages, with the +/// first page allocated as a guard page. The stack is then mapped to the +/// allocated physical frame. /// -/// The function takes the size of the stack in pages, a mutable reference to a mapper, and a -/// mutable reference to a frame allocator. It returns a `Result` containing a `StackBounds` -/// struct, which contains the start and end virtual addresses of the allocated stack. +/// The function takes the size of the stack in pages, a mutable reference to a +/// mapper, and a mutable reference to a frame allocator. It returns a `Result` +/// containing a `StackBounds` struct, which contains the start and end virtual +/// addresses of the allocated stack. /// /// # Safety /// -/// This function is unsafe because it maps physical frames to virtual addresses without any -/// protection. This can lead to bugs if the physical frames are not correctly allocated, or if the -/// virtual addresses are not correctly aligned. +/// This function is unsafe because it maps physical frames to virtual addresses +/// without any protection. This can lead to bugs if the physical frames are not +/// correctly allocated, or if the virtual addresses are not correctly aligned. /// /// # Panics /// @@ -36,27 +42,28 @@ pub unsafe fn alloc_stack( size_in_pages: u64, mapper: &mut impl Mapper, frame_allocator: &mut impl FrameAllocator, -) -> Result> { unsafe { - 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; +) -> Result> { + unsafe { + use x86_64::structures::paging::PageTableFlags as Flags; - 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(); + 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(), + }) } - - Ok(StackBounds { - start: stack_start.start_address(), - end: stack_end.start_address(), - }) -}} - +} #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct StackBounds { @@ -76,4 +83,4 @@ impl StackBounds { pub const fn end(&self) -> VirtAddr { self.end } -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/memory/mapping.rs b/kernel/src/arch/x86_64/memory/mapping.rs index 1df8437..305d800 100644 --- a/kernel/src/arch/x86_64/memory/mapping.rs +++ b/kernel/src/arch/x86_64/memory/mapping.rs @@ -16,7 +16,8 @@ static HIGHER_HALF_DIRECT_MAP_REQUEST: HhdmRequest = HhdmRequest::new(); #[used] #[unsafe(link_section = ".requests")] -static KERNEL_ADDRESS_REQUEST: KernelAddressRequest = KernelAddressRequest::new(); +static KERNEL_ADDRESS_REQUEST: KernelAddressRequest = + KernelAddressRequest::new(); /// ```rs /// let virt_addr = phys_addr + offset; diff --git a/kernel/src/arch/x86_64/memory/mod.rs b/kernel/src/arch/x86_64/memory/mod.rs index fe6d18b..0ee8807 100644 --- a/kernel/src/arch/x86_64/memory/mod.rs +++ b/kernel/src/arch/x86_64/memory/mod.rs @@ -2,20 +2,19 @@ pub mod allocation; pub mod mapping; pub mod units; -use spin::{Mutex, Once}; -use x86_64::{ - registers::control::Cr3, structures::paging::{FrameAllocator, OffsetPageTable, PageTable} - , - VirtAddr, -}; use allocation::page_alloc::FoundryOSFrameAllocator; +use spin::{Mutex, Once}; use units::MemoryUnits::*; +use x86_64::{ + VirtAddr, + registers::control::Cr3, + structures::paging::{OffsetPageTable, PageTable}, +}; pub const STACK_VIRTUAL_SPACE: usize = 0x5555_5555_0000; // start address of the memory space where we store allocated stacks pub const HEAP_VIRTUAL_SPACE: usize = 0x4444_4444_0000; // start address of heap allocated memory pub const HEAP_SIZE: usize = MiB(1).to_bytes(); - pub static FRAME_ALLOCATOR: Once> = Once::new(); pub static OFFSET_PAGE_TABLE: Once> = Once::new(); /// Returns a mutable reference to the current level 4 page table. @@ -25,7 +24,9 @@ pub static OFFSET_PAGE_TABLE: Once> = Once::new(); /// The caller must ensure that the level 4 page table is not modified /// simultaneously. The caller must also ensure that the physical memory offset /// is correct, to ensure that the correct virtual address is constructed. -unsafe fn active_l4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable { +unsafe fn active_l4_table( + physical_memory_offset: VirtAddr, +) -> &'static mut PageTable { let (level_4_frame, _) = Cr3::read(); let phys_addr = level_4_frame.start_address(); @@ -54,8 +55,8 @@ unsafe fn active_l4_table(physical_memory_offset: VirtAddr) -> &'static mut Page pub fn init_page_table(physical_memory_offset: VirtAddr) { unsafe { let l4_table = active_l4_table(physical_memory_offset); - let offset_table = OffsetPageTable::new(l4_table, physical_memory_offset); + let offset_table = + OffsetPageTable::new(l4_table, physical_memory_offset); OFFSET_PAGE_TABLE.call_once(|| Mutex::new(offset_table)); } } - diff --git a/kernel/src/arch/x86_64/memory/units.rs b/kernel/src/arch/x86_64/memory/units.rs index 4d24d50..7129ab8 100644 --- a/kernel/src/arch/x86_64/memory/units.rs +++ b/kernel/src/arch/x86_64/memory/units.rs @@ -30,7 +30,7 @@ impl MemoryUnits { pub const fn convert(&mut self) { match self { Self::B(b) if *b > 1024 => *self = Self::KiB(*b / 1024), - Self::KiB(kib) if *kib > 1024 => *self = Self::MiB(*kib / 1024), + Self::KiB(kib) if *kib > 1024 => *self = Self::MiB(*kib / 1024), Self::MiB(mib) if *mib > 1024 => *self = Self::GiB(*mib / 1024), _ => (), } @@ -46,4 +46,4 @@ impl core::fmt::Display for MemoryUnits { Self::GiB(gib) => write!(f, "{} GiB", gib), } } -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/processing/async_io/task.rs b/kernel/src/arch/x86_64/processing/async_io/task.rs index e522af0..c2ccf20 100644 --- a/kernel/src/arch/x86_64/processing/async_io/task.rs +++ b/kernel/src/arch/x86_64/processing/async_io/task.rs @@ -2,7 +2,6 @@ //! //! Written by @zxq5 for the most part with code from //! [here](https://github.com/phil-opp/blog_os/). -//! use alloc::boxed::Box; use alloc::collections::BTreeMap; @@ -81,9 +80,9 @@ impl Executor { Some(task) => task, None => continue, // task no longer exists }; - let waker = waker_cache - .entry(task_id) - .or_insert_with(|| TaskWaker::new_waker(task_id, task_queue.clone())); + let waker = waker_cache.entry(task_id).or_insert_with(|| { + TaskWaker::new_waker(task_id, task_queue.clone()) + }); let mut context = Context::from_waker(waker); match task.poll(&mut context) { Poll::Ready(()) => { @@ -129,7 +128,10 @@ impl TaskWaker { self.task_queue.push(self.task_id).expect("task_queue full"); } - fn new_waker(task_id: TaskId, task_queue: Arc>) -> Waker { + fn new_waker( + task_id: TaskId, + task_queue: Arc>, + ) -> Waker { Waker::from(Arc::new(Self { task_id, task_queue, diff --git a/kernel/src/arch/x86_64/processing/mod.rs b/kernel/src/arch/x86_64/processing/mod.rs index 01f827c..b30ed57 100644 --- a/kernel/src/arch/x86_64/processing/mod.rs +++ b/kernel/src/arch/x86_64/processing/mod.rs @@ -1,3 +1,4 @@ +#![expect(unused)] pub mod async_io; -pub mod threading; mod taskrunner; +pub mod threading; diff --git a/kernel/src/arch/x86_64/processing/taskrunner/mod.rs b/kernel/src/arch/x86_64/processing/taskrunner/mod.rs index 0198236..7b041a1 100644 --- a/kernel/src/arch/x86_64/processing/taskrunner/mod.rs +++ b/kernel/src/arch/x86_64/processing/taskrunner/mod.rs @@ -6,7 +6,7 @@ pub struct Task { } impl Task { - pub fn new() {} + // pub const fn new() {} - pub fn run() {} -} \ No newline at end of file + pub const fn run() {} +} diff --git a/kernel/src/arch/x86_64/processing/threading/mod.rs b/kernel/src/arch/x86_64/processing/threading/mod.rs index 2aa540f..db5bf89 100644 --- a/kernel/src/arch/x86_64/processing/threading/mod.rs +++ b/kernel/src/arch/x86_64/processing/threading/mod.rs @@ -1,5 +1,5 @@ -use x86_64::VirtAddr; use crate::arch::x86_64::memory::allocation::stack_alloc::StackBounds; +use x86_64::VirtAddr; mod switch; @@ -10,8 +10,6 @@ pub struct Thread { stack_bounds: Option, } - - #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct ThreadId(u64); diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 1a692bc..a74060b 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -12,17 +12,14 @@ )] extern crate alloc; -use crate::{ - arch::x86_64::memory::init_page_table, - prelude::*, -}; +use crate::arch::x86_64::cpu::apic::enable_apic; +use crate::{arch::x86_64::memory::init_page_table, prelude::*}; use arch::x86_64::memory::allocation::heap_alloc::init_heap; +use arch::x86_64::memory::allocation::page_alloc::FoundryOSFrameAllocator; use arch::x86_64::memory::mapping; use core::arch::asm; use limine::BaseRevision; use x86_64::VirtAddr; -use arch::x86_64::memory::allocation::page_alloc::FoundryOSFrameAllocator; -use crate::arch::x86_64::cpu::apic::enable_apic; pub mod arch; pub mod resources; @@ -33,15 +30,18 @@ pub mod util; pub mod prelude { pub use crate::std::io::{_print, _print_log, _serial_write}; pub use crate::{ - print, print_log, printerr, println, println_log, printlnerr, serial_print, serial_println, + print, print_log, printerr, println, println_log, printlnerr, + serial_print, serial_println, }; } /// Sets the base revision to the latest revision supported by the crate. /// See specification for further info. -/// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler. +/// Be sure to mark all limine requests with #[used], otherwise they may be +/// removed by the compiler. #[used] -// The .requests section allows limine to find the requests faster and more safely. +// The .requests section allows limine to find the requests faster and more +// safely. #[unsafe(link_section = ".requests")] static BASE_REVISION: BaseRevision = BaseRevision::new(); @@ -86,7 +86,8 @@ pub fn boot() -> Result<(), &'static str> { println_log!("[Success]"); print_log!(" Initialising Memory Subsystem... "); - let physical_memory_offset = VirtAddr::new(*mapping::PHYSICAL_MEMORY_OFFSET); + let physical_memory_offset = + VirtAddr::new(*mapping::PHYSICAL_MEMORY_OFFSET); init_page_table(physical_memory_offset); println_log!("[Success]"); diff --git a/kernel/src/std/application.rs b/kernel/src/std/application.rs index 7131253..7976172 100644 --- a/kernel/src/std/application.rs +++ b/kernel/src/std/application.rs @@ -8,7 +8,10 @@ pub mod window; pub trait Application { type Output; - fn run(&mut self, args: Vec) -> impl Future> + Send; + fn run( + &mut self, + args: Vec, + ) -> impl Future> + Send; } #[derive(Debug)] diff --git a/kernel/src/std/application/frame.rs b/kernel/src/std/application/frame.rs index a1cdfb6..b8a6346 100644 --- a/kernel/src/std/application/frame.rs +++ b/kernel/src/std/application/frame.rs @@ -11,20 +11,31 @@ pub struct Frame<'f> { impl<'a> Frame<'a> { pub fn new(window: &'a Window) -> Self { Self { - data: vec![vec![Colour::Black; window.dimensions().x()]; window.dimensions().y()], + data: vec![ + vec![Colour::Black; window.dimensions().x()]; + window.dimensions().y() + ], window, } } pub fn render(&self) -> Result<(), RenderError> { - let data: Vec<&[Colour]> = self.data.iter().map(|v| v.as_slice()).collect::>(); + let data: Vec<&[Colour]> = + self.data.iter().map(|v| v.as_slice()).collect::>(); self.window .render(data.as_slice()) .map_err(|_| RenderError::Generic) } - pub fn write_pixel(&mut self, x: usize, y: usize, color: Colour) -> Result<(), RenderError> { - if x >= self.window.dimensions().x() || y >= self.window.dimensions().y() { + pub fn write_pixel( + &mut self, + x: usize, + y: usize, + color: Colour, + ) -> Result<(), RenderError> { + if x >= self.window.dimensions().x() + || y >= self.window.dimensions().y() + { return Err(RenderError::Generic); } self.data[y][x] = color; diff --git a/kernel/src/std/application/window.rs b/kernel/src/std/application/window.rs index 758cbf6..bcc4156 100644 --- a/kernel/src/std/application/window.rs +++ b/kernel/src/std/application/window.rs @@ -24,7 +24,8 @@ impl Window { } pub fn render(&self, _data: &[&[Colour]]) -> Result<(), RenderError> { - // TODO: error handling!! the kernel should return an error in some cases + // TODO: error handling!! the kernel should return an error in some + // cases if let Some(fb) = FRAMEBUFFER_WRITER.lock().as_mut() { fb.render_frame(_data); } diff --git a/kernel/src/std/ascii.rs b/kernel/src/std/ascii.rs index 1a37feb..97eb294 100644 --- a/kernel/src/std/ascii.rs +++ b/kernel/src/std/ascii.rs @@ -46,7 +46,11 @@ impl<'a> Writer<'a> { if line & (0x80 >> col) != 0 { for i in 0..scale { for j in 0..scale { - frame.write_pixel(pixel_x + i, pixel_y + j, Colour::White)?; + frame.write_pixel( + pixel_x + i, + pixel_y + j, + Colour::White, + )?; } } } diff --git a/kernel/src/std/io.rs b/kernel/src/std/io.rs index 4719ec5..c974bd7 100644 --- a/kernel/src/std/io.rs +++ b/kernel/src/std/io.rs @@ -6,16 +6,16 @@ pub use crate::arch::x86_64::drivers::{ pub mod stdin { use crate::arch::x86_64::drivers::{ ascii::WRITER, - keyboard::{ - get_keystroke_async, get_keystroke_optional, KeyStroke, - } + keyboard::{KeyStroke, get_keystroke_async, get_keystroke_optional}, }; use alloc::string::String; - /// Reads a line of input from standard input asynchronously, returning a `String` containing - /// the input line. Does not include the newline character at the end of the line. + /// Reads a line of input from standard input asynchronously, returning a + /// `String` containing the input line. Does not include the newline + /// character at the end of the line. /// - /// If the user presses the abort key (usually Ctrl+C), the returned string will be empty. + /// If the user presses the abort key (usually Ctrl+C), the returned string + /// will be empty. /// /// This function is currently unimplemented. pub async fn read_line() -> String { @@ -60,8 +60,8 @@ pub mod stdin { } } - /// Reads a character from standard input and blocks the current task until a character is - /// available. + /// Reads a character from standard input and blocks the current task until + /// a character is available. /// /// # Note /// @@ -70,7 +70,8 @@ pub mod stdin { get_keystroke_async().await } - /// Attempt to read a character from standard input without blocking the current task. + /// Attempt to read a character from standard input without blocking the + /// current task. /// /// If no character is available, returns `None`. /// diff --git a/kernel/src/util/editor.rs b/kernel/src/util/editor.rs index 594d2a8..baa454c 100644 --- a/kernel/src/util/editor.rs +++ b/kernel/src/util/editor.rs @@ -1,6 +1,7 @@ -use crate::serial_print; use crate::arch::x86_64::drivers::keyboard::{KeyStroke, get_keystroke_async}; use crate::resources::font::Font; +use crate::serial_print; +use crate::serial_println; use crate::std::application::frame::Frame; use crate::std::application::render::RenderError; use crate::std::application::window::Window; @@ -9,7 +10,6 @@ use crate::std::ascii::Writer; use crate::std::maths::geometry::Vec2; use alloc::string::{String, ToString}; use alloc::vec::Vec; -use crate::serial_println; pub struct Editor { cursor_line: usize, @@ -65,7 +65,10 @@ impl<'a> Editor { writer.render_glyph( &mut frame, - Vec2::new(col * width + Self::PADDING, line * height + Self::PADDING), + Vec2::new( + col * width + Self::PADDING, + line * height + Self::PADDING, + ), ch as u8, scale, )?; @@ -157,7 +160,10 @@ impl<'a> Editor { impl Application for Editor { type Output = (); - async fn run(&mut self, _args: Vec) -> Result { + async fn run( + &mut self, + _args: Vec, + ) -> Result { self.window.set_dimensions(Vec2::new(1280, 800)); self.window.set_position(Vec2::new(0, 0)); self.window.open(); @@ -167,7 +173,9 @@ impl Application for Editor { loop { if let Err(_err) = self.render().and_then(|frame| frame.render()) { // TODO: Handle error - return Err(Error::ApplicationFailed("Rendering failed".to_string())); + return Err(Error::ApplicationFailed( + "Rendering failed".to_string(), + )); } let keystroke = get_keystroke_async().await; diff --git a/libm/src/lib.rs b/libm/src/lib.rs index 7480206..7a30e03 100644 --- a/libm/src/lib.rs +++ b/libm/src/lib.rs @@ -80,7 +80,12 @@ impl FontBuilder { fn revision(data: &[u8]) -> u8 { if (data[0] as u16) << 8 | data[1] as u16 == Self::PSF1_MAGIC { 1 - } else if (data[0] as u32) << 24 | (data[1] as u32) << 16 | (data[2] as u32) << 8 | data[3] as u32 == Self::PSF2_MAGIC { + } else if (data[0] as u32) << 24 + | (data[1] as u32) << 16 + | (data[2] as u32) << 8 + | data[3] as u32 + == Self::PSF2_MAGIC + { 2 } else { 0 diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..f661675 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +wrap_comments = true +max_width = 80 +comment_width = 80 +format_code_in_doc_comments = true