diff --git a/Cargo.lock b/Cargo.lock index 36412dc..ac43214 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,6 +110,7 @@ dependencies = [ "limine", "lzma-rs", "once_cell", + "raw-cpuid", "spin 0.10.0", "talc", "x86_64", @@ -199,6 +200,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags", +] + [[package]] name = "rustversion" version = "1.0.20" diff --git a/Cargo.toml b/Cargo.toml index 763261c..eeb4bda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ lazy_static = { version = "1.5.0", default-features = false, features = ["spin_n 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"] } +raw-cpuid = "11.5.0" spin = "0.10.0" talc = "4.4.2" x86_64 = "0.15.2" diff --git a/Makefile.toml b/Makefile.toml index bbc81ec..910665e 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -52,8 +52,10 @@ alias = "run" -[tasks.clean] -dependencies = ["clean_iso", "clean_initramfs"] +[tasks.clean_all] +run_task = { name = ["clean_kernel", "clean_initramfs", "clean_iso"] } + +[tasks.clean_kernel] command = "cargo" args = ["clean"] @@ -154,4 +156,17 @@ script = ''' [tasks.run] dependencies = ["iso"] command = "${QEMUCOMMAND}" -args = ["-drive", "file=build/gila.iso,format=raw,index=0,media=disk", "-serial", "stdio"] \ No newline at end of file +args = ["-display", "none", "-drive", "file=build/gila.iso,format=raw,index=0,media=disk", "-serial", "stdio"] + +[tasks.debug_run] +dependencies = ["iso"] +command = "${QEMUCOMMAND}" +args = ["-s", "-S", "-display", "none", "-drive", "file=build/gila.iso,format=raw,index=0,media=disk", "-serial", "stdio"] + +[tasks.debug_view] +dependencies = ["iso"] +command = "gdb" +args = ["${ARTIFACTDIR}/kernel", "--eval-command=target remote localhost:1234"] + +[tasks.debug] +run_task = { name = ["debug-run", "debug-view"], fork = true, parallel = true } \ No newline at end of file diff --git a/README.md b/README.md index f165903..9b85b5e 100644 --- a/README.md +++ b/README.md @@ -45,19 +45,21 @@ 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. + - [boot/](src/kernel/boot/mod.rs): Handles bootloader-managed data structures. Gila uses Limine. Other bootloaders are NOT supported. + - [params.rs](src/kernel/boot/params.rs): Command line parameter parsing. + - [modules.rs](src/kernel/boot/modules.rs): Kernel module handling. - [constants.rs](src/kernel/constants.rs): Constants referenced elsewhere in the kernel. - - [device.rs](src/kernel/device.rs): Functions for discovering hardware and assigning drivers. + - [device/](src/kernel/device/mod.rs): Functions for discovering hardware and assigning drivers. + -[acpi.rs](src/kernel/device/acpi.rs): ACPI handling functions and structures. - [log.rs](src/kernel/log.rs): Logging structures, macros, and singletons for logging to serial or the display. + - [interrupt/](src/kernel/interrupt/mod.rs): Interrupt handlers with platform-agnostic APIs. - [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. - - [params.rs](src/kernel/params.rs): Kernel parameter handler code. - [process.rs](src/kernel/process.rs): Process types and functions. - - [resources.rs](src/kernel/resources.rs): Resources that are accessible from multiple parts of the code. - [syscall_runner.rs](src/kernel/syscall_runner.rs): Chooses a system call by its ID and defers actual syscall execution to code in `src/lib/`. -- [lib/](src/lib/): Library that all Gila's binary programs will be built against. Some of this code is shared with the kernel. - - [arch/](src/lib/arch/): Architecture specific functionality like system call register storing/loading. +- [lib/](src/lib/lib.rs): Library that all Gila's binary programs will be built against. Some of this code is shared with the kernel. + - [arch/](src/lib/arch/mod.rs): Architecture specific functionality like system call register storing/loading. - [syscall.rs](src/lib/syscall.rs): System call types common to apps and the kernel. ## Building and running @@ -75,15 +77,19 @@ This project uses [cargo-make](https://github.com/sagiegurari/cargo-make) to han Then run `cargo make` to invoke the [Makefile.toml](Makefile.toml). - `cargo make prepare`: Installs needed Rust toolchain. -- `cargo make clean`: Cleans all built binaries, libraries, initramfs files, and ISOs. +- `cargo make clean_all`: Cleans all built binaries, libraries, initramfs files, and ISOs. - `cargo make clean_iso`: Clean only files involved in building the ISO. - `cargo make clean_initramfs`: Clean only files involved in building the initramfs. +- `cargo make clean_kernel`: Clean only kernel binaries and libraries. - `cargo make lib`: Builds `libgila`, the library that the kernel and user code are linked against. - `cargo make kernel`: Builds the kernel ELF file. - `cargo make bins`: Builds all binaries included in the system. - `cargo make initramfs`: Build the init archive. - `cargo make iso`: Builds the bootable ISO with Limine installed. - `cargo make run`: Builds the ISO and boots it in QEMU. +- `cargo make debug`: Launch the kernel in QEMU with debugging enabled, and start and connect GDB. +- `cargo make debug_run`: Launch the kernel in QEMU for debugging. +- `cargo make debug_view`: Attach to a running QEMU process to debug. You do not need to clean any files after making changes. The `lib`, `kernel`, and `iso` tasks will automatically be rerun if their input files change. diff --git a/limine.conf b/limine.conf index 01b3ae2..bfb209e 100644 --- a/limine.conf +++ b/limine.conf @@ -1,4 +1,4 @@ -timeout: 2 +timeout: 0 /Gila protocol: limine diff --git a/src/kernel/arch/x86_64/asm.rs b/src/kernel/arch/x86_64/asm.rs index b382a75..38913b5 100644 --- a/src/kernel/arch/x86_64/asm.rs +++ b/src/kernel/arch/x86_64/asm.rs @@ -6,6 +6,12 @@ use core::arch::asm; +pub unsafe fn cr0() -> u64 { + let mut cr0: u64; + unsafe { asm!("mov {0:r}, cr0", out(reg) cr0) } + cr0 +} + pub unsafe fn interrupt_disable() { unsafe { asm!("cli"); diff --git a/src/kernel/arch/x86_64/interrupts.rs b/src/kernel/arch/x86_64/interrupts.rs index 26503c2..73d1149 100644 --- a/src/kernel/arch/x86_64/interrupts.rs +++ b/src/kernel/arch/x86_64/interrupts.rs @@ -16,4 +16,4 @@ lazy_static! { extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! { crate::interrupt::double_fault(&format!("{info:#?}")); -} \ No newline at end of file +} diff --git a/src/kernel/arch/x86_64/mod.rs b/src/kernel/arch/x86_64/mod.rs index 2fe8b4d..ed81a84 100644 --- a/src/kernel/arch/x86_64/mod.rs +++ b/src/kernel/arch/x86_64/mod.rs @@ -1,7 +1,6 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: GPL-3.0-or-later -pub mod acpi; pub mod asm; pub mod gdt; pub mod interrupts; diff --git a/src/kernel/arch/x86_64/acpi.rs b/src/kernel/device/acpi.rs similarity index 100% rename from src/kernel/arch/x86_64/acpi.rs rename to src/kernel/device/acpi.rs diff --git a/src/kernel/device.rs b/src/kernel/device/mod.rs similarity index 82% rename from src/kernel/device.rs rename to src/kernel/device/mod.rs index 656603f..5d9847e 100644 --- a/src/kernel/device.rs +++ b/src/kernel/device/mod.rs @@ -1,14 +1,26 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: GPL-3.0-or-later +mod acpi; + use fdt::*; use lazy_static::lazy_static; use limine::response::{DeviceTreeBlobResponse, RsdpResponse}; +use raw_cpuid::native_cpuid::CpuIdReaderNative; +use raw_cpuid::*; use crate::boot::{DTB_REQUEST, RSDP_REQUEST}; use crate::log::{LOGGER, LogLevel}; use crate::{format, log_info, log_trace, log_warning}; +pub fn log_cpuid() { + let cpuid: CpuId = CpuId::with_cpuid_reader(CpuIdReaderNative); + log_trace!( + "Device: CPU vendor: {}", + cpuid.get_processor_brand_string().unwrap().as_str() + ) +} + lazy_static! { pub static ref DTB: Option<&'static DeviceTreeBlobResponse> = match DTB_REQUEST.get_response() { Some(resp) => { diff --git a/src/kernel/interrupt/mod.rs b/src/kernel/interrupt/mod.rs index 16f854e..a0c44b6 100644 --- a/src/kernel/interrupt/mod.rs +++ b/src/kernel/interrupt/mod.rs @@ -1,4 +1,3 @@ - pub fn double_fault(info: &str) -> ! { panic!("Double fault: {}", info); } diff --git a/src/kernel/main.rs b/src/kernel/main.rs index e6a786a..036d0f9 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -22,8 +22,10 @@ mod util; #[cfg(target_arch = "x86_64")] use arch::x86_64::serial::Serialport; +use arch::asm::*; use boot::{modules::*, params, *}; use constants::*; +use device::*; use log::*; use memory::alloc::{format, string::*, vec}; use params::*; @@ -196,10 +198,19 @@ unsafe extern "C" fn main() -> ! { //#[cfg(target_arch = "x86_64")] //gdt::setup_gdt(); - arch::x86_64::interrupts::IDT.load(); - unsafe { - *(0xdeadbeef as *mut u8) = 42; - }; + #[cfg(target_arch = "x86_64")] + { + log_trace!( + "Boot: Protected mode enable: {}", + unsafe { cr0() & 0b1 } == 1 + ); + log_trace!( + "Boot: Paging enable: {}", + unsafe { cr0() & (0b1 << 31) } == 1 + ); + } + + log_cpuid(); panic!("Bailing"); diff --git a/src/kernel/panic.rs b/src/kernel/panic.rs index b715703..a6d8903 100644 --- a/src/kernel/panic.rs +++ b/src/kernel/panic.rs @@ -10,11 +10,7 @@ use crate::{LOGGER, LogLevel}; #[panic_handler] pub fn panic(info: &PanicInfo) -> ! { - log_critical!( - "Panic in {}: {}", - info.location().unwrap(), - info.message() - ); + log_critical!("Panic in {}: {}", info.location().unwrap(), info.message()); loop { unsafe { asm!("nop"); diff --git a/src/kernel/util.rs b/src/kernel/util.rs index 6f43e29..774552b 100644 --- a/src/kernel/util.rs +++ b/src/kernel/util.rs @@ -1,4 +1,3 @@ - #[macro_export] macro_rules! critical_section { ($b:block) => { @@ -6,4 +5,4 @@ macro_rules! critical_section { $b unsafe { $crate::arch::asm::interrupt_enable(); } }; -} \ No newline at end of file +}