diff --git a/Cargo.lock b/Cargo.lock index 3955c15..684830b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "acpi" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e248409195304021f61b39ba2628f62a45a3abf6119669d44b3399d60eabe4c3" +dependencies = [ + "bit_field", + "log", +] + [[package]] name = "ahash" version = "0.8.11" @@ -21,13 +31,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] -name = "approx" -version = "0.5.1" +name = "anyhow" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "autocfg" @@ -35,6 +42,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + [[package]] name = "bit_field" version = "0.10.2" @@ -49,9 +62,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cfg-if" @@ -96,13 +115,45 @@ checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", +] + +[[package]] +name = "embedded-graphics" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0" +dependencies = [ + "az", + "byteorder", + "embedded-graphics-core", + "float-cmp", + "micromath", +] + +[[package]] +name = "embedded-graphics-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044" +dependencies = [ + "az", + "byteorder", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", ] [[package]] @@ -119,33 +170,43 @@ dependencies = [ name = "kernel" version = "0.1.0" dependencies = [ - "bitflags 2.5.0", + "acpi", + "anyhow", + "bitflags 2.6.0", "cfg-if", "crossbeam", + "embedded-graphics", "hashbrown", "lazy_static", + "libm", "log", "multiboot2", - "nalgebra", "once", "pc-keyboard", "pic8259", - "spin 0.9.8", + "ps2", + "spin", "talc", "uart_16550", "x86", - "x86_64", + "x86_64 0.15.1", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "lock_api" version = "0.4.12" @@ -158,9 +219,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "micromath" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" [[package]] name = "multiboot2" @@ -168,55 +235,13 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad7ef048d4783355163fd0c874aac3db54b919dc6a86dc29bb13f67308b114b0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "derive_more", "log", "ptr_meta", "uefi-raw", ] -[[package]] -name = "nalgebra" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4b5f057b303842cf3262c27e465f4c303572e7f6b0648f60e16248ac3397f4" -dependencies = [ - "approx", - "num-complex", - "num-rational", - "num-traits", - "simba", - "typenum", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -238,12 +263,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pc-keyboard" version = "0.7.0" @@ -256,18 +275,28 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62d9a86c292b165f757e47e7fd66855def189b2564609bc4203727b27c33db22" dependencies = [ - "x86_64", + "x86_64 0.15.1", ] [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] +[[package]] +name = "ps2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfef03bb1362e6a23a211efe8c72e2eeb6888f51fb329cdfa07bb470986ea7d0" +dependencies = [ + "bitflags 1.3.2", + "x86_64 0.14.12", +] + [[package]] name = "ptr_meta" version = "0.2.0" @@ -290,9 +319,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -318,24 +347,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "simba" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" -dependencies = [ - "approx", - "num-complex", - "num-traits", - "paste", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -376,19 +387,13 @@ dependencies = [ "lock_api", ] -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - [[package]] name = "uart_16550" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687" +checksum = "4922792855b1bce30997fbaa5418597902c278a92d20dfe348e6f062c3bd861d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "rustversion", "x86", ] @@ -399,7 +404,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa8716f52e8cab8bcedfd5052388a0f263b69fe5cc2561548dc6a530678333c" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "ptr_meta", "uguid", ] @@ -439,6 +444,18 @@ dependencies = [ "raw-cpuid", ] +[[package]] +name = "x86_64" +version = "0.14.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96cb6fd45bfeab6a5055c5bffdb08768bd0c069f1d946debe585bbb380a7c062" +dependencies = [ + "bit_field", + "bitflags 2.6.0", + "rustversion", + "volatile", +] + [[package]] name = "x86_64" version = "0.15.1" @@ -446,7 +463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bc79523af8abf92fb1a970c3e086c5a343f6bcc1a0eb890f575cbb3b45743df" dependencies = [ "bit_field", - "bitflags 2.5.0", + "bitflags 2.6.0", "rustversion", "volatile", ] diff --git a/boot/multiboot.s b/boot/multiboot.s index c5180e1..cd7cd79 100644 --- a/boot/multiboot.s +++ b/boot/multiboot.s @@ -1,4 +1,4 @@ -%define VIDEO_MODE 1 +%define VIDEO_MODE 0 section .data global __VIDEO_MODE diff --git a/build.sh b/build.sh index 629a070..d5c5ab2 100755 --- a/build.sh +++ b/build.sh @@ -80,7 +80,7 @@ function run_qemu() { qemu-system-x86_64 \ -cdrom $ISO \ -serial stdio \ - -device VGA + -device VGA --enable-kvm # -d int \ } diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index ca9e0fb..707656d 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -10,17 +10,21 @@ crate-type=["staticlib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +acpi = "5.0.0" +anyhow = { version = "1.0.87", default-features = false } bitflags = "2.5.0" cfg-if = "1.0.0" crossbeam = { version = "0.8.4", default-features = false, features = ["alloc"] } +embedded-graphics = "0.8.1" hashbrown = "0.14.5" lazy_static = { version = "1.4.0", features = ["spin_no_std"] } +libm = "0.2.8" log = "0.4.21" multiboot2 = "0.20.2" -nalgebra = { version = "0.33.0", default-features = false } once = "0.3.4" pc-keyboard = "0.7.0" pic8259 = "0.11.0" +ps2 = "0.2.0" spin = "0.9.8" talc = "4.4.1" uart_16550 = "0.3.0" diff --git a/kernel/src/acpi/mod.rs b/kernel/src/acpi/mod.rs new file mode 100644 index 0000000..c7967de --- /dev/null +++ b/kernel/src/acpi/mod.rs @@ -0,0 +1,22 @@ +use core::{cell::RefCell, ops::DerefMut}; + +use acpi::AcpiHandler; +use alloc::boxed::Box; + +use crate::mem::{paging::ActivePageTable, Frame}; + +#[derive(Debug, Clone)] +struct AcpiMapper { + apt: RefCell +} + +impl AcpiMapper { + pub fn new(apt: ActivePageTable) -> Self { + Self { + apt: RefCell::new(apt) + } + } +} + + + diff --git a/kernel/src/drivers/mod.rs b/kernel/src/drivers/mod.rs index e69de29..a2436b2 100644 --- a/kernel/src/drivers/mod.rs +++ b/kernel/src/drivers/mod.rs @@ -0,0 +1,105 @@ +use core::fmt::Debug; +use alloc::{boxed::Box, string::{String, ToString}, vec::Vec, vec}; +use hashbrown::HashMap; +use spin::{Mutex, MutexGuard}; + +use crate::utils::as_any_mut; + +pub mod ps2; + +lazy_static::lazy_static!( + pub static ref DRIVER_MGR: Mutex = Mutex::new(DriverHandler::new()); +); + +type RegisterFn = fn( + name: &mut String, + author: &mut String, + license: &mut String, +) -> Box; + +pub trait Driver: Debug + Send{ + fn new() -> impl Driver where Self: Sized; + fn register( + name: &mut String, + author: &mut String, + license: &mut String, + ) -> Box where Self: Sized { + *name = alloc::format!("YOUR_DRIVER_NAME"); + *author = alloc::format!("Your Name "); + *license = alloc::format!("GPLv3"); + + // Box::new(Self::new()) + todo!() + } + fn startup(&mut self) -> anyhow::Result<()> { + Ok(()) + } + fn shutdown(&mut self) -> anyhow::Result<()> { + Ok(()) + } + +} + + +#[derive(Debug)] +pub struct DriverHandler { + drivers: HashMap>, +} + +impl DriverHandler { + pub fn new() -> Self { + Self { + drivers: HashMap::new(), + } + } + + #[inline] + pub fn get_instance<'i>() -> MutexGuard<'i, Self> { + DRIVER_MGR.lock() + } + + pub fn load_drivers(&mut self) { + for driver_reg_fn in Self::get_all_driver_entries() { + let mut name = String::new(); + let mut author = String::new(); + let mut license = String::new(); + let driver = (driver_reg_fn)(&mut name, &mut author, &mut license); + log::info!("Loaded driver '{name}' ({license})"); + self.drivers.insert(name, driver); + } + } + + pub fn get_driver(&mut self, name: &str) -> Option<&mut T> { + if let Some(d) = self.drivers.get_mut(&name.to_string()) { + unsafe { + // Lets hope for the best + Some(as_any_mut(d).downcast_mut_unchecked::()) + } + } else { + None + } + } + + pub fn start_drivers(&mut self) { + for (name, driver) in &mut self.drivers { + if let Err(e) = driver.startup() { + log::error!("Driver '{name}' had an error on startup: {e}"); + } + } + } + + pub fn stop_drivers(&mut self) { + for (name, driver) in &mut self.drivers { + if let Err(e) = driver.shutdown() { + log::error!("Driver '{name}' had an error on shutdown: {e}"); + } + } + } + + #[inline] + fn get_all_driver_entries() -> Vec { + vec![ + ps2::Ps2Driver::register, + ] + } +} diff --git a/kernel/src/drivers/ps2/mod.rs b/kernel/src/drivers/ps2/mod.rs new file mode 100644 index 0000000..beb3d6e --- /dev/null +++ b/kernel/src/drivers/ps2/mod.rs @@ -0,0 +1,43 @@ +use alloc::{boxed::Box, format, string::String}; +use anyhow::bail; + +use super::Driver; + + +#[derive(Debug)] +pub struct Ps2Driver{ + +} + +impl Ps2Driver { + pub fn test(&self) -> String { + String::from("hewo") + } + +} + +impl Driver for Ps2Driver { + fn new() -> impl Driver where Self: Sized { + Self { + + } + } + fn register( + name: &mut alloc::string::String, + author: &mut alloc::string::String, + license: &mut alloc::string::String, + ) -> Box where Self: Sized { + *name = format!("PS/2"); + *author = format!("MCorange "); + *license = format!("GPLv3"); + Box::new(Self::new()) + } + + fn startup(&mut self) -> anyhow::Result<()> { + Ok(()) + } + + fn shutdown(&mut self) -> anyhow::Result<()> { + Ok(()) + } +} diff --git a/kernel/src/interrupts/handlers/mod.rs b/kernel/src/interrupts/handlers/mod.rs index 92fb4dc..2cee283 100644 --- a/kernel/src/interrupts/handlers/mod.rs +++ b/kernel/src/interrupts/handlers/mod.rs @@ -1,23 +1,13 @@ use x86_64::structures::idt::{InterruptStackFrame, PageFaultErrorCode}; use crate::interrupts::InterruptIndex; -mod ps2_keyboard; - -pub use ps2_keyboard::ps2_kb_int; +pub mod ps2; +pub mod timer; pub extern "x86-interrupt" fn breakpoint(sf: InterruptStackFrame){ log::error!("EXCEPT: BREAKPOINT\n{:#?}", sf); } -pub extern "x86-interrupt" fn timer_interrupt(_: InterruptStackFrame){ - //log::debug!("INT: TIMER\n{:#?}", sf); - // print!("."); - // EVENTMAN.lock().dispatch(&crate::events::Event::TimerInterrupt(None)); - unsafe { - super::PICS.lock() - .notify_end_of_interrupt(InterruptIndex::Timer as u8); - } -} pub extern "x86-interrupt" fn double_fault(stack_frame: InterruptStackFrame, _: u64) -> ! { panic!("EXCEPT: DOUBLE FAULT \n{:#?}", stack_frame); } diff --git a/kernel/src/interrupts/handlers/ps2_keyboard.rs b/kernel/src/interrupts/handlers/ps2.rs similarity index 73% rename from kernel/src/interrupts/handlers/ps2_keyboard.rs rename to kernel/src/interrupts/handlers/ps2.rs index c802563..9bcae2a 100644 --- a/kernel/src/interrupts/handlers/ps2_keyboard.rs +++ b/kernel/src/interrupts/handlers/ps2.rs @@ -1,12 +1,13 @@ -use x86_64::structures::idt::InterruptStackFrame; +use x86_64::{instructions::port::Port, structures::idt::InterruptStackFrame}; use crate::{events::EVENTMAN, interrupts::PICS}; +const PS2_PORT: u16 = 0x60; +// https://wiki.osdev.org/PS/2_Keyboard pub extern "x86-interrupt" fn ps2_kb_int(_sf: InterruptStackFrame){ use pc_keyboard::{layouts, HandleControl, Keyboard, ScancodeSet1}; use spin::Mutex; - use x86_64::instructions::port::Port; lazy_static::lazy_static! { static ref KEYBOARD: Mutex> = @@ -16,7 +17,7 @@ pub extern "x86-interrupt" fn ps2_kb_int(_sf: InterruptStackFrame){ } let mut keyboard = KEYBOARD.lock(); - let mut port = Port::new(0x60); + let mut port = Port::new(PS2_PORT); let scancode: u8 = unsafe { port.read() }; if let Ok(Some(key_event)) = keyboard.add_byte(scancode) { @@ -24,6 +25,6 @@ pub extern "x86-interrupt" fn ps2_kb_int(_sf: InterruptStackFrame){ } unsafe { PICS.lock() - .notify_end_of_interrupt(super::InterruptIndex::Keyboard as u8); + .notify_end_of_interrupt(super::InterruptIndex::Ps2Keyboard.get()); } } diff --git a/kernel/src/interrupts/handlers/timer.rs b/kernel/src/interrupts/handlers/timer.rs new file mode 100644 index 0000000..b6ff0e0 --- /dev/null +++ b/kernel/src/interrupts/handlers/timer.rs @@ -0,0 +1,14 @@ +use x86_64::structures::idt::InterruptStackFrame; + +use crate::interrupts::{InterruptIndex, PICS}; + +pub extern "x86-interrupt" fn timer_interrupt(_: InterruptStackFrame){ + //log::debug!("INT: TIMER\n{:#?}", sf); + // print!("."); + // EVENTMAN.lock().dispatch(&crate::events::Event::TimerInterrupt(None)); + unsafe { + PICS.lock() + .notify_end_of_interrupt(InterruptIndex::Timer.get()); + } +} + diff --git a/kernel/src/interrupts/mod.rs b/kernel/src/interrupts/mod.rs index 7a3207f..a4f2fd1 100644 --- a/kernel/src/interrupts/mod.rs +++ b/kernel/src/interrupts/mod.rs @@ -14,10 +14,11 @@ lazy_static::lazy_static! { idt.breakpoint.set_handler_fn(handlers::breakpoint); idt.page_fault.set_handler_fn(handlers::page_fault); - idt[InterruptIndex::Timer as u8] - .set_handler_fn(handlers::timer_interrupt); - idt[InterruptIndex::Keyboard as u8] - .set_handler_fn(handlers::ps2_kb_int); + idt[InterruptIndex::Timer.get()] + .set_handler_fn(handlers::timer::timer_interrupt); + + idt[InterruptIndex::Ps2Keyboard.get()] + .set_handler_fn(handlers::ps2::ps2_kb_int); unsafe { @@ -31,11 +32,52 @@ lazy_static::lazy_static! { pub static PICS: spin::Mutex = spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) }); + +/// https://wiki.osdev.org/Interrupts +/// | IRQ | Description | +/// |------|----------------------------------------------------------| +/// | 0 | Programmable Interrupt Timer Interrupt | +/// | 1 | Keyboard Interrupt | +/// | 2 | Cascade (used internally by the two PICs. never raised) | +/// | 3 | COM2 (if enabled) | +/// | 4 | COM1 (if enabled) | +/// | 5 | LPT2 (if enabled) | +/// | 6 | Floppy Disk | +/// | 7 | LPT1 / Unreliable "spurious" interrupt (usually) | +/// | 8 | CMOS real-time clock (if enabled) | +/// | 9 | Free for peripherals / legacy SCSI / NIC | +/// | 10 | Free for peripherals / SCSI / NIC | +/// | 11 | Free for peripherals / SCSI / NIC | +/// | 12 | PS2 Mouse | +/// | 13 | FPU / Coprocessor / Inter-processor | +/// | 14 | Primary ATA Hard Disk | +/// | 15 | Secondary ATA Hard Disk | +#[allow(dead_code)] #[derive(Debug, Clone, Copy)] #[repr(u8)] pub enum InterruptIndex { - Timer = PIC_1_OFFSET, - Keyboard, // PS/2 + Timer = 0, + Ps2Keyboard, + Cascade, + Com2, + Com1, + Lpt2, + FloppyDisk, + Lpt1, + Cmos, + Ffp0, + Ffp1, + Ffp2, + Ps2Mouse, + Fpu, + PrimAtaHdd, + SecAtaHdd, +} + +impl InterruptIndex { + pub fn get(self) -> u8 { + (self as u8) + PIC_1_OFFSET + } } pub fn init_idt() { diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index d9a6780..f2ee410 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -5,13 +5,16 @@ #![allow(internal_features)] #![feature(ptr_internals)] #![feature(allocator_api)] +#![feature(downcast_unchecked)] -use std::vga::video::Color; +use std::{input::Keyboard, vga::video::Color}; use mem::paging::ActivePageTable; use multiboot2::{BootInformation, BootInformationHeader}; use pc_keyboard::KeyCode; - +use embedded_graphics::prelude::*; +use scheduler::{executor::Executor, Task}; +use utils::acpi_shutdown; extern crate alloc; @@ -25,6 +28,8 @@ mod events; mod mem; mod scheduler; mod std; +mod drivers; +mod acpi; fn init(mb2p: *const BootInformationHeader) -> ActivePageTable { logger::init(log::LevelFilter::Trace).unwrap(); @@ -33,24 +38,51 @@ fn init(mb2p: *const BootInformationHeader) -> ActivePageTable { utils::enable_nxe_bit(); utils::enable_write_protect_bit(); std::init(); - mem::init(mb2p) + let active_table = mem::init(mb2p); + { + let mut dm = drivers::DriverHandler::get_instance(); + dm.load_drivers(); + dm.start_drivers(); + } + active_table +} + +fn shutdown() -> ! { + { + let mut dm = drivers::DriverHandler::get_instance(); + dm.stop_drivers(); + } + + + acpi_shutdown() } #[no_mangle] extern "C" fn kmain(mb2p: *const BootInformationHeader) -> ! { - let _ = init(mb2p); // active table - - let vc = std::vga::video::VideoControler::new(mb2p); - // vc.set_px(0, 0, Color::new(0xFF, 0xFF, 0x0)); - vc.fill_screen(Color::new(0xFF, 0x0, 0x66)); + // let sch = Executor::new(); + let _ = init(mb2p); - log::info!("end of work"); - loop { - if std::input::is_key_down(KeyCode::A) { - log::info!(":3"); + + { + let mut dm = drivers::DriverHandler::get_instance(); + let driver = dm.get_driver::("PS/2"); + if let Some(driver) = driver { + log::debug!("{:?}", driver.test()); + } + } + + 'mainloop: loop { + if Keyboard::is_key_down(KeyCode::A) { + // vc.fill_screen(Color::new(0xFF, 0, 0)); + } else { + //vc.fill_screen(Color::new(0, 0xFF, 0)); + } + + if Keyboard::are_keys_down(&[KeyCode::LAlt, KeyCode::F4]) { + break 'mainloop; } } - // utils::hcf(); + shutdown() } diff --git a/kernel/src/mem/mod.rs b/kernel/src/mem/mod.rs index 8ff06a2..56045ae 100644 --- a/kernel/src/mem/mod.rs +++ b/kernel/src/mem/mod.rs @@ -35,7 +35,7 @@ pub struct Frame { impl Frame { - fn containing_address(address: usize) -> Frame { + pub fn containing_address(address: usize) -> Frame { Frame{ number: address / PAGE_SIZE } } fn start_address(&self) -> paging::PhysicalAddress { diff --git a/kernel/src/mem/paging/mapper.rs b/kernel/src/mem/paging/mapper.rs index d9a4464..3bea5fd 100644 --- a/kernel/src/mem/paging/mapper.rs +++ b/kernel/src/mem/paging/mapper.rs @@ -11,6 +11,7 @@ use super::{ }; use core::ptr::Unique; +#[derive(Debug, Clone)] pub struct Mapper { p4: Unique>, } diff --git a/kernel/src/mem/paging/mod.rs b/kernel/src/mem/paging/mod.rs index f209578..07ceb9d 100644 --- a/kernel/src/mem/paging/mod.rs +++ b/kernel/src/mem/paging/mod.rs @@ -20,7 +20,7 @@ pub struct Page { number: usize, } - +#[derive(Debug, Clone)] pub struct ActivePageTable { mapper: Mapper } @@ -39,7 +39,6 @@ impl DerefMut for ActivePageTable { } - impl ActivePageTable { unsafe fn new() -> ActivePageTable { ActivePageTable { @@ -211,7 +210,7 @@ pub fn remap_the_kernel(allocator: &mut A, mem_info: &MemInfo) -> ActivePageT let vga_video_buffer_frame_start = Frame::containing_address(mem_info.vga_vide_start); let vga_video_buffer_frame_end = Frame::containing_address(mem_info.vga_vide_start + mem_info.vga_vide_size); for frame in Frame::range_inclusive(vga_video_buffer_frame_start, vga_video_buffer_frame_end) { - mapper.identity_map(frame, EntryFlags::WRITABLE | EntryFlags::WRITE_THROUGH, allocator); + //mapper.identity_map(frame, EntryFlags::WRITABLE | EntryFlags::WRITE_THROUGH, allocator); } let multiboot_start = Frame::containing_address(mem_info.boot_info.start_address()); diff --git a/kernel/src/std/input.rs b/kernel/src/std/input.rs index 8cb1b1b..86b1fea 100644 --- a/kernel/src/std/input.rs +++ b/kernel/src/std/input.rs @@ -1,47 +1,94 @@ -use alloc::collections::{btree_set::BTreeSet, vec_deque::VecDeque}; -use pc_keyboard::{KeyCode, KeyEvent, KeyState}; -use spin::Mutex; +use core::{arch::asm, future::Future}; -use crate::events::{Event, EVENTMAN}; +use alloc::{collections::{btree_set::BTreeSet, vec_deque::VecDeque}, vec::Vec}; +use pc_keyboard::{KeyCode, KeyEvent, KeyState}; +use spin::{Lazy, Mutex, MutexGuard}; +use x86_64::instructions::port::{Port, PortGeneric, ReadWriteAccess}; + +use crate::{events::{Event, EVENTMAN}, scheduler::{executor::Executor, Task}}; static mut KEYS_PRESSED: Mutex> = Mutex::new(BTreeSet::new()); static mut KEY_BUF: VecDeque = VecDeque::new(); const KEY_BUF_MAX_LEN: usize = 32; -pub(super) unsafe fn init() { - EVENTMAN.lock().add_listener(crate::events::Event::Ps2KeyEvent(None), |e| { - let Event::Ps2KeyEvent(ke) = e else {panic!()}; - if let Some(ke) = ke { - if KEY_BUF.len() > KEY_BUF_MAX_LEN { - KEY_BUF.pop_front(); +pub struct Keyboard; +impl Keyboard { + pub(super) unsafe fn init() { + EVENTMAN.lock().add_listener(crate::events::Event::Ps2KeyEvent(None), |e| { + let Event::Ps2KeyEvent(ke) = e else {panic!()}; + if let Some(ke) = ke { + if KEY_BUF.len() > KEY_BUF_MAX_LEN { + KEY_BUF.pop_front(); + } + KEY_BUF.push_back(ke.clone()); } - KEY_BUF.push_back(ke.clone()); - } - Ok(()) - }) -} - -// TODO: It is possible for `KEY_BUF` to get overfilled and lose data and make keys stuck. -// Possibly run this every now an again somehow -unsafe fn process_events() { - while !KEY_BUF.is_empty() { - if let Some(ke) = KEY_BUF.pop_front() { - match ke.state { - KeyState::Down => { - KEYS_PRESSED.lock().insert(ke.code); + Ok(()) + }); + } + + pub fn keys_pressed<'a>() -> MutexGuard<'a, BTreeSet> { + unsafe { KEYS_PRESSED.lock() } + } + // TODO: It is possible for `KEY_BUF` to get overfilled and lose data and make keys stuck. + // Possibly run this every now an again somehow + unsafe fn process_events() { + while !KEY_BUF.is_empty() { + if let Some(ke) = KEY_BUF.pop_front() { + match ke.state { + KeyState::Down => { + Self::keys_pressed().insert(ke.code); + } + KeyState::Up => { + Self::keys_pressed().remove(&ke.code); + } + _ => () } - KeyState::Up => { - KEYS_PRESSED.lock().remove(&ke.code); - } - _ => () } } } + + + pub fn is_key_down(key: KeyCode) -> bool { + unsafe { + Self::process_events(); + return Self::keys_pressed().contains(&key); + } + } + + pub fn are_keys_down(keys: &[KeyCode]) -> bool { + for key in keys { + if !Self::keys_pressed().contains(key) { + return false; + } + } + true + } + + } -pub fn is_key_down(key: KeyCode) -> bool { - unsafe { - process_events(); - return KEYS_PRESSED.lock().contains(&key); - } +pub static MOUSE: Lazy> = Lazy::new(|| Mutex::new(Mouse::new())); + +pub struct Mouse { } + +impl Mouse { + pub const fn new() -> Self { + Self { + } + } + + fn get() { + let a = MOUSE.lock(); + } + + pub(super) fn init() { + } + + fn on_move() { + + } + + +} + diff --git a/kernel/src/std/mod.rs b/kernel/src/std/mod.rs index dbb2d2c..62583b8 100644 --- a/kernel/src/std/mod.rs +++ b/kernel/src/std/mod.rs @@ -1,8 +1,11 @@ +use crate::scheduler::executor::Executor; + pub mod input; pub mod vga; +pub mod typemap; pub fn init() { - unsafe { input::init(); }; + unsafe { input::Keyboard::init(); }; } diff --git a/kernel/src/std/typemap.rs b/kernel/src/std/typemap.rs new file mode 100644 index 0000000..758bdae --- /dev/null +++ b/kernel/src/std/typemap.rs @@ -0,0 +1,37 @@ +use core::{any::{Any, TypeId}, marker::PhantomData, ops::Deref}; + +use alloc::{borrow::ToOwned, boxed::Box, vec}; +use hashbrown::HashMap; + + +#[derive(Debug)] +pub struct TypeMap<'a> { + map: HashMap>, + _phantom: PhantomData<&'a ()> +} + +impl TypeMap<'_> { + pub fn new() -> Self { + Self { + map: HashMap::new(), + _phantom: PhantomData + } + } + + pub fn insert(&mut self, value: T) { + self.map.insert(TypeId::of::(), Box::new(value)); + } + + pub fn get(&self) -> Option<&T> { + self.map.get(&TypeId::of::()).and_then(|boxed| boxed.downcast_ref::()) + } +} + + +impl<'a> IntoIterator for TypeMap<'a> { + type Item = (TypeId, Box); + type IntoIter = hashbrown::hash_map::IntoIter>; + fn into_iter(self) -> Self::IntoIter { + self.map.into_iter() + } +} diff --git a/kernel/src/std/vga/video/mod.rs b/kernel/src/std/vga/video/mod.rs index 820874f..3df8f25 100644 --- a/kernel/src/std/vga/video/mod.rs +++ b/kernel/src/std/vga/video/mod.rs @@ -1,11 +1,7 @@ mod util; -use core::{borrow::BorrowMut, ops::Deref}; -use alloc::boxed::Box; -use lazy_static::lazy_static; +use embedded_graphics::{pixelcolor::Rgb888, prelude::{DrawTarget, OriginDimensions, PixelColor, RgbColor, Size}}; use multiboot2::{BootInformation, BootInformationHeader, FramebufferTag, FramebufferType, TagTrait}; -use nalgebra::Vector2; -use spin::{Mutex, MutexGuard}; pub use util::is_video_mode_enabled; @@ -21,7 +17,7 @@ impl Color { Self {r, g, b} } } - +#[derive(Clone, Copy)] pub struct VideoControler{ component_size: u8, r_ofs: u8, @@ -29,7 +25,7 @@ pub struct VideoControler{ b_ofs: u8, buf_addr: u64, pitch: usize, - size: Vector2, + size: [usize; 2], bpp: u8 } @@ -51,14 +47,14 @@ impl VideoControler { g_ofs: green.position, b_ofs: blue.position, buf_addr: fbt.address(), - size: Vector2::new(fbt.width() as usize, fbt.height() as usize), + size: [fbt.width() as usize, fbt.height() as usize], pitch: fbt.pitch() as usize, bpp: fbt.bpp(), } } pub fn set_px(&self, x: usize, y: usize, c: Color) { - assert!(x <= self.size.x && y <= self.size.x); + assert!(x <= self.size[0] && y <= self.size[1]); let ptr = self.buf_addr as *mut () as *mut u8; let px = ptr.wrapping_add((self.bpp / 8) as usize * x + self.pitch * y); unsafe { @@ -69,11 +65,56 @@ impl VideoControler { } pub fn fill_screen(&self, c: Color) { - for x in 0..self.size.x { - for y in 0..self.size.y { + for x in 0..self.size[0] { + for y in 0..self.size[1] { self.set_px(x, y, c); } } } - + + pub fn fill_screen_grad(&self, start: Color, end: Color) { + let diag = libm::sqrt((self.size[0].pow(2) + self.size[1].pow(2)) as f64); + for x in 0..self.size[0] { + for y in 0..self.size[1] { + let dist = libm::sqrt((x.pow(2) + y.pow(2)) as f64); + let fact = dist / diag; + let color = Color::new( + start.r + (fact * (end.r - start.r) as f64) as u8, + start.g + (fact * (end.g - start.g) as f64) as u8, + start.b + (fact * (end.b - start.b) as f64) as u8, + ); + self.set_px(x, y, color); + } + } + } +} + +impl DrawTarget for VideoControler { + type Color = Rgb888; + type Error = &'static str; + fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> + where + I: IntoIterator> { + for px in pixels { + self.set_px( + px.0.x as usize, + px.0.y as usize, + px.1.into() + ) + } + + Ok(()) + } +} + +impl OriginDimensions for VideoControler { + fn size(&self) -> embedded_graphics::prelude::Size { + Size::new(self.size[0] as u32, self.size[1] as u32) + } +} + +impl From for Color { + fn from(c: Rgb888) -> Self { + Color::new(c.r(), c.g(), c.b()) + } } diff --git a/kernel/src/utils.rs b/kernel/src/utils.rs index e9114b7..7ae0ff3 100644 --- a/kernel/src/utils.rs +++ b/kernel/src/utils.rs @@ -1,7 +1,7 @@ -use core::arch::asm; +use core::{any::Any, arch::asm}; use x86::msr::{rdmsr, wrmsr, IA32_EFER}; -use x86_64::{instructions, registers::{control::{Cr0, Cr0Flags}, segmentation::{Segment, DS}}, PrivilegeLevel}; +use x86_64::{instructions::{self, port::PortWriteOnly}, registers::{control::{Cr0, Cr0Flags}, segmentation::{Segment, DS}}, PrivilegeLevel}; use crate::mem::paging::{ActivePageTable, VirtualAddress}; @@ -54,3 +54,14 @@ pub unsafe fn jmp_to_usermode(apt: ActivePageTable, code: VirtualAddress, stack_ code = in(reg) code_addr, sa = in(reg) sa_addr, cs = in(reg) cs_idx, ds = in(reg) ds_idx); } +pub fn acpi_shutdown() -> ! { + let mut port = x86_64::instructions::port::Port::new(0x0604); + unsafe { + port.write(0x2000_u16); + } + loop {hcf()} +} + +pub fn as_any_mut(i: &mut T) -> &mut dyn Any { + i as &mut dyn Any +}