diff --git a/.cargo/runner.sh b/.cargo/runner.sh index 15d0dddfcc60d765d8109d686bd24be9a385e3a8..e66833b774f66418285d8f9a737ee97127d47376 100755 --- a/.cargo/runner.sh +++ b/.cargo/runner.sh @@ -43,8 +43,9 @@ if [ "$(basename $KERNEL)" = "hyperion" ]; then qemu-system-x86_64 \ -enable-kvm \ -machine q35 \ - -cpu qemu64 \ + -cpu qemu64,+rdrand,+rdseed \ -smp 8 \ + -m 512m \ -M smm=off \ -d int,guest_errors,cpu_reset \ -no-reboot \ @@ -59,8 +60,9 @@ else qemu-system-x86_64 \ -enable-kvm \ -machine q35 \ - -cpu qemu64 \ + -cpu qemu64,+rdrand,+rdseed \ -smp 8 \ + -m 512m \ -M smm=off \ -d int,guest_errors,cpu_reset \ -device isa-debug-exit,iobase=0xf4,iosize=0x04 \ diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000000000000000000000000000000000000..4ceff496ab83a79a4eb72e91b048ea6c6f4f5510 --- /dev/null +++ b/TODO.md @@ -0,0 +1,15 @@ +# TODOs: + + - GDT + IDT for non-boot SMP CPU:s + + - Font generator proc macro + + - With cache of course + + - Memory manager + + - Physical memory allocator + + - Virtual memory manager + + - APIC diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index 7a415c331fc6b6a9ef06f96952297f24054b183b..4078b80d88139170cc195ea24130025afd5dfd72 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -1,4 +1,5 @@ -use crate::debug; +use crate::{debug, error}; +use x86_64::instructions::random::RdRand; // @@ -17,6 +18,13 @@ pub fn early_boot_cpu() { pub fn early_per_cpu() {} +pub fn rng_seed() -> u64 { + RdRand::new().and_then(RdRand::get_u64).unwrap_or_else(|| { + error!("Failed to generate a rng seed with x86_64 RDSEED"); + 0 + }) +} + pub fn done() -> ! { loop { x86_64::instructions::hlt(); diff --git a/src/boot/limine/mod.rs b/src/boot/limine/mod.rs index 0f7170aaa5d13009367751b6a0ec6f53b0839979..483e3e246e356ec27b6ec2b1fc4b36c66364cb9d 100644 --- a/src/boot/limine/mod.rs +++ b/src/boot/limine/mod.rs @@ -1,4 +1,5 @@ -use crate::arch; +use super::BOOT_NAME; +use crate::{arch, kernel_main}; // @@ -17,7 +18,7 @@ mod term; #[no_mangle] pub extern "C" fn _start() -> ! { - crate::BOOTLOADER.call_once(|| "Limine"); + BOOT_NAME.call_once(|| "Limine"); framebuffer::init(); cmdline::init(); @@ -25,7 +26,7 @@ pub extern "C" fn _start() -> ! { arch::early_boot_cpu(); arch::early_per_cpu(); - crate::kernel_main() + kernel_main() } pub fn smp_init() { diff --git a/src/boot/limine/smp.rs b/src/boot/limine/smp.rs index 74859e1fc2301c8e6581df13fd3e34880768d3a6..29e2e0a5233239727f4aabc0fbc5b9129be78573 100644 --- a/src/boot/limine/smp.rs +++ b/src/boot/limine/smp.rs @@ -1,7 +1,4 @@ -use crate::{ - arch, - smp::{smp_main, Cpu}, -}; +use crate::{arch, smp::Cpu, smp_main}; use limine::{LimineSmpInfo, LimineSmpRequest}; // diff --git a/src/boot/mod.rs b/src/boot/mod.rs index f670b8d23fdfb8ead447862081c3bf6eb0a55185..fb80769a21349b4156271995f77cc687f8af263f 100644 --- a/src/boot/mod.rs +++ b/src/boot/mod.rs @@ -1,3 +1,7 @@ +use spin::Once; + +// + #[cfg(feature = "multiboot1")] #[path = "multiboot1/mod.rs"] mod boot; @@ -11,4 +15,11 @@ mod boot; #[path = "limine/mod.rs"] mod boot; +// + pub use boot::*; + +// + +/// Name of the detected bootloader +pub static BOOT_NAME: Once<&'static str> = Once::new(); diff --git a/src/env.rs b/src/env.rs index 899980f56184962d89d104d7ec4eba22990cafc7..57cc52d5b7f8a142ebb3907df16c5737620715c2 100644 --- a/src/env.rs +++ b/src/env.rs @@ -3,8 +3,6 @@ use spin::Once; // -// - pub fn args() -> Arguments { Arguments::get() } @@ -25,7 +23,7 @@ pub struct Arguments { impl Arguments { pub fn parse(s: &'static str) { ARGUMENTS.call_once(|| { - let mut iter = s.split_whitespace(); + let mut iter = s.split(|c: char| c.is_whitespace() || c == '='); let mut result = Arguments::default(); result.cmdline = s; @@ -40,13 +38,6 @@ impl Arguments { } } } - _ if item.starts_with("log=") => { - if let Some(l) = LogLevel::parse(&item[4..]) { - result.log_level = l - } else { - result.had_unrecognized = true - } - } _ => result.had_unrecognized = true, } } diff --git a/src/main.rs b/src/main.rs index 74becd5a273454bb24443abea98330344bc31aad..7dbe95c4ae83a20014d3292fd01419ffe0b539a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,16 +7,12 @@ #![feature(result_option_inspect)] #![feature(allocator_api)] #![feature(nonnull_slice_from_raw_parts)] +#![feature(exclusive_range_pattern)] #![test_runner(crate::testfw::test_runner)] #![reexport_test_harness_main = "test_main"] // -use crate::term::escape::encode::EscapeEncoder; -use spin::Once; - -// - extern crate alloc; // @@ -33,19 +29,18 @@ pub mod smp; pub mod term; #[cfg(test)] pub mod testfw; +pub mod util; pub mod video; // -/// Name of the kernel -pub static KERNEL: &str = if cfg!(test) { +pub static KERNEL_NAME: &str = if cfg!(test) { "Hyperion-Testing" } else { "Hyperion" }; -/// Name of the detected bootloader -pub static BOOTLOADER: Once<&'static str> = Once::new(); +pub static KERNEL_VERS: &str = env!("CARGO_PKG_VERSION"); // @@ -58,13 +53,22 @@ fn kernel_main() -> ! { // ofc. every kernel has to have this cringy ascii name splash info!("\n{}\n", include_str!("./splash")); - if let Some(bl) = BOOTLOADER.get() { - let kernel = KERNEL.true_cyan(); - debug!("{kernel} was booted with {bl}"); + if let Some(bl) = boot::BOOT_NAME.get() { + debug!("{KERNEL_NAME} {KERNEL_VERS} was booted with {bl}"); } #[cfg(test)] test_main(); + debug!("{}", arch::rng_seed()); + smp::init(); } + +fn smp_main(cpu: smp::Cpu) -> ! { + debug!("{cpu} entering smp_main"); + + // x86_64::instructions::interrupts::int3(); + + arch::done(); +} diff --git a/src/mem.rs b/src/mem.rs index 61bc690260e7505ac3c7391f454dc43b6dc250fd..af0077cbf6342b300d06eedc15d9b3f63589f4d9 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -1,4 +1,4 @@ -use crate::{boot, debug, error}; +use crate::{boot, debug, error, util::NumberPostfix}; use core::{ alloc::{GlobalAlloc, Layout}, ptr::null_mut, @@ -13,12 +13,13 @@ pub fn init() { for Memmap { base, len } in boot::memmap() { usable += len; - debug!("base: {base:#X} len: {len:#X}"); + debug!("base: {base:#X} len: {len:#X} ({}B)", len.postfix_binary()); ALLOC.memory.store(base, Ordering::SeqCst); *ALLOC.remaining.lock() = len; } - debug!("Usable system memory: {usable}"); + + debug!("Usable system memory: {}B", usable.postfix_binary()); } // diff --git a/src/smp.rs b/src/smp.rs index c2bd0a62ce6ee1aed1656c96442dce3edde3389d..aa926d25285b23e6ca9bb9ee89f9d92b5dea4377 100644 --- a/src/smp.rs +++ b/src/smp.rs @@ -10,20 +10,12 @@ use core::fmt::{self, Display, Formatter}; pub fn init() -> ! { debug!("Waking up non-boot CPUs"); boot::smp_init(); - smp_main(Cpu { + crate::smp_main(Cpu { processor_id: 0, local_apic_id: 0, }) } -pub fn smp_main(cpu: Cpu) -> ! { - debug!("Entering smp_main ({cpu})"); - - // x86_64::instructions::interrupts::int3(); - - arch::done(); -} - // #[derive(Debug)] diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000000000000000000000000000000000000..e43b03aebf51bf8785494b31087b5f039b73760f --- /dev/null +++ b/src/util.rs @@ -0,0 +1,86 @@ +use core::{fmt, ops::DivAssign}; + +// + +pub trait NumberPostfix: Sized + Copy + DivAssign + PartialOrd { + const NUM_1000: Self; + const NUM_1024: Self; + + fn postfix(mut self) -> NumberPostfixed<Self> { + const TABLE: [&'static str; 10] = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R"]; + for scale in TABLE { + if self < Self::NUM_1000 { + return NumberPostfixed { n: self, scale }; + } + self /= Self::NUM_1000; + } + NumberPostfixed { + n: self, + scale: "Q", + } + } + + fn postfix_binary(mut self) -> NumberPostfixed<Self> { + const TABLE: [&'static str; 10] = + ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", "Ri"]; + for scale in TABLE { + if self < Self::NUM_1024 { + return NumberPostfixed { n: self, scale }; + } + self /= Self::NUM_1024; + } + NumberPostfixed { + n: self, + scale: "Qi", + } + } +} + +// + +#[derive(Debug)] +pub struct NumberPostfixed<T> { + n: T, + scale: &'static str, +} + +// + +impl NumberPostfix for f32 { + const NUM_1000: Self = 1000.0; + const NUM_1024: Self = 1024.0; +} + +impl NumberPostfix for f64 { + const NUM_1000: Self = 1000.0; + const NUM_1024: Self = 1024.0; +} + +impl NumberPostfix for u16 { + const NUM_1000: Self = 1000; + const NUM_1024: Self = 1024; +} + +impl NumberPostfix for u32 { + const NUM_1000: Self = 1000; + const NUM_1024: Self = 1024; +} + +impl NumberPostfix for u64 { + const NUM_1000: Self = 1000; + const NUM_1024: Self = 1024; +} + +impl NumberPostfix for usize { + const NUM_1000: Self = 1000; + const NUM_1024: Self = 1024; +} + +impl<T> fmt::Display for NumberPostfixed<T> +where + T: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} {}", self.n, self.scale) + } +}