Add a kernel crash function, add a timer using the timer interrupt and

set PIT interval to 1000hz, use a vector inside Framebuffer, remove
without_interrupts from the framebuffer and serial console, move to
usize on primitives, add date at boot and turn on multithreading, add a
boot animation and add a test_performance function with the new timer
This commit is contained in:
csd4ni3l
2026-03-28 21:03:13 +01:00
parent 4a3c1c9ced
commit aa5cd85b48
10 changed files with 301 additions and 128 deletions

View File

@@ -7,20 +7,23 @@ use core::fmt::Write;
use limine::BaseRevision;
use limine::request::{
FramebufferRequest, HhdmRequest, MemoryMapRequest, RequestsEndMarker, RequestsStartMarker,
DateAtBootRequest, FramebufferRequest, HhdmRequest, MemoryMapRequest, MpRequest,
RequestsEndMarker, RequestsStartMarker,
};
pub mod arch;
pub mod driver;
pub mod util;
use crate::arch::arch::{idle, init};
use crate::arch::arch::{infinite_idle, init, kernel_crash, sleep};
use crate::driver::graphics::base::rgb;
use crate::driver::graphics::framebuffer::{init_framebuffer, with_framebuffer};
use crate::driver::graphics::primitives::{
circle_filled, circle_outline, rectangle_filled, rectangle_outline, triangle_outline,
};
use crate::driver::serial::{ConsoleWriter, init_serial_console, with_serial_console};
use alloc::{boxed::Box, vec::Vec};
use crate::driver::timer::TIMER;
use crate::util::test_performance;
use alloc::{boxed::Box, string::ToString, vec::Vec};
/// Sets the base revision to the latest revision supported by the crate.
/// See specification for further info.
@@ -42,6 +45,14 @@ static HHDM_REQUEST: HhdmRequest = HhdmRequest::new();
#[unsafe(link_section = ".requests")]
static MEMORY_MAP_REQUEST: MemoryMapRequest = MemoryMapRequest::new();
#[used]
#[unsafe(link_section = ".requests")]
static DATE_AT_BOOT_REQUEST: DateAtBootRequest = DateAtBootRequest::new();
#[used]
#[unsafe(link_section = ".requests")]
static MP_REQUEST: MpRequest = MpRequest::new();
/// Define the stand and end markers for Limine requests.
#[used]
#[unsafe(link_section = ".requests_start_marker")]
@@ -88,6 +99,16 @@ unsafe extern "C" fn kmain() -> ! {
// removed by the linker.
assert!(BASE_REVISION.is_supported());
if let Some(hhdm_response) = HHDM_REQUEST.get_response() {
if let Some(memory_map_response) = MEMORY_MAP_REQUEST.get_response() {
let (mapper, frame_allocator) = init(hhdm_response, memory_map_response);
} else {
kernel_crash(); // Could not get required info from Limine's memory map.
}
} else {
kernel_crash(); // Could not get required info from the Limine's higher-half direct mapping.
}
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
if let Some(limine_framebuffer) = framebuffer_response.framebuffers().next() {
init_framebuffer(&limine_framebuffer);
@@ -96,26 +117,13 @@ unsafe extern "C" fn kmain() -> ! {
init_serial_console(0, 0);
if let Some(hhdm_response) = HHDM_REQUEST.get_response() {
if let Some(memory_map_response) = MEMORY_MAP_REQUEST.get_response() {
let (mapper, frame_allocator) = init(hhdm_response, memory_map_response);
} else {
panic!("Could not get required info from Limine's memory map. ")
}
if let Some(date_at_boot_response) = DATE_AT_BOOT_REQUEST.get_response() {
TIMER.set_date_at_boot(date_at_boot_response.timestamp().as_secs());
} else {
panic!("Could not get required info from the Limine's higher-half direct mapping. ")
println!("Could not get date at boot. Will default to 0.")
}
with_framebuffer(|mut fb| {
let (width, height) = (fb.width.clone(), fb.height.clone());
init_serial_console(0, 0);
rectangle_filled(&mut fb, 0, 0, width, height, rgb(253, 129, 0), true);
rectangle_filled(&mut fb, 700, 400, 200, 200, rgb(0, 0, 0), true);
rectangle_outline(&mut fb, 400, 400, 100, 100, rgb(0, 0, 0));
circle_filled(&mut fb, 200, 200, 100.0, rgb(0, 0, 0));
circle_outline(&mut fb, 400, 200, 100.0, rgb(0, 0, 0));
triangle_outline(&mut fb, 100, 400, 200, 400, 150, 600, rgb(0, 0, 0));
});
boot_animation();
let x = Box::new(41);
let mut test_vec: Vec<u16> = Vec::new();
@@ -124,14 +132,82 @@ unsafe extern "C" fn kmain() -> ! {
test_vec.push(9);
println!("After: {:?}", test_vec);
idle();
sleep(500);
loop {
with_serial_console(|serial_console| serial_console.clear(0, 0));
with_framebuffer(|mut fb| {
fb.clear(rgb(253, 129, 0));
// rectangle_filled(&mut fb, 700, 400, 200, 200, rgb(0, 0, 0));
// rectangle_outline(&mut fb, 400, 400, 100, 100, rgb(0, 0, 0));
// circle_filled(&mut fb, 200, 200, 100.0, rgb(0, 0, 0));
circle_outline(&mut fb, 400, 200, 100.0, rgb(0, 0, 0));
triangle_outline(&mut fb, 100, 400, 200, 400, 150, 600, rgb(0, 0, 0));
});
let (hours, minutes, seconds) =
unix_to_hms(TIMER.get_date_at_boot() + (TIMER.now().elapsed()) / 1000);
print!("{:?}:{:?}:{:?}", hours, minutes, seconds);
sleep(16);
}
}
fn boot_animation() {
let mut i = 1;
while i < 10 {
let mut width = 0;
let mut height = 0;
with_framebuffer(|fb| {
fb.clear(rgb(253, 129, 0));
width = fb.width;
height = fb.height;
});
let text_width = ("XunilOS Loading".len() + ".".repeat(i).len()) * 4 * 2;
with_serial_console(|serial_console| {
serial_console.clear(width / 2 - text_width / 2, height / 2)
});
println!(
"{}",
"XunilOS Loading".to_string() + &".".repeat(i).as_str()
);
i += 1;
sleep(200);
}
with_serial_console(|serial_console| {
serial_console.clear(0, 0);
});
with_framebuffer(|fb| {
fb.clear(rgb(253, 129, 0));
});
}
fn unix_to_hms(timestamp: u64) -> (u64, u64, u64) {
let seconds = timestamp % 86400;
let h = seconds / 3600;
let m = (seconds % 3600) / 60;
let s = seconds % 60;
(h, m, s)
}
#[panic_handler]
fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
with_framebuffer(|mut fb| {
let (width, height) = (fb.width.clone(), fb.height.clone());
rectangle_filled(&mut fb, 0, 0, width, height, rgb(180, 0, 0), true);
rectangle_filled(&mut fb, 0, 0, width, height, rgb(180, 0, 0));
with_serial_console(|console| {
console.clear(5, 5);
@@ -148,5 +224,5 @@ fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
});
});
idle();
infinite_idle();
}