mirror of
https://github.com/XunilGroup/XunilOS.git
synced 2026-04-25 11:49:03 +02:00
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:
@@ -1,3 +1,4 @@
|
||||
use crate::driver::timer::TIMER;
|
||||
use core::arch::asm;
|
||||
use limine::response::{HhdmResponse, MemoryMapResponse};
|
||||
|
||||
@@ -14,8 +15,7 @@ pub fn init<'a>(
|
||||
return init_x86_64(hhdm_response, memory_map_response);
|
||||
}
|
||||
|
||||
pub fn idle() -> ! {
|
||||
loop {
|
||||
pub fn idle() {
|
||||
unsafe {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
asm!("hlt");
|
||||
@@ -24,5 +24,37 @@ pub fn idle() -> ! {
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
asm!("idle 0");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sleep(ticks: u64) {
|
||||
let start = TIMER.now();
|
||||
while (TIMER.now() - start).elapsed() <= ticks {
|
||||
idle();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn infinite_idle() -> ! {
|
||||
loop {
|
||||
idle()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn kernel_crash() -> ! {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
unsafe {
|
||||
core::arch::asm!("ud2")
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
unsafe {
|
||||
core::arch::asm!("udf #0")
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
unsafe {
|
||||
core::arch::asm!("unimp")
|
||||
};
|
||||
|
||||
loop {} // satisfies -> ! on unknown archs
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
use crate::arch::x86_64::gdt::load_gdt_x86_64;
|
||||
use crate::arch::x86_64::interrupts::{PICS, init_idt_x86_64};
|
||||
use crate::arch::x86_64::interrupts::{InterruptIndex, PICS, init_idt_x86_64};
|
||||
use limine::response::{HhdmResponse, MemoryMapResponse};
|
||||
use x86_64::instructions::interrupts;
|
||||
use x86_64::instructions::interrupts::without_interrupts;
|
||||
use x86_64::instructions::{interrupts, port::Port};
|
||||
|
||||
const TIMER_PRECISION_HZ: u32 = 1000;
|
||||
const PIT_DIVISOR: u16 = (1_193_182_u32 / TIMER_PRECISION_HZ) as u16;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86_64::{
|
||||
@@ -22,6 +26,19 @@ pub fn memory_management_init<'a>(
|
||||
(mapper, frame_allocator)
|
||||
}
|
||||
|
||||
pub fn set_pit_interval() {
|
||||
without_interrupts(|| {
|
||||
let mut command_port: Port<u8> = Port::new(0x43);
|
||||
let mut data_port: Port<u8> = Port::new(0x40);
|
||||
|
||||
unsafe {
|
||||
command_port.write(0b00_11_011_0);
|
||||
data_port.write((PIT_DIVISOR & 0xFF) as u8); // low byte
|
||||
data_port.write(((PIT_DIVISOR >> 8) & 0xFF) as u8); // high byte
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn init_x86_64<'a>(
|
||||
hhdm_response: &HhdmResponse,
|
||||
memory_map_response: &'a MemoryMapResponse,
|
||||
@@ -35,6 +52,8 @@ pub fn init_x86_64<'a>(
|
||||
pics.write_masks(0xFC, 0xFF);
|
||||
}
|
||||
|
||||
set_pit_interval();
|
||||
|
||||
interrupts::enable();
|
||||
|
||||
let (mut mapper, mut frame_allocator) =
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::driver::timer::TIMER;
|
||||
use crate::{arch::x86_64::gdt, driver::keyboard::keyboard_interrupt_handler, println};
|
||||
use lazy_static::lazy_static;
|
||||
use pic8259::ChainedPics;
|
||||
@@ -18,7 +19,7 @@ pub static PICS: Mutex<ChainedPics> =
|
||||
#[repr(u8)]
|
||||
pub enum InterruptIndex {
|
||||
Timer = PIC_1_OFFSET,
|
||||
Keyboard, // putting it below increments it by 1, so its offset + 1
|
||||
Keyboard = PIC_1_OFFSET + 1,
|
||||
}
|
||||
|
||||
impl InterruptIndex {
|
||||
@@ -83,6 +84,8 @@ pub extern "x86-interrupt" fn gpf_handler(stack_frame: InterruptStackFrame, erro
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||
TIMER.interrupt();
|
||||
|
||||
unsafe {
|
||||
PICS.lock()
|
||||
.notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||
|
||||
@@ -23,7 +23,6 @@ pub fn render_char(
|
||||
font_size,
|
||||
font_size,
|
||||
color,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use limine::framebuffer::Framebuffer as LimineFramebuffer;
|
||||
use spin::Mutex;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86_64::interrupts::without_interrupts;
|
||||
|
||||
const MAX_BACKBUFFER_PIXELS: usize = 1920 * 1080;
|
||||
static mut BACK_BUFFER: [u32; MAX_BACKBUFFER_PIXELS] = [0; MAX_BACKBUFFER_PIXELS];
|
||||
|
||||
pub struct Framebuffer {
|
||||
addr: *mut u32,
|
||||
back_buffer: *mut u32,
|
||||
back_buffer: Vec<u32>,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pitch: usize,
|
||||
@@ -21,12 +20,11 @@ impl Framebuffer {
|
||||
let width = limine_fb.width() as usize;
|
||||
let height = limine_fb.height() as usize;
|
||||
let pitch = limine_fb.pitch() as usize / 4;
|
||||
let needed = pitch.saturating_mul(height);
|
||||
let back_buffer_len = core::cmp::min(needed, MAX_BACKBUFFER_PIXELS);
|
||||
let back_buffer_len = width * height;
|
||||
|
||||
Framebuffer {
|
||||
addr: limine_fb.addr().cast::<u32>(),
|
||||
back_buffer: core::ptr::addr_of_mut!(BACK_BUFFER).cast::<u32>(),
|
||||
back_buffer: vec![0u32; width * height],
|
||||
width,
|
||||
height,
|
||||
pitch,
|
||||
@@ -44,16 +42,22 @@ impl Framebuffer {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
*self.back_buffer.add(idx) = color;
|
||||
}
|
||||
self.back_buffer[idx] = color;
|
||||
}
|
||||
|
||||
pub fn swap(&mut self) {
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(self.back_buffer, self.addr, self.back_buffer_len);
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.back_buffer.as_ptr(),
|
||||
self.addr,
|
||||
self.back_buffer_len,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self, color: u32) {
|
||||
self.back_buffer.fill(color);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for Framebuffer {}
|
||||
@@ -65,10 +69,8 @@ pub fn init_framebuffer(raw: &LimineFramebuffer) {
|
||||
}
|
||||
|
||||
pub fn with_framebuffer<F: FnOnce(&mut Framebuffer)>(f: F) {
|
||||
without_interrupts(|| {
|
||||
let mut guard = FRAMEBUFFER.lock();
|
||||
if let Some(fb) = guard.as_mut() {
|
||||
f(fb);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,43 +1,45 @@
|
||||
use crate::driver::graphics::framebuffer::Framebuffer;
|
||||
use crate::driver::graphics::{base::rgb, font_render::render_text, framebuffer::Framebuffer};
|
||||
use alloc::{format, string::ToString};
|
||||
use core::f32::consts::PI;
|
||||
use micromath::F32Ext;
|
||||
|
||||
pub fn line(framebuffer: &mut Framebuffer, mut x0: i64, mut y0: i64, x1: i64, y1: i64, color: u32) {
|
||||
let mut dx = x1 - x0;
|
||||
let mut dy = y1 - y0;
|
||||
pub fn line(framebuffer: &mut Framebuffer, x0: usize, y0: usize, x1: usize, y1: usize, color: u32) {
|
||||
let mut x0 = x0 as isize;
|
||||
let mut y0 = y0 as isize;
|
||||
let x1 = x1 as isize;
|
||||
let y1 = y1 as isize;
|
||||
|
||||
let mut dx: isize = x1 - x0;
|
||||
let mut dy: isize = y1 - y0;
|
||||
|
||||
if dx < 0 {
|
||||
dx = -dx;
|
||||
}
|
||||
|
||||
if dy < 0 {
|
||||
dy = -dy;
|
||||
}
|
||||
|
||||
let step_x = if x0 < x1 { 1 } else { -1 };
|
||||
let step_y = if y0 < y1 { 1 } else { -1 };
|
||||
let step_x: isize = if x0 < x1 { 1 } else { -1 };
|
||||
let step_y: isize = if y0 < y1 { 1 } else { -1 };
|
||||
|
||||
let mut error = dx - dy;
|
||||
let mut e2: i64;
|
||||
let mut error: isize = dx - dy;
|
||||
|
||||
loop {
|
||||
framebuffer.put_pixel(x0 as usize, y0 as usize, color);
|
||||
|
||||
if x0 == x1 && y0 == y1 {
|
||||
break;
|
||||
}
|
||||
|
||||
e2 = 2 * error;
|
||||
|
||||
let e2: isize = 2 * error;
|
||||
if e2 > -dy {
|
||||
error -= dy;
|
||||
x0 += step_x;
|
||||
}
|
||||
|
||||
if e2 < dx {
|
||||
error += dx;
|
||||
y0 += step_y;
|
||||
}
|
||||
|
||||
if x0 == x1 && y0 == y1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,31 +53,9 @@ pub fn triangle_outline(
|
||||
y3: usize,
|
||||
color: u32,
|
||||
) {
|
||||
line(
|
||||
framebuffer,
|
||||
x1 as i64,
|
||||
y1 as i64,
|
||||
x2 as i64,
|
||||
y2 as i64,
|
||||
color,
|
||||
);
|
||||
line(
|
||||
framebuffer,
|
||||
x1 as i64,
|
||||
y1 as i64,
|
||||
x3 as i64,
|
||||
y3 as i64,
|
||||
color,
|
||||
);
|
||||
line(
|
||||
framebuffer,
|
||||
x2 as i64,
|
||||
y2 as i64,
|
||||
x3 as i64,
|
||||
y3 as i64,
|
||||
color,
|
||||
);
|
||||
framebuffer.swap();
|
||||
line(framebuffer, x1, y1, x2, y2, color);
|
||||
line(framebuffer, x1, y1, x3, y3, color);
|
||||
line(framebuffer, x2, y2, x3, y3, color);
|
||||
}
|
||||
|
||||
pub fn circle_outline(framebuffer: &mut Framebuffer, x: usize, y: usize, radius: f32, color: u32) {
|
||||
@@ -92,42 +72,37 @@ pub fn circle_outline(framebuffer: &mut Framebuffer, x: usize, y: usize, radius:
|
||||
break;
|
||||
}
|
||||
}
|
||||
framebuffer.swap();
|
||||
}
|
||||
|
||||
pub fn circle_filled(framebuffer: &mut Framebuffer, x0: usize, y0: usize, radius: f32, color: u32) {
|
||||
let mut x = radius as i64;
|
||||
let mut y: i64 = 0;
|
||||
let mut x_change: i64 = 1 - (radius as i64 * 2);
|
||||
let mut y_change: i64 = 0;
|
||||
let mut radius_error: i64 = 0;
|
||||
let mut x = radius as isize;
|
||||
let mut y: isize = 0;
|
||||
let mut x_change: isize = 1 - (radius as isize * 2);
|
||||
let mut y_change: isize = 0;
|
||||
let mut radius_error: isize = 0;
|
||||
|
||||
while x >= y {
|
||||
let mut i = x0 as i64 - x;
|
||||
while i <= x0 as i64 + x {
|
||||
framebuffer.put_pixel(i as usize, (y0 as i64 + y) as usize, color);
|
||||
framebuffer.put_pixel(i as usize, (y0 as i64 - y) as usize, color);
|
||||
let mut i = x0 as isize - x;
|
||||
while i <= x0 as isize + x {
|
||||
framebuffer.put_pixel(i as usize, (y0 as isize + y) as usize, color);
|
||||
framebuffer.put_pixel(i as usize, (y0 as isize - y) as usize, color);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
let mut i = x0 as i64 - y;
|
||||
while i <= x0 as i64 + y {
|
||||
framebuffer.put_pixel(i as usize, (y0 as i64 + x) as usize, color);
|
||||
framebuffer.put_pixel(i as usize, (y0 as i64 - x) as usize, color);
|
||||
let mut i = x0 as isize - y;
|
||||
while i <= x0 as isize + y {
|
||||
framebuffer.put_pixel(i as usize, (y0 as isize + x) as usize, color);
|
||||
framebuffer.put_pixel(i as usize, (y0 as isize - x) as usize, color);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
y += 1;
|
||||
radius_error += y_change;
|
||||
y_change += 2;
|
||||
|
||||
if (radius_error * 2) + x_change > 0 {
|
||||
x -= 1;
|
||||
radius_error += x_change;
|
||||
x_change += 2;
|
||||
}
|
||||
}
|
||||
framebuffer.swap();
|
||||
}
|
||||
|
||||
pub fn rectangle_filled(
|
||||
@@ -137,29 +112,24 @@ pub fn rectangle_filled(
|
||||
width: usize,
|
||||
height: usize,
|
||||
color: u32,
|
||||
swap: bool,
|
||||
) {
|
||||
for fb_x in x..x + width {
|
||||
for fb_y in y..y + height {
|
||||
framebuffer.put_pixel(fb_x, fb_y, color);
|
||||
}
|
||||
}
|
||||
if swap {
|
||||
framebuffer.swap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rectangle_outline(
|
||||
framebuffer: &mut Framebuffer,
|
||||
x: i64,
|
||||
y: i64,
|
||||
width: i64,
|
||||
height: i64,
|
||||
x: usize,
|
||||
y: usize,
|
||||
width: usize,
|
||||
height: usize,
|
||||
color: u32,
|
||||
) {
|
||||
line(framebuffer, x, y, x + width, y, color); // bottomleft -> bottomright
|
||||
line(framebuffer, x, y + height, x + width, y + height, color); // topleft -> topright
|
||||
line(framebuffer, x, y, x, y + height, color); // bottomleft -> topleft
|
||||
line(framebuffer, x + width, y, x + width, y + height, color); // bottomright -> topright
|
||||
framebuffer.swap();
|
||||
}
|
||||
|
||||
@@ -73,10 +73,8 @@ pub fn init_serial_console(start_x: usize, start_y: usize) {
|
||||
}
|
||||
|
||||
pub fn with_serial_console<F: FnOnce(&mut SerialConsole)>(f: F) {
|
||||
without_interrupts(|| {
|
||||
let mut guard = SERIAL_CONSOLE.lock();
|
||||
if let Some(fb) = guard.as_mut() {
|
||||
f(fb);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1 +1,67 @@
|
||||
use core::{
|
||||
ops::{Add, Sub},
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
};
|
||||
|
||||
pub static TIMER: Timer = Timer::new();
|
||||
|
||||
pub struct Timer {
|
||||
pub interrupt_count: AtomicU64,
|
||||
pub date_at_boot: AtomicU64,
|
||||
}
|
||||
|
||||
impl Timer {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
interrupt_count: AtomicU64::new(0),
|
||||
date_at_boot: AtomicU64::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_date_at_boot(&self, date_at_boot: u64) {
|
||||
self.date_at_boot.store(date_at_boot, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
pub fn get_date_at_boot(&self) -> u64 {
|
||||
self.date_at_boot.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn interrupt(&self) {
|
||||
self.interrupt_count.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
pub fn now(&self) -> Time {
|
||||
Time {
|
||||
interrupt_count: self.interrupt_count.load(Ordering::Relaxed),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||
pub struct Time {
|
||||
pub interrupt_count: u64,
|
||||
}
|
||||
|
||||
impl Time {
|
||||
pub fn new(interrupt_count: u64) -> Self {
|
||||
Self { interrupt_count }
|
||||
}
|
||||
|
||||
pub fn elapsed(&self) -> u64 {
|
||||
self.interrupt_count
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Time {
|
||||
type Output = Time;
|
||||
fn add(self, other: Time) -> Time {
|
||||
Time::new(self.interrupt_count + other.interrupt_count)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Time {
|
||||
type Output = Time;
|
||||
fn sub(self, other: Time) -> Time {
|
||||
Time::new(self.interrupt_count - other.interrupt_count)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
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 Limine's memory map. ")
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::{driver::timer::TIMER, println};
|
||||
use spin::{Mutex, MutexGuard};
|
||||
|
||||
pub struct LinkedNode {
|
||||
@@ -34,3 +35,10 @@ impl<A> Locked<A> {
|
||||
self.inner.lock()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_performance<F: FnOnce()>(function: F) {
|
||||
let start = TIMER.now();
|
||||
let ret = function();
|
||||
println!("took {} ms", (TIMER.now() - start).elapsed());
|
||||
ret
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user