From 884e9aa3cfb9feb57c39be908ce81a8886fcbda1 Mon Sep 17 00:00:00 2001 From: Arthur Beck Date: Sun, 16 Feb 2025 20:32:36 -0600 Subject: [PATCH] Worked on build script a bunch, added format script and formatted everything --- kernel/Cargo.toml | 4 - kernel/build | 43 ++++-- kernel/build.rs | 46 ++++-- kernel/expand | 3 - kernel/format | 7 + kernel/functions | 2 + kernel/src/arch_boot_entry/x86.rs | 160 ++++++++++++--------- kernel/src/common/mod.rs | 1 + kernel/src/kernel/arch/example_impl/mod.rs | 37 ++--- kernel/src/kernel/arch/mod.rs | 6 +- kernel/src/kernel/arch/x86/constants.rs | 2 +- kernel/src/kernel/arch/x86/egatext.rs | 18 ++- kernel/src/kernel/arch/x86/gdt.rs | 18 ++- kernel/src/kernel/arch/x86/interrupts.rs | 52 +++---- kernel/src/kernel/arch/x86/memory.rs | 14 +- kernel/src/kernel/arch/x86/mod.rs | 30 ++-- kernel/src/kernel/arch/x86/output.rs | 3 +- kernel/src/kernel/arch/x86/paging.rs | 9 +- kernel/src/kernel/arch/x86/ports.rs | 2 +- kernel/src/kernel/boot.rs | 17 ++- kernel/src/kernel/cfg.rs | 2 +- kernel/src/kernel/cmdline.rs | 16 ++- kernel/src/kernel/constants.rs | 2 +- kernel/src/kernel/display.rs | 35 +++-- kernel/src/kernel/errors.rs | 6 +- kernel/src/kernel/indep_boot_entry.rs | 12 +- kernel/src/kernel/mem.rs | 37 ++++- kernel/src/kernel/memsections.rs | 10 +- kernel/src/kernel/mod.rs | 10 +- kernel/src/kernel/multiboot2.rs | 21 ++- kernel/src/kernel/output.rs | 4 +- kernel/src/kernel/psfont.rs | 16 +-- kernel/src/kernel/util.rs | 20 +-- 33 files changed, 393 insertions(+), 272 deletions(-) delete mode 100755 kernel/expand create mode 100755 kernel/format diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index d114495..d8f16cc 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -21,7 +21,3 @@ path = "src/arch_boot_entry/x86.rs" [lib] name = "aphrodite" path = "src/kernel/mod.rs" - -[[test]] -name = "test_aphrodite" -path = "src/include/test.rs" diff --git a/kernel/build b/kernel/build index 02c5367..366d1b2 100755 --- a/kernel/build +++ b/kernel/build @@ -1,29 +1,33 @@ #!/bin/bash ( - set -o errexit -o pipefail -o noclobber + flags=$- + set -o pipefail -o noclobber - HAVE_GETOPT=true + HAVE_GETOPT="${HAVE_GETOPT:-true}" getopt --test > /dev/null && true - if [[ $? -ne 4 ]]; then + if [[ $? -ne 4 && $HAVE_GETOPT ]]; then if [[ -n "EXIT_WITHOUT_GETOPT" ]]; then - echo '`getopt --test` failed. Exiting.' + echo '[ERROR] `getopt --test` failed. Exiting.' exit 1 else - echo '`getopt --test` failed. Continuing and ignoring command line flags. (note that $1 will still be used for the target)' - echo '(to exit instead of ignoring, set the environment variable `EXIT_WITHOUT_GETOPT` to a non-null value)' + echo '[WARN] `getopt --test` failed. Continuing and ignoring command line flags. (note that $1 will still be used for the target)' + echo '[WARN] (to exit instead of ignoring, set the environment variable `EXIT_WITHOUT_GETOPT` to a non-null value)' HAVE_GETOPT=false fi fi + set -o errexit # put down here as getopt returns error code four if it's working, and it probably would work otherwise, but I'm not taking chances + check=false + format=false if [[ "$HAVE_GETOPT" = "true" ]]; then - LONGOPTS=check - OPTIONS=c + LONGOPTS=check,format + OPTIONS=cf PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") || ( - echo '`getopt` failed to parse command line arguments. Check the arguments passed.' + echo '[ERROR] Failed to parse command line arguments. If your getopt is broken, set HAVE_GETOPT=true.' exit 1 ) eval set -- "$PARSED" @@ -34,6 +38,10 @@ check=true shift ;; + -f|--format) + format=true + shift + ;; --) shift break @@ -44,6 +52,12 @@ ;; esac done + + if [[ $check == "true" && $format == "true" ]]; then + echo "[WARN] Both --check and --format were passed." + echo "[WARN] Interpretting as only --format, as format will also check that Aphrokern can compile." + check=false + fi fi export KERNEL_DIR=$(readlink -e .) @@ -79,11 +93,11 @@ function compile_one { target=$1 real_target=${!target} - real_target=$(basename $real_target) - echo "Compiling target $target(with rust target of $real_target)" if [[ $check = "true" ]]; then + echo "[INFO] Checking target $target(with rust target of $real_target)" cargo check --target "$real_target" --release -Zbuild-std=core,alloc --bin entrypoint_$target else + echo "[INFO] Compiling target $target(with rust target of $real_target)" cargo build --target "$real_target" --release -Zbuild-std=core,alloc --bin entrypoint_$target cp "target/$(echo $real_target | sed 's/\.json//')/release/entrypoint_$target" kernel-$target @@ -103,6 +117,12 @@ fi } + if [[ $format = "true" ]]; then + echo "[INFO] Formatting" + cargo fmt --all + exit 0 + fi + if [[ $# -ge 1 ]]; then echo "[INFO] Compiling only target $1" compile_one $1 @@ -114,4 +134,5 @@ done reset_version_vars + set +$flags ) \ No newline at end of file diff --git a/kernel/build.rs b/kernel/build.rs index c8ce001..0f79722 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -1,22 +1,42 @@ fn main() { let env = std::env::vars(); - + // Begin checks - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_DISABLE_MULTIBOOT2_SUPPORT, values("true", "false", none()))"#); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_DISABLE_MULTIBOOT2_SUPPORT, values("true", "false", none()))"# + ); println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_HALT_ON_PANIC, values("true", "false", none()))"#); println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_SPIN_ON_PANIC, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_WARN_ON_INVALID_LENGTH, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH, values("true", "false", none()))"#); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_EXIT_LOOP_ON_INVALID_LENGTH, values("true", "false", none()))"# + ); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH, values("true", "false", none()))"# + ); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_WARN_ON_INVALID_LENGTH, values("true", "false", none()))"# + ); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH, values("true", "false", none()))"# + ); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_DEBUG, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_INFO, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_WARN, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_ERROR, values("true", "false", none()))"#); - println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_FATAL, values("true", "false", none()))"#); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_DEBUG, values("true", "false", none()))"# + ); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_INFO, values("true", "false", none()))"# + ); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_WARN, values("true", "false", none()))"# + ); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_ERROR, values("true", "false", none()))"# + ); + println!( + r#"cargo:rustc-check-cfg=cfg(CONFIG_PREUSER_OUTPUT_FATAL, values("true", "false", none()))"# + ); println!(r#"cargo:rustc-check-cfg=cfg(CONFIG_BUILD_GRUB, values("true", "false", none()))"#); // End checks @@ -26,9 +46,9 @@ fn main() { for (var, val) in env { if !var.starts_with("CONFIG_") { - continue + continue; } println!("cargo:rerun-if-env-changed={}", var); println!("cargo:rustc-cfg={}=\"{}\"", var, val); } -} \ No newline at end of file +} diff --git a/kernel/expand b/kernel/expand deleted file mode 100755 index c198d22..0000000 --- a/kernel/expand +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -RUSTFLAGS='-Clink-arg=--script=link.x' cargo expand --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint_x86 \ No newline at end of file diff --git a/kernel/format b/kernel/format new file mode 100755 index 0000000..94ec0a4 --- /dev/null +++ b/kernel/format @@ -0,0 +1,7 @@ +#!/bin/bash + +( + set -o errexit -o pipefail -o noclobber + + ./build --format $! +) \ No newline at end of file diff --git a/kernel/functions b/kernel/functions index b0ef352..8507235 100644 --- a/kernel/functions +++ b/kernel/functions @@ -1,3 +1,5 @@ +#!/bin/bash + function get_version() { local TEMP_SUFFIX if git add . && git diff --quiet && git diff --cached --quiet diff --git a/kernel/src/arch_boot_entry/x86.rs b/kernel/src/arch_boot_entry/x86.rs index 316b4dc..a0d420c 100644 --- a/kernel/src/arch_boot_entry/x86.rs +++ b/kernel/src/arch_boot_entry/x86.rs @@ -9,26 +9,27 @@ #![feature(cfg_match)] #![feature(formatting_options)] -use core::{arch::asm, ffi::CStr, panic::PanicInfo}; use core::fmt::Debug; +use core::{arch::asm, ffi::CStr, panic::PanicInfo}; -use aphrodite::boot::{BootInfo, MemoryMapping}; -use aphrodite::multiboot2::{FramebufferInfo, MemoryMap, MemorySection, RawMemoryMap, RootTag, Tag}; +use aphrodite::arch::egatext; use aphrodite::arch::output::*; -use aphrodite::arch::egatext as egatext; -use aphrodite::output::*; +use aphrodite::boot::{BootInfo, MemoryMapping}; use aphrodite::display::COLOR_DEFAULT; +use aphrodite::multiboot2::{ + FramebufferInfo, MemoryMap, MemorySection, RawMemoryMap, RootTag, Tag, +}; +use aphrodite::output::*; #[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))] #[unsafe(link_section = ".bootheader")] #[unsafe(no_mangle)] static MULTIBOOT2_HEADER: [u8; 24] = [ - 0xd6, 0x50, 0x52, 0xe8, // Magic number + 0xd6, 0x50, 0x52, 0xe8, // Magic number 0x00, 0x00, 0x00, 0x00, // Architecture - 0x18, 0x00, 0x00, 0x00, // Size + 0x18, 0x00, 0x00, 0x00, // Size 0x12, 0xaf, 0xad, 0x17, // Checksum - - 0x00, 0x00, // End tag + 0x00, 0x00, // End tag 0x00, 0x00, // Flags 0x08, 0x00, 0x00, 0x00, // Size ]; @@ -45,14 +46,15 @@ static mut MM: MemoryMap = MemoryMap { sections: &[], }; -static mut FBI: aphrodite::arch::egatext::FramebufferInfo = aphrodite::arch::egatext::FramebufferInfo { - address: 0, - pitch: 0, - width: 0, - height: 0, - bpp: 0, - change_cursor: false, -}; +static mut FBI: aphrodite::arch::egatext::FramebufferInfo = + aphrodite::arch::egatext::FramebufferInfo { + address: 0, + pitch: 0, + width: 0, + height: 0, + bpp: 0, + change_cursor: false, + }; // The magic number in eax. 0x36D76289 for multiboot2. static mut MAGIC: u32 = 0xFFFFFFFF; @@ -61,7 +63,8 @@ static mut MAGIC: u32 = 0xFFFFFFFF; #[unsafe(no_mangle)] #[aphrodite_proc_macros::kernel_item(ArchBootEntry)] extern "C" fn _start() -> ! { - unsafe { // Copy values provided by the bootloader out + unsafe { + // Copy values provided by the bootloader out // Aphrodite bootloaders pass values in eax and ebx, however rust doesn't know that it can't overwrite those. // (if necessary, we'll store all of the registers for other bootloaders and identify which one it is later) // we force using ebx and eax as the output of an empty assembly block to let it know. @@ -81,7 +84,8 @@ extern "C" fn _start() -> ! { unsafe { match MAGIC { #[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))] - 0x36D76289 => { // Multiboot2 + 0x36D76289 => { + // Multiboot2 RT = O as *const RootTag; // This is unsafe rust! We can do whatever we want! *manical laughter* sdebugs("Total boot info length is "); @@ -92,11 +96,12 @@ extern "C" fn _start() -> ! { sdebugbnp(&aphrodite::usize_as_u8_slice(O as usize)); sdebugunp(b'\n'); - if (*RT).total_len<16 { // Size of root tag+size of terminating tag. Something's up. + if (*RT).total_len < 16 { + // Size of root tag+size of terminating tag. Something's up. panic!("total length < 16") } - let end_addr = O as usize+(*RT).total_len as usize; + let end_addr = O as usize + (*RT).total_len as usize; sdebugunp(b'\n'); @@ -104,7 +109,7 @@ extern "C" fn _start() -> ! { ptr += size_of::(); let mut current_tag = core::ptr::read_volatile(ptr as *const Tag); - + loop { sdebugs("Tag address is "); sdebugbnpln(&aphrodite::usize_as_u8_slice(ptr)); @@ -114,26 +119,34 @@ extern "C" fn _start() -> ! { sdebugs("Tag length is "); sdebugbnpln(&aphrodite::u32_as_u8_slice(current_tag.tag_len)); - + match current_tag.tag_type { - 0 => { // Ending tag - if current_tag.tag_len != 8 { // Unexpected size, something is probably up + 0 => { + // Ending tag + if current_tag.tag_len != 8 { + // Unexpected size, something is probably up panic!("size of ending tag != 8"); } - break - }, - 4 => { // Basic memory information - if current_tag.tag_len != 16 { // Unexpected size, something is probably up + break; + } + 4 => { + // Basic memory information + if current_tag.tag_len != 16 { + // Unexpected size, something is probably up panic!("size of basic memory information tag != 16"); } - }, - 5 => { // BIOS boot device, ignore - if current_tag.tag_len != 20 { // Unexpected size, something is probably up + } + 5 => { + // BIOS boot device, ignore + if current_tag.tag_len != 20 { + // Unexpected size, something is probably up panic!("size of bios boot device tag != 20"); } - }, - 1 => { // Command line - if current_tag.tag_len < 8 { // Unexpected size, something is probably up + } + 1 => { + // Command line + if current_tag.tag_len < 8 { + // Unexpected size, something is probably up panic!("size of command line tag < 8"); } let cstring = CStr::from_ptr((ptr + 8) as *const i8); @@ -141,13 +154,16 @@ extern "C" fn _start() -> ! { BI.cmdline = Some(cstring.to_str().unwrap()); // ...before the BootInfo's commandline is set. - }, - 6 => { // Memory map tag - if current_tag.tag_len < 16 { // Unexpected size, something is probably up + } + 6 => { + // Memory map tag + if current_tag.tag_len < 16 { + // Unexpected size, something is probably up panic!("size of memory map tag < 16"); } let rawmemorymap: *mut RawMemoryMap = core::ptr::from_raw_parts_mut( - ptr as *mut u8, (current_tag.tag_len / *((ptr + 8usize) as *const u32)) as usize + ptr as *mut u8, + (current_tag.tag_len / *((ptr + 8usize) as *const u32)) as usize, ); // The end result of the above is creating a *const RawMemoryMap that has the same address as current_tag // and has all of the [aphrodite::multiboot2::MemorySection]s for the memory map @@ -169,12 +185,14 @@ extern "C" fn _start() -> ! { size_pages: 1, page_size: MM.mem_size(), sections: MM.sections, - idx: 0 + idx: 0, }; BI.memory_map = Some(mm2); - }, - 2 => { // Bootloader name - if current_tag.tag_len < 8 { // Unexpected size, something is probably up + } + 2 => { + // Bootloader name + if current_tag.tag_len < 8 { + // Unexpected size, something is probably up panic!("size of command line tag < 8"); } let cstring = CStr::from_ptr((ptr + 8) as *const i8); @@ -182,21 +200,26 @@ extern "C" fn _start() -> ! { BI.bootloader_name = Some(cstring.to_str().unwrap()); // ...before the BootInfo's bootloader_name is set. - }, - 8 => { // Framebuffer info - if current_tag.tag_len < 32 { // Unexpected size, something is probably up + } + 8 => { + // Framebuffer info + if current_tag.tag_len < 32 { + // Unexpected size, something is probably up panic!("size of framebuffer info tag < 32"); } - let framebufferinfo: *const FramebufferInfo = (ptr as usize + size_of::()) as *const FramebufferInfo; + let framebufferinfo: *const FramebufferInfo = + (ptr as usize + size_of::()) as *const FramebufferInfo; match (*framebufferinfo).fb_type { - 0 => { // Indexed + 0 => { + // Indexed panic!("Indexed color is unimplemented"); - }, - 1 => { // RGB + } + 1 => { + // RGB panic!("RGB color is unimplemented"); - }, + } 2 => { // EGA Text - }, + } _ => { panic!("unknown color info type") } @@ -212,15 +235,16 @@ extern "C" fn _start() -> ! { change_cursor: false, }; BI.output = Some(&FBI) - }, - _ => { // Unknown/unimplemented tag type, ignore + } + _ => { + // Unknown/unimplemented tag type, ignore swarnings("Unknown tag type "); swarningbnpln(&aphrodite::u32_as_u8_slice(current_tag.tag_type)); } } sinfounp(b'\n'); ptr = (ptr + current_tag.tag_len as usize + 7) & !7; - if ptr>end_addr { + if ptr > end_addr { cfg_match! { all(CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH = "true", CONFIG_PREUSER_PANIC_ON_INVALID_LENGTH = "false") => { serrorsln("Current tag length would put pointer out-of-bounds; CONFIG_PREUSER_ERROR_ON_INVALID_LENGTH is set, continuing"); @@ -242,8 +266,9 @@ extern "C" fn _start() -> ! { } current_tag = core::ptr::read_volatile(ptr as *const Tag); } - }, - _ => { // Unknown bootloader, panic + } + _ => { + // Unknown bootloader, panic panic!("unknown bootloader"); } } @@ -261,10 +286,12 @@ extern "C" fn _start() -> ! { sdebugs("Framebuffer pitch: "); sdebugbnpln(&aphrodite::u32_as_u8_slice(framebuffer_info.pitch)); sdebugs("Framebuffer address: "); - sdebugbnpln(&aphrodite::usize_as_u8_slice(framebuffer_info.address as usize)); + sdebugbnpln(&aphrodite::usize_as_u8_slice( + framebuffer_info.address as usize, + )); sdebugs("Framebuffer bpp: "); sdebugbnpln(&aphrodite::u8_as_u8_slice(framebuffer_info.bpp)); - + sdebugsln("Beginning test output to screen..."); let ega: &dyn aphrodite::display::TextDisplay = &framebuffer_info; @@ -293,12 +320,13 @@ fn halt_on_panic(info: &PanicInfo) -> ! { sfatalsnp(":"); sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line())); sfatalsnp(":"); - sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column())); - sfatalsnp(": "); + sfatalbnpln(&aphrodite::u32_as_u8_slice( + info.location().unwrap().column(), + )); } else { sfatals("Panic: "); } - let mut formatter = FormattingOptions::new().create_formatter(unsafe { &mut FBI }); + let mut formatter = FormattingOptions::new().create_formatter(unsafe { &mut FBI }); let _ = info.message().fmt(&mut formatter); aphrodite::arch::interrupts::disable_interrupts(); unsafe { @@ -308,7 +336,7 @@ fn halt_on_panic(info: &PanicInfo) -> ! { #[unsafe(link_section = ".panic")] #[panic_handler] -#[cfg(all(CONFIG_SPIN_ON_PANIC = "true", CONFIG_PREUSER_HALT_ON_PANIC = "false"))] +#[cfg(all(CONFIG_SPIN_ON_PANIC = "true", CONFIG_HALT_ON_PANIC = "false"))] fn spin_on_panic(info: &PanicInfo) -> ! { if info.location().is_some() { sfatals("Panic at "); @@ -316,7 +344,9 @@ fn spin_on_panic(info: &PanicInfo) -> ! { sfatalsnp(":"); sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line())); sfatalsnp(":"); - sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column())); + sfatalbnp(&aphrodite::u32_as_u8_slice( + info.location().unwrap().column(), + )); sfatalsnp(": "); } else { sfatals("Panic: "); @@ -329,4 +359,4 @@ fn spin_on_panic(info: &PanicInfo) -> ! { } aphrodite::arch::interrupts::disable_interrupts(); loop {} -} \ No newline at end of file +} diff --git a/kernel/src/common/mod.rs b/kernel/src/common/mod.rs index e69de29..8b13789 100644 --- a/kernel/src/common/mod.rs +++ b/kernel/src/common/mod.rs @@ -0,0 +1 @@ + diff --git a/kernel/src/kernel/arch/example_impl/mod.rs b/kernel/src/kernel/arch/example_impl/mod.rs index 2b50065..262d2d1 100644 --- a/kernel/src/kernel/arch/example_impl/mod.rs +++ b/kernel/src/kernel/arch/example_impl/mod.rs @@ -1,12 +1,13 @@ //! An example implementation of an architecture. DO NOT use this module! //! Everything must be implemented via either kernel items, or for constants //! making them public. -//! +//! //! This is commented out for obvious reasons, but make sure to have this at //! the top of the all files in your arch(with "arch" replaced with the //! actual architecture, of course): //! #![cfg(any(target_arch = "arch"))] +/// Returns the most specific architecture available. pub const fn get_arch() -> super::Architecture { super::Architecture::ExampleDummy } @@ -15,11 +16,11 @@ pub mod interrupts { //! Interrupt-related functions. use core::mem::MaybeUninit; - + /// Must be a u16 or castable to a u16. /// Value used in x86 shown here as an example. pub const USER_SYSCALL_VECTOR: u16 = 0xA0; - + /// Returns whether interrupts are enabled or not. #[aphrodite_proc_macros::kernel_item(InterruptsCheck)] fn interrupts_enabled() -> bool { @@ -28,15 +29,11 @@ pub mod interrupts { /// Enables interrupts. #[aphrodite_proc_macros::kernel_item(InterruptsEnable)] - fn enable_interrupts() { - - } + fn enable_interrupts() {} /// Disables interrupts. #[aphrodite_proc_macros::kernel_item(InterruptsDisable)] - fn disable_interrupts() { - - } + fn disable_interrupts() {} /// Disables interrupts and a value that can be used to restore them /// with [restore_irq]. @@ -47,21 +44,17 @@ pub mod interrupts { /// Restores interrupts after a [pop_irq] call. #[aphrodite_proc_macros::kernel_item(InterruptsRestore)] - fn restore_irq(irq: u64) { - irq; - } + fn restore_irq(_irq: u64) {} /// Activates an IDT. #[aphrodite_proc_macros::kernel_item(ActivateIDT)] - fn activate_idt(idt: Idt) { - idt; - } + fn activate_idt(_idt: Idt) {} /// An IDT. #[derive(Clone, Copy)] pub struct Idt { vectors: [u16; 256], - funcs: [MaybeUninit; 256], + funcs: [MaybeUninit; 256], len: usize, } @@ -70,14 +63,14 @@ pub mod interrupts { #[derive(Clone, Copy)] pub struct IdtBuilder { vectors: [u16; 256], - funcs: [MaybeUninit; 256], + funcs: [MaybeUninit; 256], idx: usize, } impl IdtBuilder { /// Start creating a new IDT. pub fn new() -> Self { - IdtBuilder { + IdtBuilder { vectors: [0; 256], funcs: [MaybeUninit::uninit(); 256], idx: 0, @@ -95,7 +88,7 @@ pub mod interrupts { Idt { vectors: self.vectors, funcs: self.funcs, - len: self.idx + len: self.idx, } } } @@ -106,9 +99,3 @@ pub mod output { //! LOT of output functions must be implemented. Using macros to //! implement these is HIGHLY recommended. } - -/// Returns whether paging is available for this architecture. -#[aphrodite_proc_macros::kernel_item(PagingAvailabe)] -pub fn paging_available() -> bool { - true -} \ No newline at end of file diff --git a/kernel/src/kernel/arch/mod.rs b/kernel/src/kernel/arch/mod.rs index 8498953..88440fa 100644 --- a/kernel/src/kernel/arch/mod.rs +++ b/kernel/src/kernel/arch/mod.rs @@ -1,9 +1,9 @@ //! Arch-specific code. This module re-exports all code from the architecture being used. -//! +//! //! See [example_impl] for everything that has to be implemented by an architecture module. -mod x86; pub mod example_impl; +mod x86; pub use x86::*; @@ -16,4 +16,4 @@ pub enum Architecture { ExampleDummy, /// 32-bit x86. X86, -} \ No newline at end of file +} diff --git a/kernel/src/kernel/arch/x86/constants.rs b/kernel/src/kernel/arch/x86/constants.rs index 53cf9b6..b6e57c8 100644 --- a/kernel/src/kernel/arch/x86/constants.rs +++ b/kernel/src/kernel/arch/x86/constants.rs @@ -2,4 +2,4 @@ #![cfg(any(target_arch = "x86"))] /// The assembly port number to output debug messages to. -pub(super) const DEBUG_PORT: u16 = 0xE9; \ No newline at end of file +pub(super) const DEBUG_PORT: u16 = 0xE9; diff --git a/kernel/src/kernel/arch/x86/egatext.rs b/kernel/src/kernel/arch/x86/egatext.rs index 89e383f..e4a7a50 100644 --- a/kernel/src/kernel/arch/x86/egatext.rs +++ b/kernel/src/kernel/arch/x86/egatext.rs @@ -34,7 +34,12 @@ impl core::fmt::Write for FramebufferInfo { impl crate::display::TextDisplay for FramebufferInfo { /// Writes a character to the screen. - fn write_char(&self, mut pos: (u32, u32), char: u8, color: Color) -> Result<(), crate::Error<'static>> { + fn write_char( + &self, + mut pos: (u32, u32), + char: u8, + color: Color, + ) -> Result<(), crate::Error<'static>> { let mut clr = color.0; if color.1 { match clr { @@ -44,18 +49,18 @@ impl crate::display::TextDisplay for FramebufferInfo { } } let color = clr; - if pos.0>self.width { + if pos.0 > self.width { return Err(crate::Error::new("Invalid X position", ERR_INVALID_X)); } - if pos.1>self.height { + if pos.1 > self.height { return Err(crate::Error::new("Invalid Y position", ERR_INVALID_Y)); } unsafe { let mut addr = self.address as usize; - addr += (pos.1*self.pitch) as usize; - addr += (pos.0*(self.bpp as u32/8)) as usize; + addr += (pos.1 * self.pitch) as usize; + addr += (pos.0 * (self.bpp as u32 / 8)) as usize; let base_ptr = addr as *mut u16; - (*base_ptr) = ((color as u16)<<8) | (char as u16); + (*base_ptr) = ((color as u16) << 8) | (char as u16); } pos.1 += 1; if self.change_cursor { @@ -69,7 +74,6 @@ impl crate::display::TextDisplay for FramebufferInfo { } impl FramebufferInfo { - /// Disables the cursor. pub fn disable_cursor(self) { super::ports::outb(0x3D4, 0x0A); diff --git a/kernel/src/kernel/arch/x86/gdt.rs b/kernel/src/kernel/arch/x86/gdt.rs index e2f3112..73c5a8e 100644 --- a/kernel/src/kernel/arch/x86/gdt.rs +++ b/kernel/src/kernel/arch/x86/gdt.rs @@ -5,15 +5,18 @@ use core::alloc::Layout; use alloc::vec::Vec; /// Writes a series of GDT entries to an allocated section of memory and returns a pointer. -pub unsafe fn write_gdt_entries(entries: Vec) -> Result<*const [u8], crate::Error<'static>> { - let mut mem = unsafe { alloc::alloc::alloc(Layout::from_size_align(8*entries.len(), 1).unwrap()) }; +pub unsafe fn write_gdt_entries( + entries: Vec, +) -> Result<*const [u8], crate::Error<'static>> { + let mut mem = + unsafe { alloc::alloc::alloc(Layout::from_size_align(8 * entries.len(), 1).unwrap()) }; for ele in &entries { let ele: &GDTEntry = ele; unsafe { ele.write_to_addr(mem as *mut ())? } mem = (mem as usize + 8) as *mut u8; } - Ok(core::ptr::from_raw_parts(mem, 8*entries.len())) + Ok(core::ptr::from_raw_parts(mem, 8 * entries.len())) } /// A GDT entry. @@ -35,7 +38,10 @@ const GDT_WRITE_ADDR_INVALID_LIMIT: i16 = -1; impl GDTEntry { const unsafe fn write_to_addr(self, ptr: *mut ()) -> Result<(), crate::Error<'static>> { if self.limit > 0xFFFFF { - return Err(crate::Error::new("Invalid GDT entry limit(more than 0xFFFFF)", GDT_WRITE_ADDR_INVALID_LIMIT)); + return Err(crate::Error::new( + "Invalid GDT entry limit(more than 0xFFFFF)", + GDT_WRITE_ADDR_INVALID_LIMIT, + )); } let mut serialized = (0u64).to_ne_bytes(); @@ -55,7 +61,7 @@ impl GDTEntry { unsafe { core::ptr::write(ptr as *mut [u8; 8], serialized); } - + Ok(()) } -} \ No newline at end of file +} diff --git a/kernel/src/kernel/arch/x86/interrupts.rs b/kernel/src/kernel/arch/x86/interrupts.rs index cbe7f27..5e6d9b3 100644 --- a/kernel/src/kernel/arch/x86/interrupts.rs +++ b/kernel/src/kernel/arch/x86/interrupts.rs @@ -2,7 +2,11 @@ #![cfg(any(target_arch = "x86"))] #![allow(static_mut_refs)] -use core::{alloc::{Allocator, Layout}, arch::asm, mem::MaybeUninit}; +use core::{ + alloc::{Allocator, Layout}, + arch::asm, + mem::MaybeUninit, +}; /// The syscall vector. pub const USER_SYSCALL_VECTOR: u16 = 0xA0; @@ -23,9 +27,7 @@ pub fn interrupts_enabled() -> bool { /// Disables interrupts. #[aphrodite_proc_macros::kernel_item(InterruptsDisable)] pub fn disable_interrupts() { - unsafe { - asm!("cli") - } + unsafe { asm!("cli") } } /// PoppedInterrupts implements drop and restores the interrupts upon being dropped. @@ -62,9 +64,7 @@ pub fn restore_irq(flags: PoppedInterrupts) { asm!( "push {0:e}", in(reg) flags ); - asm!( - "popf" - ); + asm!("popf"); } } @@ -73,7 +73,7 @@ pub fn restore_irq(flags: PoppedInterrupts) { #[repr(C)] struct IDTR { base: *const u8, - size: usize + size: usize, } unsafe impl Send for IDTR {} @@ -83,53 +83,54 @@ unsafe impl Sync for IDTR {} fn load_idt(base: *const u8, size: usize) { static mut IDTR: MaybeUninit = MaybeUninit::uninit(); unsafe { - IDTR.write(IDTR { - base, - size - }); - } - unsafe { - asm!("lidt {}", in(reg) IDTR.as_ptr() as usize) + IDTR.write(IDTR { base, size }); } + unsafe { asm!("lidt {}", in(reg) IDTR.as_ptr() as usize) } } /// Activate an IDT. #[aphrodite_proc_macros::kernel_item(ActivateIDT)] fn activate_idt(idt: Idt, alloc: crate::mem::MemoryMapAlloc) { - let mem = alloc.allocate(unsafe { Layout::from_size_align_unchecked(8*idt.len, 1) }).unwrap().as_mut_ptr(); + let _mem = alloc + .allocate(unsafe { Layout::from_size_align_unchecked(8 * idt.len, 1) }) + .unwrap() + .as_mut_ptr(); for i in 0..idt.len { - let vector = idt.vectors[i]; - let func = unsafe { idt.funcs[i].assume_init() } as usize as u64; - let user_callable = idt.user_callable[i]; - + let _vector = idt.vectors[i]; + let _func = unsafe { idt.funcs[i].assume_init() } as usize as u64; + let _user_callable = idt.user_callable[i]; } } +/// An Interrupt Descriptor Table. #[derive(Clone, Copy)] pub struct Idt { vectors: [u16; 256], - funcs: [MaybeUninit; 256], + funcs: [MaybeUninit; 256], user_callable: [bool; 256], len: usize, } +/// A builder of an [Idt]. #[derive(Clone, Copy)] pub struct IdtBuilder { vectors: [u16; 256], - funcs: [MaybeUninit; 256], + funcs: [MaybeUninit; 256], user_callable: [bool; 256], idx: usize, } impl IdtBuilder { + /// Create a new IdtBuilder. pub fn new() -> Self { - IdtBuilder { + IdtBuilder { vectors: [0; 256], funcs: [MaybeUninit::uninit(); 256], user_callable: [false; 256], idx: 0, } } + /// Add a function to this IdtBuilder. pub fn add_fn(&mut self, vector: u16, func: fn(), user_callable: bool) -> &mut Self { self.vectors[self.idx] = vector; self.funcs[self.idx].write(func); @@ -137,12 +138,13 @@ impl IdtBuilder { self.idx += 1; self } + /// Finish creating this IdtBuilder and return an [Idt]. pub fn finish(&self) -> Idt { Idt { vectors: self.vectors, funcs: self.funcs, user_callable: self.user_callable, - len: self.idx + len: self.idx, } } -} \ No newline at end of file +} diff --git a/kernel/src/kernel/arch/x86/memory.rs b/kernel/src/kernel/arch/x86/memory.rs index b309ee5..95384de 100644 --- a/kernel/src/kernel/arch/x86/memory.rs +++ b/kernel/src/kernel/arch/x86/memory.rs @@ -6,8 +6,9 @@ use alloc::{vec, vec::Vec}; use crate::memsections::*; -use super::gdt::{write_gdt_entries, GDTEntry}; +use super::gdt::{GDTEntry, write_gdt_entries}; +/// A list of memory sections. Create one with [MemorySectionBuilder]. pub struct MemorySections { sections: Vec, } @@ -100,11 +101,11 @@ unsafe impl crate::memsections::MemorySections for MemorySections { let gdtr = GDTR { address: ptr as *const u8 as usize as u32, - size: (ptr.len()-1) as u16 + size: (ptr.len() - 1) as u16, }; let addr = &gdtr as *const GDTR as *const () as usize as u32; - + asm!( "lgdt eax", in("eax") addr @@ -124,10 +125,10 @@ unsafe impl crate::memsections::MemorySections for MemorySections { } if entry.access & 0b11000 == 0b11000 && !code_set { - code_segment = i-1; + code_segment = i - 1; code_set = true; } else if entry.access & 0b10000 == 0b10000 && !data_set { - data_segment = i-1; + data_segment = i - 1; data_set = true; } } @@ -156,16 +157,19 @@ pub struct MemorySectionBuilder { } impl MemorySectionBuilder { + /// Create a new MemorySectionBuilder. pub fn new() -> Self { MemorySectionBuilder { sections: vec![] } } + /// Adds a section to this MemorySectionBuilder. pub fn add_section(&mut self, section: MemorySection) -> &mut Self { self.sections.push(section); self } + /// Finishes this MemorySectionBuilder and returns a MemorySections. pub fn finish(self) -> MemorySections { MemorySections { sections: self.sections, diff --git a/kernel/src/kernel/arch/x86/mod.rs b/kernel/src/kernel/arch/x86/mod.rs index 116141e..1515851 100644 --- a/kernel/src/kernel/arch/x86/mod.rs +++ b/kernel/src/kernel/arch/x86/mod.rs @@ -3,13 +3,13 @@ use core::arch::asm; -pub mod interrupts; -pub mod ports; -pub mod output; pub mod egatext; -pub mod paging; mod gdt; +pub mod interrupts; pub mod memory; +pub mod output; +pub mod paging; +pub mod ports; mod constants; @@ -17,15 +17,11 @@ pub(self) use constants::*; use interrupts::{pop_irq, restore_irq}; use ports::{inb, outb}; +/// Returns the most specific architecture available. pub const fn get_arch() -> super::Architecture { super::Architecture::X86 } -#[aphrodite_proc_macros::kernel_item(PagingAvailabe)] -pub fn paging_available() -> bool { - true -} - /// Returns information from the CPUID command in the form /// (ebx, edx, ecx). pub fn cpuid(id: u32) -> (u32, u32, u32) { @@ -70,12 +66,12 @@ pub fn test_a20() -> bool { /// Waits for a keyboard command to complete. pub fn wait_for_keyboard_cmd() { - while inb(0x64)&0b10 > 1 {} + while inb(0x64) & 0b10 > 1 {} } /// Waits for there to be data to read from the keyboard. pub fn wait_for_keyboard_data() { - while inb(0x64)&0b1 == 0 {} + while inb(0x64) & 0b1 == 0 {} } /// Sends a keyboard command. @@ -111,7 +107,7 @@ pub fn enable_a20_keyboard() { send_keyboard_cmd(0xD1); // write to output wait_for_keyboard_cmd(); - send_keyboard_data(a|2); + send_keyboard_data(a | 2); wait_for_keyboard_cmd(); send_keyboard_cmd(0xAE); // enable keyboard @@ -123,8 +119,8 @@ pub fn enable_a20_keyboard() { /// Note that this may not work or do something unexpected. pub fn enable_a20_fasta20() { let mut a = inb(0x92); - if a&0b10 > 0 { - return + if a & 0b10 > 0 { + return; } a |= 0b10; a &= 0xFE; @@ -145,7 +141,7 @@ pub fn enable_a20() -> bool { enable_a20_keyboard(); let mut i = 0u32; - while (!test_a20()) && i<10000 { + while (!test_a20()) && i < 10000 { i += 1; } @@ -155,7 +151,7 @@ pub fn enable_a20() -> bool { enable_a20_ee_port(); let mut i = 0u32; - while (!test_a20()) && i<10000 { + while (!test_a20()) && i < 10000 { i += 1; } @@ -165,7 +161,7 @@ pub fn enable_a20() -> bool { enable_a20_fasta20(); let mut i = 0u32; - while (!test_a20()) && i<10000 { + while (!test_a20()) && i < 10000 { i += 1; } diff --git a/kernel/src/kernel/arch/x86/output.rs b/kernel/src/kernel/arch/x86/output.rs index f194121..d136571 100644 --- a/kernel/src/kernel/arch/x86/output.rs +++ b/kernel/src/kernel/arch/x86/output.rs @@ -94,7 +94,7 @@ macro_rules! message_funcs { ports::outb(super::DEBUG_PORT, s); } } - } + }; } message_funcs!(debug, "[DEBUG] ", CONFIG_PREUSER_OUTPUT_DEBUG); @@ -103,4 +103,3 @@ message_funcs!(warning, "[WARN] ", CONFIG_PREUSER_OUTPUT_WARN); message_funcs!(error, "[ERROR] ", CONFIG_PREUSER_OUTPUT_ERROR); message_funcs!(fatal, "[FATAL] ", CONFIG_PREUSER_OUTPUT_FATAL); message_funcs!(output, "", NONE); - diff --git a/kernel/src/kernel/arch/x86/paging.rs b/kernel/src/kernel/arch/x86/paging.rs index 94137ca..a38022c 100644 --- a/kernel/src/kernel/arch/x86/paging.rs +++ b/kernel/src/kernel/arch/x86/paging.rs @@ -4,8 +4,11 @@ use core::arch::asm; use aphrodite_proc_macros::kernel_item; +/// One page directory entry. Use [PageDirectoryEntry::create_fourmb] or [PageDirectoryEntry::create_other] to make these. pub enum PageDirectoryEntry { + /// A four megabyte page. FourMb(u32), + /// A smaller page. Other(u32), } @@ -114,11 +117,9 @@ impl PageDirectoryEntry { static mut PAGE_DIRECTORY: PageDirectoryEntry = PageDirectoryEntry::create_other(0, false, 0, false, false, false, false, false, false, false); +/// Initalize paging. #[kernel_item(PagingInit)] -pub fn initalize_paging() { - -} - +pub fn initalize_paging() {} /// Disables paging by clearing bit 31 in the cr0 register. #[kernel_item(PagingDeinit)] diff --git a/kernel/src/kernel/arch/x86/ports.rs b/kernel/src/kernel/arch/x86/ports.rs index 36a040b..9f8d35e 100644 --- a/kernel/src/kernel/arch/x86/ports.rs +++ b/kernel/src/kernel/arch/x86/ports.rs @@ -36,4 +36,4 @@ pub fn inb(port: u16) -> u8 { #[inline(always)] pub fn io_wait() { outb(0x80, 0); -} \ No newline at end of file +} diff --git a/kernel/src/kernel/boot.rs b/kernel/src/kernel/boot.rs index 5bc0810..7cba67e 100644 --- a/kernel/src/kernel/boot.rs +++ b/kernel/src/kernel/boot.rs @@ -34,15 +34,14 @@ impl MemoryType { MemoryType::Faulty => crate::arch::output::sdebugsnp("Faulty RAM"), MemoryType::HardwareReserved => crate::arch::output::sdebugsnp("Hardware Reserved"), MemoryType::HardwareSpecific(val, allocatable) => { - crate::arch::output::sdebugsnp("Hardware specific "); - crate::arch::output::sdebugbnp(&crate::u32_as_u8_slice(*val)); - if *allocatable { - crate::arch::output::sdebugsnp(", allocatable"); - } else { - crate::arch::output::sdebugsnp(", unallocatable"); - } - - }, + crate::arch::output::sdebugsnp("Hardware specific "); + crate::arch::output::sdebugbnp(&crate::u32_as_u8_slice(*val)); + if *allocatable { + crate::arch::output::sdebugsnp(", allocatable"); + } else { + crate::arch::output::sdebugsnp(", unallocatable"); + } + } MemoryType::Kernel => crate::arch::output::sdebugsnp("Kernel loaded"), MemoryType::Permanent => crate::arch::output::sdebugsnp("Flash"), MemoryType::Reserved => crate::arch::output::sdebugsnp("Reserved"), diff --git a/kernel/src/kernel/cfg.rs b/kernel/src/kernel/cfg.rs index 00a455c..ff4561f 100644 --- a/kernel/src/kernel/cfg.rs +++ b/kernel/src/kernel/cfg.rs @@ -11,4 +11,4 @@ macro_rules! cfg_int { } } }; -} \ No newline at end of file +} diff --git a/kernel/src/kernel/cmdline.rs b/kernel/src/kernel/cmdline.rs index cfaf0ee..63a2ab8 100644 --- a/kernel/src/kernel/cmdline.rs +++ b/kernel/src/kernel/cmdline.rs @@ -19,14 +19,14 @@ pub struct Argument { /// The name of an argument. pub name: &'static str, /// The value of an argument. - pub value: ArgumentValue + pub value: ArgumentValue, } /// A single flag in a [Cmdline]. #[derive(Clone, Copy)] pub struct Flag { /// The name of a flag. - pub name: &'static str + pub name: &'static str, } /// A kernel command line. @@ -83,7 +83,10 @@ impl Validator for CmdlineValidator { } } if !correct { - return Err(crate::Error::new("invalid argument in command line", ERR_INVALID_ARGUMENT)); + return Err(crate::Error::new( + "invalid argument in command line", + ERR_INVALID_ARGUMENT, + )); } } @@ -96,9 +99,12 @@ impl Validator for CmdlineValidator { } } if !correct { - return Err(crate::Error::new("invalid flag in command line", ERR_INVALID_FLAG)); + return Err(crate::Error::new( + "invalid flag in command line", + ERR_INVALID_FLAG, + )); } } Ok(()) } -} \ No newline at end of file +} diff --git a/kernel/src/kernel/constants.rs b/kernel/src/kernel/constants.rs index 7cafa70..f824f1e 100644 --- a/kernel/src/kernel/constants.rs +++ b/kernel/src/kernel/constants.rs @@ -1 +1 @@ -//! Constants used throughout kernel code. \ No newline at end of file +//! Constants used throughout kernel code. diff --git a/kernel/src/kernel/display.rs b/kernel/src/kernel/display.rs index c405736..6c4318a 100644 --- a/kernel/src/kernel/display.rs +++ b/kernel/src/kernel/display.rs @@ -3,7 +3,7 @@ use core::fmt::Write; /// A type used for color in the functions of [TextDisplay]. -/// +/// /// Type alias for (u8, bool). Boolean argument is whether to /// change the value(i.e. for [COLOR_BLACK] and [COLOR_DEFAULT]). pub type Color = (u8, bool); @@ -18,7 +18,12 @@ pub const COLOR_DEFAULT: Color = (1, true); /// Some form of display that can be written to with text. pub trait TextDisplay: core::fmt::Write { /// Writes a single character to the specified position. - fn write_char(&self, pos: (u32, u32), char: u8, color: Color) -> Result<(), crate::Error<'static>>; + fn write_char( + &self, + pos: (u32, u32), + char: u8, + color: Color, + ) -> Result<(), crate::Error<'static>>; /// Gets the size of the screen. fn get_size(&self) -> (u32, u32); } @@ -35,16 +40,21 @@ impl dyn TextDisplay + '_ { } /// Writes a &str to the screen. - pub fn write_str(&self, pos: (u32, u32), str: &str, color: Color) -> Result<(u32, u32), crate::Error<'static>> { + pub fn write_str( + &self, + pos: (u32, u32), + str: &str, + color: Color, + ) -> Result<(u32, u32), crate::Error<'static>> { let (width, _) = self.get_size(); let (mut x, mut y) = pos; for char in str.as_bytes() { self.write_char((x, y), *char, color)?; if *char == 0 { - continue + continue; } x += 1; - while x>width { + while x > width { x -= width; y += 1; } @@ -53,16 +63,21 @@ impl dyn TextDisplay + '_ { } /// Writes a &\[u8] to the screen. - pub fn write_bytes(&self, pos: (u32, u32), str: &[u8], color: Color) -> Result<(u32, u32), crate::Error<'static>> { + pub fn write_bytes( + &self, + pos: (u32, u32), + str: &[u8], + color: Color, + ) -> Result<(u32, u32), crate::Error<'static>> { let (width, _) = self.get_size(); let (mut x, mut y) = pos; for char in str { self.write_char((x, y), *char, color)?; if *char == 0 { - continue + continue; } x += 1; - while x>width { + while x > width { x -= width; y += 1; } @@ -76,7 +91,7 @@ pub struct NoneTextDisplay {} impl TextDisplay for NoneTextDisplay { fn get_size(&self) -> (u32, u32) { - (1,1) + (1, 1) } fn write_char(&self, _: (u32, u32), _: u8, _: Color) -> Result<(), crate::Error<'static>> { Ok(()) @@ -90,4 +105,4 @@ impl Write for NoneTextDisplay { fn write_str(&mut self, _: &str) -> core::fmt::Result { Ok(()) } -} \ No newline at end of file +} diff --git a/kernel/src/kernel/errors.rs b/kernel/src/kernel/errors.rs index 107ab4b..687b432 100644 --- a/kernel/src/kernel/errors.rs +++ b/kernel/src/kernel/errors.rs @@ -6,7 +6,7 @@ use crate::display::TextDisplay; #[derive(Clone, Copy)] pub struct Error<'a> { message: &'a str, - code: i16 + code: i16, } impl<'a> Error<'a> { @@ -17,7 +17,7 @@ impl<'a> Error<'a> { } impl Error<'_> { - /// Display the contents of the error on a [TextDisplay]. + /// Display the contents of the error on a [TextDisplay] with no prefix. pub fn display_np(&self, display: &dyn TextDisplay) { crate::output::terrorbnp(&crate::i16_as_u8_slice(self.code), display).unwrap(); crate::output::terrorsnp(": ", display).unwrap(); @@ -41,4 +41,4 @@ impl core::fmt::Display for Error<'_> { } } -impl core::error::Error for Error<'_> {} \ No newline at end of file +impl core::error::Error for Error<'_> {} diff --git a/kernel/src/kernel/indep_boot_entry.rs b/kernel/src/kernel/indep_boot_entry.rs index eea3bac..faa6e50 100644 --- a/kernel/src/kernel/indep_boot_entry.rs +++ b/kernel/src/kernel/indep_boot_entry.rs @@ -5,7 +5,10 @@ use core::alloc::{Allocator, Layout}; -use crate::{display::{NoneTextDisplay, COLOR_DEFAULT}, output::*}; +use crate::{ + display::{COLOR_DEFAULT, NoneTextDisplay}, + output::*, +}; use aphrodite_proc_macros::*; @@ -17,7 +20,10 @@ fn indep_boot_entry( display: Option<&dyn crate::display::TextDisplay>, #[allow(non_snake_case)] BI: &crate::boot::BootInfo, ) -> ! { - assert_ne!(crate::arch::get_arch(), crate::arch::Architecture::ExampleDummy); + assert_ne!( + crate::arch::get_arch(), + crate::arch::Architecture::ExampleDummy + ); crate::arch::output::sdebugsln("IndepBootEntry called"); let display = display.unwrap_or(&NoneTextDisplay {}); @@ -64,6 +70,8 @@ fn indep_boot_entry( terrors("Failed to deallocate: ", display).unwrap(); err.display_np(display); panic!("Deallocation failure"); + } else { + tdebugsln("Successfully deallocated!", display).unwrap(); } } tdebugsln("", display).unwrap(); diff --git a/kernel/src/kernel/mem.rs b/kernel/src/kernel/mem.rs index e9ba4e0..9dd0dca 100644 --- a/kernel/src/kernel/mem.rs +++ b/kernel/src/kernel/mem.rs @@ -48,8 +48,6 @@ struct AllocationIter { impl Iterator for AllocationIter { type Item = *mut Allocation; fn next(&mut self) -> Option<::Item> { - crate::arch::output::sdebugbln(&crate::u64_as_u8_slice(self.num_allocations)); - crate::arch::output::sdebugbln(&crate::u64_as_u8_slice(self.idx)); self.idx += 1; if self.idx > self.num_allocations { return None; @@ -139,7 +137,11 @@ impl<'a> Debug for MemoryMapAlloc<'a> { impl<'a> MemoryMapAlloc<'a> { /// Creates a new [MemoryMapAlloc]. Please call this method instead of creating it manually! - /// This method uses the memory mapping to + /// + /// This method internally stores the memory map in the outputted MemoryMapAlloc. + /// + /// Note that this function will return an error only if there isn't enough allocatable space + /// for at least 32 allocations. pub fn new( memory_map: &'a mut crate::boot::MemoryMap, ) -> Result, crate::Error<'a>> { @@ -222,6 +224,9 @@ impl<'a> MemoryMapAlloc<'a> { /// Add an allocation to [MemoryMapAlloc::allocations]. It will overwrite allocations with `used` set to false. fn add_allocation(&self, allocation: Allocation) -> Result<(), crate::Error<'static>> { + if !allocation.used { + crate::arch::output::swarningsln("Adding unused allocation"); + } for alloc in self.allocations_iter() { if !unsafe { *alloc }.used { unsafe { (*alloc) = allocation } @@ -355,7 +360,7 @@ pub const MAYBE_MEMORY_MAP_ALLOC_UNINITALIZED: i16 = -8; struct MaybeMemoryMapAlloc<'a> { alloc: MaybeUninit>, - initalized: bool + initalized: bool, } impl<'a> MaybeMemoryMapAlloc<'a> { const fn new(alloc: Option>) -> Self { @@ -363,7 +368,7 @@ impl<'a> MaybeMemoryMapAlloc<'a> { return MaybeMemoryMapAlloc { alloc: MaybeUninit::uninit(), initalized: false, - } + }; } MaybeMemoryMapAlloc { alloc: MaybeUninit::new(alloc.unwrap()), @@ -385,7 +390,9 @@ impl<'a> MaybeMemoryMapAlloc<'a> { if !self.initalized { return; } - unsafe { self.alloc.assume_init_drop(); } + unsafe { + self.alloc.assume_init_drop(); + } self.initalized = false; } } @@ -418,7 +425,10 @@ unsafe impl<'a> GlobalAlloc for MaybeMemoryMapAlloc<'a> { } unsafe impl<'a> Allocator for MaybeMemoryMapAlloc<'a> { - fn allocate(&self, layout: core::alloc::Layout) -> Result, core::alloc::AllocError> { + fn allocate( + &self, + layout: core::alloc::Layout, + ) -> Result, core::alloc::AllocError> { if !self.initalized { unsafe { LAST_MEMMAP_ERR = Err(crate::Error::new( @@ -545,6 +555,7 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> { } return; } + crate::arch::output::sdebugsln("Searching for allocation"); crate::arch::output::sdebugbln(&crate::u64_as_u8_slice( unsafe { *self.allocationheader }.num_allocations, )); @@ -552,6 +563,17 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> { crate::arch::output::sdebugsln("Allocation"); let alloc = unsafe { *allocation }.clone(); if !alloc.used { + crate::arch::output::sdebugs("Unused, addr is "); + if alloc.addr == addr { + crate::arch::output::sdebugsnp("correct and "); + } else { + crate::arch::output::sdebugsnp("incorrect and "); + } + if alloc.addr == 0 { + crate::arch::output::sdebugsnpln("null"); + } else { + crate::arch::output::sdebugsnpln("non-null"); + } continue; } crate::arch::output::sdebugsln("Used"); @@ -560,6 +582,7 @@ unsafe impl<'a> Allocator for MemoryMapAlloc<'a> { return; } } + crate::arch::output::sdebugsln("Memory unallocated"); // Memory not allocated, something is up, this is put after the loop to prevent a costly call to check_addr unsafe { LAST_MEMMAP_ERR = Err(crate::Error::new( diff --git a/kernel/src/kernel/memsections.rs b/kernel/src/kernel/memsections.rs index 4726fac..fc812dc 100644 --- a/kernel/src/kernel/memsections.rs +++ b/kernel/src/kernel/memsections.rs @@ -1,5 +1,5 @@ //! Architecture-independt memory section stuff. -//! +//! //! arch::*::memory is the architecture-dependent counterpart. /// Section types for [MemorySection]. @@ -12,7 +12,7 @@ pub enum SectionType { CodeSection { /// Whether more powerful owners can jump to this if the owner /// is less powerful. - can_powerful_sections_jump: bool + can_powerful_sections_jump: bool, }, /// A data section. Generally at least one of these for the kernel. DataSection, @@ -21,7 +21,7 @@ pub enum SectionType { /// if they aren't directly supported by the hardware. TaskSection { /// Whether the section is busy. - busy: bool + busy: bool, }, } @@ -62,8 +62,8 @@ pub struct MemorySection { /// is called, which is not supposed to happen. pub unsafe trait MemorySections { /// Write the sections to an allocated region and then activate them. - /// + /// /// This intentionally takes ownership of the MemorySections as it /// shouldn't be used after this is called. unsafe fn write(self) -> Result<(), crate::Error<'static>>; -} \ No newline at end of file +} diff --git a/kernel/src/kernel/mod.rs b/kernel/src/kernel/mod.rs index 358c01d..9b1839d 100644 --- a/kernel/src/kernel/mod.rs +++ b/kernel/src/kernel/mod.rs @@ -29,12 +29,12 @@ pub mod display; mod errors; pub mod indep_boot_entry; pub mod mem; +pub mod memsections; pub mod multiboot2; pub mod output; pub mod psfont; mod traits; mod util; -pub mod memsections; #[macro_use] pub(crate) mod cfg; @@ -47,3 +47,11 @@ pub use util::*; #[allow(unused_imports)] // if there are no traits, then it gives a warning pub use traits::*; + +pub const fn version() -> &'static str { + env!("VERSION") +} + +pub const fn cfg_version() -> &'static str { + env!("CFG_VERSION") +} diff --git a/kernel/src/kernel/multiboot2.rs b/kernel/src/kernel/multiboot2.rs index e048353..65b436a 100644 --- a/kernel/src/kernel/multiboot2.rs +++ b/kernel/src/kernel/multiboot2.rs @@ -9,7 +9,7 @@ pub struct Tag { /// The type of the tag. pub tag_type: u32, /// The length of the tag. - pub tag_len: u32 + pub tag_len: u32, } /// The root tag. The official Multiboot2 name is literally the "fixed part" of the tags, so I made a better name. @@ -32,7 +32,7 @@ pub struct Module { pub mod_end: *const u8, /// A string that should be in the format `module_name (command line arguments)`. /// See . - pub mod_str: &'static core::ffi::CStr + pub mod_str: &'static core::ffi::CStr, } /// One memory section provided by a Multiboot2 bootloader. @@ -58,10 +58,10 @@ impl Into for MemorySection { 2 => crate::boot::MemoryType::HardwareReserved, 3 => crate::boot::MemoryType::HardwareSpecific(3, false), 5 => crate::boot::MemoryType::Faulty, - _ => crate::boot::MemoryType::Reserved + _ => crate::boot::MemoryType::Reserved, }, start: self.base_addr, - len: self.length + len: self.length, } } } @@ -79,7 +79,7 @@ pub struct RawMemoryMap { /// The version of the memory map. Should be disregarded as it's 0. pub entry_version: u32, // currently is 0, future Multiboot2 versions may increment /// The sections. This is the reason that [Clone] can't be implemented for [RawMemoryMap]. - pub sections: [MemorySection] + pub sections: [MemorySection], } /// A full memory map provided by a Multiboot2 bootloader. @@ -119,7 +119,7 @@ pub struct PaletteColorDescriptor { /// The green value pub green: u8, /// The blue value - pub blue: u8 + pub blue: u8, } /// Information about color, for use in [FramebufferInfo]. @@ -131,7 +131,7 @@ pub enum ColorInfo { /// The number of colors in the palette. num_colors: u32, /// The first color in the palette. - palette: *const PaletteColorDescriptor + palette: *const PaletteColorDescriptor, }, /// RGB information for use on the framebuffer. RGBColor { @@ -151,7 +151,7 @@ pub enum ColorInfo { blue_mask_size: u8, }, /// Text information, no metadata - EGAText + EGAText, } /// Information about the framebuffer. @@ -172,7 +172,6 @@ pub struct FramebufferInfo { pub fb_type: u8, /// Reserved space. Ignore. reserved: u8, - // Color info after this; we need separate structs for each colorinfo as // we have to understand the format the bootloader gives us. } @@ -190,7 +189,6 @@ pub struct Multiboot2BootInfo { // Multiboot2 bootloaders may provide us with the BIOS device and partition, but we're not interested. // To ensure future developers don't get any ideas, I'm leaving it out here. // If you need it, good luck. - /// We're provided with a C-style UTF-8(null-terminated UTF-8) string. This should contain the original pointer provided by /// the bootloader. /// See for the format. @@ -201,7 +199,6 @@ pub struct Multiboot2BootInfo { // Multiboot2 bootloaders may provide us with ELF symbols, but I'm feeling lazy and right now it's mostly // unnecessary, so I don't care. Sorry if you are affected by this. - /// The memory map provided by the bootloader. pub memory_map: Option, @@ -212,12 +209,10 @@ pub struct Multiboot2BootInfo { // APM table is ignored as APM has been superseded by ACPI. If your system doesn't support ACPI, good luck. // VBE table is ignored for a similar reason to above: it's deprecated. Good luck if you need it. - /// Provides information on the framebuffer. pub framebuffer_info: Option, /// Color info, stored separately from [FramebufferInfo] because rust pub color_info: Option, - // Even though SMBIOS is documented for Multiboot2, we're not using it and will instead search for it ourselves. // This is because right now I cannot figure out what format it provides the SMBIOS table in. diff --git a/kernel/src/kernel/output.rs b/kernel/src/kernel/output.rs index 77771e4..fcf4433 100644 --- a/kernel/src/kernel/output.rs +++ b/kernel/src/kernel/output.rs @@ -1,7 +1,7 @@ //! Architecture-independent output functions. -use paste::paste; use crate::display::COLOR_DEFAULT; +use paste::paste; /// The position to output stuff to. static mut OUTPUT_TERM_POSITION: (u32, u32) = (0, 0); @@ -157,4 +157,4 @@ pub fn sreset() { unsafe { OUTPUT_TERM_POSITION = (0, 0); } -} \ No newline at end of file +} diff --git a/kernel/src/kernel/psfont.rs b/kernel/src/kernel/psfont.rs index a0fc667..10a794d 100644 --- a/kernel/src/kernel/psfont.rs +++ b/kernel/src/kernel/psfont.rs @@ -82,17 +82,13 @@ pub fn parse_raw_pc_screen_font(data: Vec) -> Result Result> { +pub fn parse_pc_screen_font(data: RawPCScreenFont) -> Result> { unsafe { if data.flags == 0 { - let mut unitable: Vec> = Vec::with_capacity(data.num_glyphs as usize * core::mem::size_of::>()); + let mut unitable: Vec> = + Vec::with_capacity(data.num_glyphs as usize * core::mem::size_of::>()); - let unistr = (data - .glyphs - .as_slice() - as *const [u8]) + let unistr = (data.glyphs.as_slice() as *const [u8]) .byte_add(data.bytes_per_glyph as usize * data.num_glyphs as usize); let mut i = 0usize; @@ -136,9 +132,7 @@ pub fn parse_pc_screen_font( } /// Parses a Vec into a [PCScreenFont]. -pub fn parse_psfu( - data: Vec, -) -> Result> { +pub fn parse_psfu(data: Vec) -> Result> { let data = parse_raw_pc_screen_font(data)?; parse_pc_screen_font(data) } diff --git a/kernel/src/kernel/util.rs b/kernel/src/kernel/util.rs index c54b448..caac0fc 100644 --- a/kernel/src/kernel/util.rs +++ b/kernel/src/kernel/util.rs @@ -13,7 +13,7 @@ pub const fn i16_as_u8_slice(mut value: i16) -> [u8; 6] { } i = 5; while value > 0 { - let digit = value%10; + let digit = value % 10; let char = b'0' + digit as u8; buf[i] = char; value = value / 10; @@ -30,7 +30,7 @@ pub const fn u32_as_u8_slice(mut value: u32) -> [u8; 10] { buf[0] = b'0'; } while value > 0 { - let digit = value%10; + let digit = value % 10; let char = b'0' + digit as u8; buf[i] = char; value = value / 10; @@ -47,7 +47,7 @@ pub const fn u8_as_u8_slice(mut value: u8) -> [u8; 3] { buf[0] = b'0'; } while value > 0 { - let digit = value%10; + let digit = value % 10; let char = b'0' + digit as u8; buf[i] = char; value = value / 10; @@ -64,7 +64,7 @@ pub const fn usize_as_u8_slice(mut value: usize) -> [u8; 20] { buf[0] = b'0'; } while value > 0 { - let digit = value%10; + let digit = value % 10; let char = b'0' + digit as u8; buf[i] = char; value = value / 10; @@ -81,7 +81,7 @@ pub const fn u64_as_u8_slice(mut value: u64) -> [u8; 20] { buf[0] = b'0'; } while value > 0 { - let digit = value%10; + let digit = value % 10; let char = b'0' + digit as u8; buf[i] = char; value = value / 10; @@ -103,7 +103,7 @@ pub fn str_as_i16(mut value: &[u8]) -> i16 { continue; } out *= 10; - out += (byte-b'0') as i16; + out += (byte - b'0') as i16; } let mut reversed = 0; @@ -125,7 +125,7 @@ pub fn str_as_u32(value: &[u8]) -> u32 { continue; } out *= 10; - out += (byte-b'0') as u32; + out += (byte - b'0') as u32; } let mut reversed = 0; @@ -147,7 +147,7 @@ pub fn str_as_u128(value: &[u8]) -> u128 { continue; } out *= 10; - out += (byte-b'0') as u128; + out += (byte - b'0') as u128; } let mut reversed = 0; @@ -169,7 +169,7 @@ pub fn str_as_u64(value: &[u8]) -> u64 { continue; } out *= 10; - out += (byte-b'0') as u64; + out += (byte - b'0') as u64; } let mut reversed = 0; @@ -180,4 +180,4 @@ pub fn str_as_u64(value: &[u8]) -> u64 { } reversed -} \ No newline at end of file +}