Compare commits

...

2 Commits

Author SHA1 Message Date
1bd0c60b93
Critical section macro 2025-05-26 00:07:44 -04:00
f569497776
Fault handling stuff 2025-05-25 23:58:00 -04:00
15 changed files with 108 additions and 41 deletions

View File

@ -14,6 +14,7 @@ lzma-rs = { git = "https://github.com/glaeqen/lzma-no-std-rs/", version = "0.2.0
once_cell = { version = "1.20.3", default-features = false, features = ["alloc", "critical-section"] } once_cell = { version = "1.20.3", default-features = false, features = ["alloc", "critical-section"] }
spin = "0.10.0" spin = "0.10.0"
talc = "4.4.2" talc = "4.4.2"
x86_64 = "0.15.2"
[target.'cfg(target_arch = "x86_64")'.dependencies] [target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = "0.15.2" x86_64 = "0.15.2"

View File

@ -2,10 +2,8 @@ use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use super::asm::*;
use crate::log::{LOGGER, LogLevel}; use crate::log::{LOGGER, LogLevel};
use crate::{format, log_trace}; use crate::{critical_section, format, log_trace};
lazy_static! { lazy_static! {
pub static ref GDT: GlobalDescriptorTable = { pub static ref GDT: GlobalDescriptorTable = {
@ -15,16 +13,13 @@ lazy_static! {
}; };
} }
#[allow(dead_code)]
pub fn setup_gdt() { pub fn setup_gdt() {
unsafe { critical_section!({
interrupt_disable();
}
GDT.load(); GDT.load();
log_trace!( log_trace!(
"GDT: Setting up global descriptor table at 0x{:x}", "GDT: Setting up global descriptor table at 0x{:x}",
core::ptr::addr_of!(GDT) as usize core::ptr::addr_of!(GDT) as usize
); );
unsafe { });
interrupt_enable();
}
} }

View File

@ -0,0 +1,19 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
use lazy_static::lazy_static;
use x86_64::structures::idt::*;
use crate::format;
lazy_static! {
pub static ref IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new();
idt.double_fault.set_handler_fn(double_fault);
idt
};
}
extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
crate::interrupt::double_fault(&format!("{info:#?}"));
}

View File

@ -4,4 +4,5 @@
pub mod acpi; pub mod acpi;
pub mod asm; pub mod asm;
pub mod gdt; pub mod gdt;
pub mod interrupts;
pub mod serial; pub mod serial;

View File

@ -1,6 +1,9 @@
// Copyright (c) 2025 shibedrill // Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
pub mod modules;
pub mod params;
use limine::{BaseRevision, request::*}; use limine::{BaseRevision, request::*};
#[used] #[used]

View File

@ -0,0 +1,15 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
use lazy_static::lazy_static;
use limine::response::ModuleResponse;
use crate::boot::MODULE_REQUEST;
lazy_static! {
pub static ref MODULE_RESPONSE: &'static ModuleResponse = MODULE_REQUEST
.get_response()
.expect("Bootloader did not return kernel modules");
}
// TODO: make initramfs a lazy static somehow?

View File

@ -1,12 +1,12 @@
// Copyright (c) 2025 shibedrill // Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use crate::boot::FILE_REQUEST;
use crate::memory::alloc; use crate::memory::alloc;
use alloc::string::String; use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use limine::response::ExecutableFileResponse; use limine::response::ExecutableFileResponse;
use crate::boot::FILE_REQUEST;
lazy_static! { lazy_static! {
pub static ref EXECUTABLE_FILE_RESPONSE: &'static ExecutableFileResponse = FILE_REQUEST pub static ref EXECUTABLE_FILE_RESPONSE: &'static ExecutableFileResponse = FILE_REQUEST

View File

@ -1,3 +1,6 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::format; use crate::format;
use crate::log::LogLevel; use crate::log::LogLevel;
use crate::memory::alloc::string::String; use crate::memory::alloc::string::String;

View File

@ -1,3 +1,6 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
use fdt::*; use fdt::*;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use limine::response::{DeviceTreeBlobResponse, RsdpResponse}; use limine::response::{DeviceTreeBlobResponse, RsdpResponse};
@ -8,12 +11,24 @@ use crate::{format, log_info, log_trace, log_warning};
lazy_static! { lazy_static! {
pub static ref DTB: Option<&'static DeviceTreeBlobResponse> = match DTB_REQUEST.get_response() { pub static ref DTB: Option<&'static DeviceTreeBlobResponse> = match DTB_REQUEST.get_response() {
Some(resp) => { log_info!("Device: Got DTB pointer"); Some(resp) }, Some(resp) => {
None => { log_warning!("Device: Did not get DTB pointer"); None }, log_info!("Device: Got DTB pointer");
Some(resp)
}
None => {
log_warning!("Device: Did not get DTB pointer");
None
}
}; };
pub static ref RSDP: Option<&'static RsdpResponse> = match RSDP_REQUEST.get_response() { pub static ref RSDP: Option<&'static RsdpResponse> = match RSDP_REQUEST.get_response() {
Some(resp) => { log_info!("Device: Got RSDP pointer"); Some(resp) }, Some(resp) => {
None => { log_warning!("Device: Did not get RSDP pointer, ACPI unavailable"); None }, log_info!("Device: Got RSDP pointer");
Some(resp)
}
None => {
log_warning!("Device: Did not get RSDP pointer, ACPI unavailable");
None
}
}; };
} }

View File

@ -0,0 +1,4 @@
pub fn double_fault(info: &str) -> ! {
panic!("Double fault: {}", info);
}

View File

@ -3,27 +3,26 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(cfg_match)]
#![feature(allocator_api)] #![feature(allocator_api)]
#![feature(abi_x86_interrupt)]
mod arch; mod arch;
mod boot; mod boot;
mod constants; mod constants;
mod device; mod device;
mod interrupt;
#[macro_use] #[macro_use]
mod log; mod log;
mod memory; mod memory;
mod panic; mod panic;
mod params;
mod process; mod process;
mod resources; #[macro_use]
mod util;
#[cfg(target_arch = "x86_64")]
use arch::x86_64::gdt;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use arch::x86_64::serial::Serialport; use arch::x86_64::serial::Serialport;
use boot::*; use boot::{modules::*, params, *};
use constants::*; use constants::*;
use log::*; use log::*;
use memory::alloc::{format, string::*, vec}; use memory::alloc::{format, string::*, vec};
@ -97,16 +96,9 @@ unsafe extern "C" fn main() -> ! {
} }
} }
let module_response = MODULE_REQUEST if !MODULE_RESPONSE.modules().is_empty() {
.get_response()
.expect("Bootloader did not return kernel modules");
log_info!(
"Boot: {} kernel modules found",
module_response.modules().len()
);
if !module_response.modules().is_empty() {
let mut log_msg: String = String::from("Boot: Kernel modules list:\n"); let mut log_msg: String = String::from("Boot: Kernel modules list:\n");
for module in module_response.modules() { for module in MODULE_RESPONSE.modules() {
log_msg.push_str(&format!( log_msg.push_str(&format!(
"\t\t{}", "\t\t{}",
String::from_utf8_lossy(module.path().to_bytes()) String::from_utf8_lossy(module.path().to_bytes())
@ -126,7 +118,7 @@ unsafe extern "C" fn main() -> ! {
log_trace!("Boot: initramfs path requested: {irfs_path}"); log_trace!("Boot: initramfs path requested: {irfs_path}");
let _initramfs = { let _initramfs = {
let mut result: Option<&File> = None; let mut result: Option<&File> = None;
for file in module_response.modules() { for file in MODULE_RESPONSE.modules() {
if file.path().to_string_lossy() == irfs_path { if file.path().to_string_lossy() == irfs_path {
result = Some(file); result = Some(file);
log_info!("Boot: initramfs found"); log_info!("Boot: initramfs found");
@ -137,7 +129,9 @@ unsafe extern "C" fn main() -> ! {
.expect("initramfs not found in modules list"); .expect("initramfs not found in modules list");
// Panic if this is absent. It's needed to set up the GDT and paging // Panic if this is absent. It's needed to set up the GDT and paging
let mmap_response = MEMMAP_REQUEST.get_response().expect("Bootloader did not supply memory map"); let mmap_response = MEMMAP_REQUEST
.get_response()
.expect("Bootloader did not supply memory map");
log_info!("Boot: Memory map received"); log_info!("Boot: Memory map received");
if !mmap_response.entries().is_empty() { if !mmap_response.entries().is_empty() {
let mut log_msg: String = String::from("Boot: Memory map:"); let mut log_msg: String = String::from("Boot: Memory map:");
@ -199,8 +193,15 @@ unsafe extern "C" fn main() -> ! {
panic!("Memory map contains no entries"); panic!("Memory map contains no entries");
} }
#[cfg(target_arch = "x86_64")] //#[cfg(target_arch = "x86_64")]
gdt::setup_gdt(); //gdt::setup_gdt();
arch::x86_64::interrupts::IDT.load();
unsafe {
*(0xdeadbeef as *mut u8) = 42;
};
panic!("Bailing");
#[allow(unreachable_code)] #[allow(unreachable_code)]
loop { loop {

View File

@ -13,7 +13,7 @@ pub fn panic(info: &PanicInfo) -> ! {
log_critical!( log_critical!(
"Panic in {}: {}", "Panic in {}: {}",
info.location().unwrap(), info.location().unwrap(),
info.message().as_str().unwrap_or("missing panic message"), info.message()
); );
loop { loop {
unsafe { unsafe {

View File

@ -1,3 +1,6 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later
#![allow(unused_imports, dead_code)] #![allow(unused_imports, dead_code)]
use enumflags2::{BitFlags, bitflags, make_bitflags}; use enumflags2::{BitFlags, bitflags, make_bitflags};

View File

@ -1,2 +0,0 @@
// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later

9
src/kernel/util.rs Normal file
View File

@ -0,0 +1,9 @@
#[macro_export]
macro_rules! critical_section {
($b:block) => {
unsafe { $crate::arch::asm::interrupt_disable(); }
$b
unsafe { $crate::arch::asm::interrupt_enable(); }
};
}