feat: Integrate LVGL v8.3 desktop GUI, PS/2 mouse driver, live system monitor, and make gui target

This commit is contained in:
RarDog
2026-09-02 20:42:18 +03:00
parent c98c8de9d4
commit 78d38f7620
435 changed files with 286235 additions and 24 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ pub unsafe fn init() {
/// Enable SSE/SSE2/XSAVE for user-space SIMD operations.
/// Required to prevent #GP when user programs use XMM registers or compiler-generated SSE code.
unsafe fn enable_sse() {
pub unsafe fn enable_sse() {
// Clear CR0.EM (bit 2) - disable x87 FPU emulation
// Set CR0.MP (bit 1) - monitor coprocessor (allow WAIT)
let mut cr0: u64;
+1
View File
@@ -13,6 +13,7 @@ pub extern "C" fn ap_startup(info: *const LimineSmpInfo) -> ! {
let lapic_id = (*info).lapic_id;
// Initialize CPU Architecture for this AP with dedicated TSS selector
super::enable_sse();
super::gdt::init_ap(cpu_id as usize);
super::idt::init();
super::syscall::init();
+22
View File
@@ -488,8 +488,30 @@ pub extern "C" fn kernel_syscall_dispatcher(regs: &mut SyscallRegisters) {
}
regs.rax = (-1i64) as u64;
}
// SYS_MOUSE_GET = 21 (Read mouse coordinates and buttons)
21 => {
let out_ptr = regs.rdi as *mut MouseInfoPayload;
if !out_ptr.is_null() {
let (mx, my, mb) = crate::drivers::mouse::get_mouse_info();
unsafe {
(*out_ptr).x = mx;
(*out_ptr).y = my;
(*out_ptr).buttons = mb;
}
regs.rax = 0;
return;
}
regs.rax = (-1i64) as u64;
}
_ => {
regs.rax = (-1i64) as u64; // SYS_ERR_INVALID_ARG
}
}
}
#[repr(C)]
pub struct MouseInfoPayload {
pub x: i32,
pub y: i32,
pub buttons: u32,
}
+13 -7
View File
@@ -72,14 +72,20 @@ pub fn init() {
#[no_mangle]
pub extern "C" fn keyboard_interrupt_handler() {
unsafe {
let scancode = inb(PS2_DATA_PORT);
let status = inb(0x64);
let data = inb(PS2_DATA_PORT);
// Process only key-down events (bit 7 clear)
if (scancode as usize) < SCANCODE_MAP.len() {
let ascii = SCANCODE_MAP[scancode as usize];
if ascii != 0 {
let buf = &mut *core::ptr::addr_of_mut!(KEY_BUFFER);
buf.push(ascii);
if (status & 0x20) != 0 {
let mouse = &mut *core::ptr::addr_of_mut!(crate::drivers::mouse::MOUSE_STATE);
mouse.handle_byte(data);
} else {
// Process only key-down events (bit 7 clear)
if (data as usize) < SCANCODE_MAP.len() {
let ascii = SCANCODE_MAP[data as usize];
if ascii != 0 {
let buf = &mut *core::ptr::addr_of_mut!(KEY_BUFFER);
buf.push(ascii);
}
}
}
+1
View File
@@ -3,3 +3,4 @@ pub mod timer;
pub mod keyboard;
pub mod rtc;
pub mod dmesg;
pub mod mouse;
+152
View File
@@ -0,0 +1,152 @@
//! PS/2 Mouse Driver
//! Handles 8042 Auxiliary Device communication, 3-byte packet assembly, and coordinate tracking.
use crate::kprintln;
const PS2_DATA_PORT: u16 = 0x60;
const PS2_STATUS_PORT: u16 = 0x64;
const PS2_COMMAND_PORT: u16 = 0x64;
#[inline]
unsafe fn inb(port: u16) -> u8 {
let mut val: u8;
core::arch::asm!("in al, dx", in("dx") port, out("al") val, options(nomem, nostack, preserves_flags));
val
}
#[inline]
unsafe fn outb(port: u16, val: u8) {
core::arch::asm!("out dx, al", in("dx") port, in("al") val, options(nomem, nostack, preserves_flags));
}
unsafe fn wait_ps2_write() {
let mut timeout = 100000;
while (inb(PS2_STATUS_PORT) & 0x02) != 0 && timeout > 0 {
timeout -= 1;
core::hint::spin_loop();
}
}
unsafe fn wait_ps2_read() {
let mut timeout = 100000;
while (inb(PS2_STATUS_PORT) & 0x01) == 0 && timeout > 0 {
timeout -= 1;
core::hint::spin_loop();
}
}
pub struct MouseState {
pub x: i32,
pub y: i32,
pub buttons: u32, // bit 0 = Left, bit 1 = Right, bit 2 = Middle
packet: [u8; 3],
packet_index: usize,
max_x: i32,
max_y: i32,
}
pub static mut MOUSE_STATE: MouseState = MouseState {
x: 640,
y: 400,
buttons: 0,
packet: [0; 3],
packet_index: 0,
max_x: 1280,
max_y: 800,
};
impl MouseState {
pub fn handle_byte(&mut self, b: u8) {
if self.packet_index == 0 {
// First byte must have bit 3 set (sync bit)
if (b & 0x08) == 0 {
return; // Out of sync, discard
}
}
self.packet[self.packet_index] = b;
self.packet_index += 1;
if self.packet_index == 3 {
self.packet_index = 0;
let flags = self.packet[0];
let raw_dx = self.packet[1];
let raw_dy = self.packet[2];
// Buttons: bit 0 = Left, bit 1 = Right, bit 2 = Middle
self.buttons = (flags & 0x07) as u32;
// X offset with 9-bit sign extension
let mut dx = raw_dx as i32;
if (flags & 0x10) != 0 {
dx |= !0xFF; // sign extend negative
}
// Y offset with 9-bit sign extension (PS/2 Y points upwards, screen points downwards)
let mut dy = raw_dy as i32;
if (flags & 0x20) != 0 {
dy |= !0xFF; // sign extend negative
}
self.x += dx;
self.y -= dy; // Invert Y for screen coordinates
// Clamp to screen boundaries
if self.x < 0 { self.x = 0; }
if self.x >= self.max_x { self.x = self.max_x - 1; }
if self.y < 0 { self.y = 0; }
if self.y >= self.max_y { self.y = self.max_y - 1; }
}
}
}
pub fn init(screen_w: i32, screen_h: i32) {
unsafe {
MOUSE_STATE.max_x = screen_w;
MOUSE_STATE.max_y = screen_h;
MOUSE_STATE.x = screen_w / 2;
MOUSE_STATE.y = screen_h / 2;
// 1. Enable auxiliary device (Mouse) in 8042 controller
wait_ps2_write();
outb(PS2_COMMAND_PORT, 0xA8);
// 2. Enable auxiliary device interrupts in 8042 controller configuration byte
wait_ps2_write();
outb(PS2_COMMAND_PORT, 0x20); // Read Controller Command Byte
wait_ps2_read();
let mut status = inb(PS2_DATA_PORT);
status |= 0x02; // Enable IRQ 12 (mouse interrupt)
status &= !0x20; // Clear mouse clock disable
wait_ps2_write();
outb(PS2_COMMAND_PORT, 0x60); // Write Controller Command Byte
wait_ps2_write();
outb(PS2_DATA_PORT, status);
// 3. Set Defaults (command 0xF6) to mouse
wait_ps2_write();
outb(PS2_COMMAND_PORT, 0xD4);
wait_ps2_write();
outb(PS2_DATA_PORT, 0xF6);
wait_ps2_read();
let _ = inb(PS2_DATA_PORT); // ACK (0xFA)
// 4. Enable Data Reporting (command 0xF4) to mouse
wait_ps2_write();
outb(PS2_COMMAND_PORT, 0xD4);
wait_ps2_write();
outb(PS2_DATA_PORT, 0xF4);
wait_ps2_read();
let _ = inb(PS2_DATA_PORT); // ACK (0xFA)
kprintln!("[MOUSE] PS/2 Mouse Driver Initialized (Screen: {}x{}).", screen_w, screen_h);
}
}
pub fn get_mouse_info() -> (i32, i32, u32) {
unsafe {
(MOUSE_STATE.x, MOUSE_STATE.y, MOUSE_STATE.buttons)
}
}
+3
View File
@@ -74,6 +74,7 @@ pub extern "C" fn _start() -> ! {
unsafe {
drivers::timer::init(100);
drivers::keyboard::init();
drivers::mouse::init(1280, 800);
}
// 7. Initialize IPC & Capability System
@@ -103,6 +104,8 @@ pub extern "C" fn _start() -> ! {
0 => "init_server",
1 => "uart_driver",
2 => "sh",
3 => "procmgr",
4 => "gui_server",
_ => "user_server",
};