From 154c9512dcbed6b16a7a6914f3a5515ef98c6828 Mon Sep 17 00:00:00 2001 From: shibedrill Date: Mon, 19 May 2025 10:16:51 -0400 Subject: [PATCH] Some work on GDT setup --- Cargo.lock | 43 +++++++++++++++++++++++++++++++- Cargo.toml | 4 +++ Makefile.toml | 2 +- README.md | 7 +++--- src/kernel/arch/mod.rs | 8 +++--- src/kernel/arch/x86_64/asm.rs | 12 +++++++++ src/kernel/arch/x86_64/gdt.rs | 23 +++++++++++++++++ src/kernel/arch/x86_64/mod.rs | 1 + src/kernel/arch/x86_64/serial.rs | 3 ++- src/kernel/constants.rs | 30 ++++++++++++++++++++++ src/kernel/main.rs | 37 +++++++++++++++++---------- src/kernel/process.rs | 36 +------------------------- 12 files changed, 148 insertions(+), 58 deletions(-) create mode 100644 src/kernel/arch/x86_64/gdt.rs diff --git a/Cargo.lock b/Cargo.lock index ca1d12b..639a2a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,11 +100,22 @@ dependencies = [ "acpi", "enumflags2", "flagset", + "lazy_static", "limine", "lzma-rs", "once_cell", - "spin", + "spin 0.10.0", "talc", + "x86_64", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", ] [[package]] @@ -182,12 +193,24 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spin" version = "0.10.0" @@ -222,3 +245,21 @@ name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "volatile" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793" + +[[package]] +name = "x86_64" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f042214de98141e9c8706e8192b73f56494087cc55ebec28ce10f26c5c364ae" +dependencies = [ + "bit_field", + "bitflags", + "rustversion", + "volatile", +] diff --git a/Cargo.toml b/Cargo.toml index 00f67c8..ef5b213 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,12 +7,16 @@ edition = "2024" acpi = "5.1.0" enumflags2 = "0.7.11" flagset = "0.4.7" +lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } limine = "0.4.0" lzma-rs = { git = "https://github.com/glaeqen/lzma-no-std-rs/", version = "0.2.0", default-features = false } once_cell = { version = "1.20.3", default-features = false, features = ["alloc", "critical-section"] } spin = "0.10.0" talc = "4.4.2" +[target.'cfg(target_arch = "x86_64")'.dependencies] +x86_64 = "0.15.2" + [lib] name = "gila" path = "src/lib/lib.rs" diff --git a/Makefile.toml b/Makefile.toml index 8942a4b..238f5f8 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -62,7 +62,7 @@ args = ["-rf", "build/initramfs", "build/initramfs.tar.lzma"] condition = { files_modified = { input = ["src/lib/**/*.rs"], output = ["${ARTIFACTDIR}/libgila.rlib"] }, fail_message = "(inputs unchanged)" } dependencies = ["prepare"] command = "cargo" -args = ["build", "--lib"] +args = ["build", "--profile", "${PROFILE}", "--lib"] [tasks.kernel] condition = { files_modified = { input = [ diff --git a/README.md b/README.md index f5ba969..15c9c6f 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,8 @@ Licensed under the GNU Public License v3. See [LICENSE](LICENSE) for details. - [kernel/](src/kernel/): Kernel-specific code. - [arch/](src/kernel/arch/): Architecture specific features like the display, serial, and interrupts. Each architecture is a subfolder, containing a file or module for each feature. - [boot.rs](src/kernel/boot.rs): Handles bootloader-managed data structures. Gila uses Limine. Other bootloaders are NOT supported. - - [log.rs](src/kernel/log.rs): Logging structures and singletons for logging to serial or the display. + - [constants.rs](src/kernel/constants.rs): Constants referenced elsewhere in the kernel. + - [log.rs](src/kernel/log.rs): Logging structures, macros, and singletons for logging to serial or the display. - [main.rs](src/kernel/main.rs): The entry point that gets called by the bootloader. - [memory.rs](src/kernel/memory.rs): Types relating to memory regions and allocation. - [panic.rs](src/kernel/panic.rs): The panic handler and associated functionality. @@ -100,13 +101,13 @@ Kernel parameters are passed as part of the `cmdline` through [limine.conf](limi List of current extant kernel parameters: -- `-loglevel`: Can be a number or string corresponding to a log level. Only one value supported. +- `-loglevel`: Can be a number or string corresponding to a log level. Only one value supported. Current options are `Disabled`, `Trace`, `Info`, `Warning`, `Error`, and `Critical`. - `-logdev`: A sequence of one or more values representing devices to log to. Current options are `display` and `serial`. - `-initramfs`: A valid path to a module to serve as the initramfs (containing the init binary). Only one value supported. The default behavior for each parameter, when not supplied, is: -`-loglevel=Trace -initramfs=/boot/initramfs.tar.lzma` +`-loglevel=Info -initramfs=/boot/initramfs.tar.lzma` ## Credits diff --git a/src/kernel/arch/mod.rs b/src/kernel/arch/mod.rs index 4973b91..c894aa2 100644 --- a/src/kernel/arch/mod.rs +++ b/src/kernel/arch/mod.rs @@ -4,19 +4,19 @@ #[cfg(target_arch = "x86_64")] pub mod x86_64; #[cfg(target_arch = "x86_64")] -pub use x86_64 as current; +pub use x86_64::asm; #[cfg(target_arch = "aarch64")] pub mod aarch64; #[cfg(target_arch = "aarch64")] -pub use aarch64 as current; +pub use aarch64::asm; #[cfg(target_arch = "riscv64")] pub mod riscv64; #[cfg(target_arch = "riscv64")] -pub use riscv64 as current; +pub use riscv64::asm; #[cfg(target_arch = "loongarch64")] pub mod loongarch64; #[cfg(target_arch = "loongarch64")] -pub use loongarch64 as current; +pub use loongarch64::asm; diff --git a/src/kernel/arch/x86_64/asm.rs b/src/kernel/arch/x86_64/asm.rs index 647aa4c..b382a75 100644 --- a/src/kernel/arch/x86_64/asm.rs +++ b/src/kernel/arch/x86_64/asm.rs @@ -6,6 +6,18 @@ use core::arch::asm; +pub unsafe fn interrupt_disable() { + unsafe { + asm!("cli"); + } +} + +pub unsafe fn interrupt_enable() { + unsafe { + asm!("sti"); + } +} + pub unsafe fn halt() { unsafe { asm!("hlt"); diff --git a/src/kernel/arch/x86_64/gdt.rs b/src/kernel/arch/x86_64/gdt.rs new file mode 100644 index 0000000..59ce8ca --- /dev/null +++ b/src/kernel/arch/x86_64/gdt.rs @@ -0,0 +1,23 @@ +use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable}; + +use lazy_static::lazy_static; + +use super::asm::*; + +lazy_static! { + pub static ref GDT: GlobalDescriptorTable = { + let mut gdt = GlobalDescriptorTable::new(); + gdt.append(Descriptor::kernel_code_segment()); + gdt + }; +} + +pub fn setup_gdt() { + unsafe { + interrupt_disable(); + } + GDT.load(); + unsafe { + interrupt_enable(); + } +} diff --git a/src/kernel/arch/x86_64/mod.rs b/src/kernel/arch/x86_64/mod.rs index ab2b8ea..767c2f7 100644 --- a/src/kernel/arch/x86_64/mod.rs +++ b/src/kernel/arch/x86_64/mod.rs @@ -3,4 +3,5 @@ pub mod acpi; pub mod asm; +pub mod gdt; pub mod serial; diff --git a/src/kernel/arch/x86_64/serial.rs b/src/kernel/arch/x86_64/serial.rs index ad92105..f684cd8 100644 --- a/src/kernel/arch/x86_64/serial.rs +++ b/src/kernel/arch/x86_64/serial.rs @@ -1,7 +1,8 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: GPL-3.0-or-later -use crate::{asm::*, log::LogSubscriber}; +use crate::arch::asm::*; +use crate::log::LogSubscriber; #[derive(Clone, Copy)] pub struct Serialport { diff --git a/src/kernel/constants.rs b/src/kernel/constants.rs index 83e7b77..8cb0b44 100644 --- a/src/kernel/constants.rs +++ b/src/kernel/constants.rs @@ -1,9 +1,39 @@ +use crate::format; use crate::log::LogLevel; +use crate::memory::alloc::string::String; pub static INITRAMFS_DEFAULT_PATH: &str = "/boot/initramfs.tar.lzma"; pub static LOG_DEFAULT_LEVEL: LogLevel = LogLevel::Info; +pub static KERNEL_BUILD_PROFILE: &str = { + if cfg!(debug_assertions) { + "debug" + } else { + "release" + } +}; + +pub static KERNEL_ARCH: &str = { + if cfg!(target_arch = "x86_64") { + "x86_64" + } else if cfg!(target_arch = "aarch64") { + "aarch64" + } else if cfg!(target_arch = "loongarch64") { + "loongarch64" + } else if cfg!(target_arch = "riscv64") { + "riscv64" + } else { + "unsupported" + } +}; + +pub fn kernel_version_string() -> String { + format!( + "{KERNEL_VERSION_MAJOR}.{KERNEL_VERSION_MINOR}.{KERNEL_VERSION_PATCH}-{KERNEL_ARCH}-{KERNEL_BUILD_PROFILE}" + ) +} + // FUCKING ADD CONST UNWRAP!!! pub static KERNEL_VERSION_MAJOR: u8 = match u8::from_str_radix(env!("CARGO_PKG_VERSION_MAJOR"), 10) { diff --git a/src/kernel/main.rs b/src/kernel/main.rs index 9372e84..8cd136f 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -3,6 +3,7 @@ #![no_std] #![no_main] +#![feature(cfg_match)] #![feature(allocator_api)] mod arch; @@ -17,7 +18,9 @@ mod process; mod resources; mod syscall_runner; -use arch::current::*; +use core::ptr; + +use arch::x86_64::gdt::{self, GDT}; use arch::x86_64::serial::Serialport; use boot::*; use constants::*; @@ -72,9 +75,7 @@ unsafe extern "C" fn main() -> ! { "Boot: Kernel file path: {}", String::from_utf8_lossy(executable_file_response.file().path().to_bytes()) ); - log_info!( - "Boot: Booting gila version {KERNEL_VERSION_MAJOR}.{KERNEL_VERSION_MINOR}.{KERNEL_VERSION_PATCH}" - ); + log_info!("Boot: Booting gila version {}", kernel_version_string()); log_info!("Boot: Trans rights!"); @@ -110,10 +111,14 @@ unsafe extern "C" fn main() -> ! { module_response.modules().len() ); if !module_response.modules().is_empty() { - log_trace!("Boot: Kernel modules list:"); + let mut log_msg: String = String::from("Boot: Kernel modules list:\n"); for module in module_response.modules() { - log_trace!("\t{}", String::from_utf8_lossy(module.path().to_bytes())); + log_msg.push_str(&format!( + "\t\t{}", + String::from_utf8_lossy(module.path().to_bytes()) + )); } + log_trace!("{log_msg}") } let irfs_path = { @@ -140,14 +145,14 @@ unsafe extern "C" fn main() -> ! { if let Some(mmap_response) = MEMMAP_REQUEST.get_response() { log_info!("Boot: Memory map received"); if !mmap_response.entries().is_empty() { - log_trace!("Boot: Memory map entries list:"); + let mut log_msg: String = String::from("Boot: Memory map:"); let mut usable: u64 = 0; let mut reclaimable: u64 = 0; let mut hardware: u64 = 0; let mut unusable: u64 = 0; for entry in mmap_response.entries() { - log_trace!( - "\t{} bytes @ 0x{:x}: {}", + log_msg.push_str(&format!( + "\n\t\t0x{:x} bytes @ 0x{:x}: {}", entry.length, entry.base, match entry.entry_type { @@ -186,17 +191,23 @@ unsafe extern "C" fn main() -> ! { } _ => "unidentified", } - ) + )); } + log_trace!("{log_msg}"); + let total = usable + reclaimable + hardware + unusable; log_info!( - "Boot: Memory report:\n\tFree: {usable}\n\tAvailable: {reclaimable}\n\tUsable: {}\n\tHardware: {hardware}\n\tUnusable: {unusable}\n\tTotal: {}", + "Boot: Memory report:\n\t\tFree: {usable}\n\t\tAvailable: {reclaimable}\n\t\tUsable: {}\n\t\tHardware: {hardware}\n\t\tUnusable: {unusable}\n\t\tTotal: {}", usable + reclaimable, - usable + reclaimable + hardware + unusable + total ); } } - panic!("Test panic"); + log_trace!( + "GDT: Setting up global descriptor table at 0x{:x}", + ptr::addr_of!(GDT) as usize + ); + gdt::setup_gdt(); #[allow(unreachable_code)] loop { diff --git a/src/kernel/process.rs b/src/kernel/process.rs index 66fd750..0037390 100644 --- a/src/kernel/process.rs +++ b/src/kernel/process.rs @@ -2,13 +2,12 @@ use enumflags2::{BitFlags, bitflags, make_bitflags}; -use crate::arch::current; +use crate::arch::asm; use crate::memory::MemoryRegion; use crate::memory::MemoryRegionFlags; use crate::memory::alloc; use alloc::string::String; use alloc::vec::Vec; -use current::asm; #[allow(dead_code)] pub struct ProcessTable {} @@ -33,10 +32,6 @@ pub struct Process { mem_region: MemoryRegion, /// Process priority. Lower number is higher priority. prio: u16, - /// Which semaphor the process is waiting on. - semaphor_wait: Option, - /// What capabilities the process has - capabilities: BitFlags, } #[allow(dead_code)] @@ -57,35 +52,6 @@ pub enum ProcessState { Suspended, } -#[bitflags] -#[repr(u32)] -#[derive(Copy, Clone)] -pub enum ProcessCapabilities { - // Process capabilities - ProcessEnum, // Enumerate running process IDs and names - ProcessRead, // Read information from a process struct - ProcessKill, // Kill any process - ProcessSpawn, // Create a new process - ProcessExec, // Replace self with new process image - ProcessSession, // Create and accept IPC requests. - // Capability meta - CapabilityRead, // Inspect a process's capabilities - CapabilityAdd, // Add a capability to a process - // Hardware access capabilities - HardwareWrite, // Write to memory-mapped IO - HardwareRead, // Read from memory-mapped IO - HardwareLock, // Obtain exclusive access to a device - HardwareQuery, // Check on the lock status of a device - // Kernel config capabilities - KernelCfgRead, // Read kernel configurations - KernelCfgWrite, // Modify kernel configurations - KernelProtCall, // Call protected kernel functions - // Server resolution capabilities - ServerEnum, // Enumerate server processes - ServerGet, // Get the PID of a specific server for IPC. - ServerRegister, // Register a process as a server. -} - // Interprocess communication system: // Processes communicate through "sessions" which are mediated by the kernel. // Sessions can only be opened if two processes both request a session with