mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
FEAT: Verbose boot
This commit is contained in:
parent
a27b2c6423
commit
e4603792b6
16 changed files with 296 additions and 87 deletions
95
src/core/kconsole.c
Normal file
95
src/core/kconsole.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
#include "kconsole.h"
|
||||
#include "graphics.h"
|
||||
#include "sys/spinlock.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static spinlock_t console_lock = SPINLOCK_INIT;
|
||||
static int cursor_x = 0;
|
||||
static int cursor_y = 0;
|
||||
static bool kconsole_active = false;
|
||||
static uint32_t text_color = 0xFFFFFFFF; // White
|
||||
|
||||
#define CHAR_WIDTH 8
|
||||
#define CHAR_HEIGHT 10
|
||||
|
||||
void kconsole_init(void) {
|
||||
cursor_x = 10;
|
||||
cursor_y = 10;
|
||||
kconsole_active = true;
|
||||
|
||||
// Initial clear screen during boot
|
||||
graphics_clear_back_buffer(0x00000000);
|
||||
graphics_mark_screen_dirty();
|
||||
graphics_flip_buffer();
|
||||
}
|
||||
|
||||
void kconsole_set_active(bool active) {
|
||||
kconsole_active = active;
|
||||
}
|
||||
|
||||
void kconsole_set_color(uint32_t color) {
|
||||
uint64_t flags = spinlock_acquire_irqsave(&console_lock);
|
||||
text_color = color;
|
||||
spinlock_release_irqrestore(&console_lock, flags);
|
||||
}
|
||||
|
||||
static void kconsole_scroll(void) {
|
||||
if (cursor_y + CHAR_HEIGHT >= get_screen_height() - 10) {
|
||||
graphics_scroll_back_buffer(CHAR_HEIGHT);
|
||||
cursor_y -= CHAR_HEIGHT;
|
||||
graphics_mark_screen_dirty();
|
||||
graphics_flip_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
static void kconsole_putc_nolock(char c) {
|
||||
if (!kconsole_active) return;
|
||||
|
||||
if (c == '\n') {
|
||||
cursor_x = 10;
|
||||
cursor_y += CHAR_HEIGHT;
|
||||
kconsole_scroll();
|
||||
graphics_flip_buffer();
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == '\r') {
|
||||
cursor_x = 10;
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == '\t') {
|
||||
cursor_x += CHAR_WIDTH * 4;
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw character
|
||||
draw_char_bitmap(cursor_x, cursor_y, c, text_color);
|
||||
graphics_mark_screen_dirty();
|
||||
|
||||
cursor_x += CHAR_WIDTH;
|
||||
if (cursor_x + CHAR_WIDTH >= get_screen_width() - 10) {
|
||||
cursor_x = 10;
|
||||
cursor_y += CHAR_HEIGHT;
|
||||
kconsole_scroll();
|
||||
}
|
||||
}
|
||||
|
||||
void kconsole_putc(char c) {
|
||||
uint64_t flags = spinlock_acquire_irqsave(&console_lock);
|
||||
kconsole_putc_nolock(c);
|
||||
spinlock_release_irqrestore(&console_lock, flags);
|
||||
}
|
||||
|
||||
void kconsole_write(const char *s) {
|
||||
if (!s) return;
|
||||
|
||||
uint64_t flags = spinlock_acquire_irqsave(&console_lock);
|
||||
while (*s) {
|
||||
kconsole_putc_nolock(*s++);
|
||||
}
|
||||
|
||||
// Flip buffer after a write batch during boot
|
||||
graphics_flip_buffer();
|
||||
spinlock_release_irqrestore(&console_lock, flags);
|
||||
}
|
||||
13
src/core/kconsole.h
Normal file
13
src/core/kconsole.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef KCONSOLE_H
|
||||
#define KCONSOLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void kconsole_init(void);
|
||||
void kconsole_set_color(uint32_t color);
|
||||
void kconsole_putc(char c);
|
||||
void kconsole_write(const char *s);
|
||||
void kconsole_set_active(bool active);
|
||||
|
||||
#endif // KCONSOLE_H
|
||||
124
src/core/main.c
124
src/core/main.c
|
|
@ -18,6 +18,7 @@
|
|||
#include "fat32.h"
|
||||
#include "tar.h"
|
||||
#include "vfs.h"
|
||||
#include "core/kconsole.h"
|
||||
#include "memory_manager.h"
|
||||
#include "platform.h"
|
||||
#include "wallpaper.h"
|
||||
|
|
@ -91,26 +92,70 @@ static void init_serial() {
|
|||
outb(0x3F8 + 4, 0x0B);
|
||||
}
|
||||
|
||||
static spinlock_t serial_lock = SPINLOCK_INIT;
|
||||
|
||||
void serial_write(const char *str) {
|
||||
while (*str) {
|
||||
uint64_t flags = spinlock_acquire_irqsave(&serial_lock);
|
||||
const char *p = str;
|
||||
while (*p) {
|
||||
char c = *p++;
|
||||
while ((inb(0x3F8 + 5) & 0x20) == 0);
|
||||
outb(0x3F8, *str++);
|
||||
outb(0x3F8, c);
|
||||
}
|
||||
kconsole_write(str);
|
||||
spinlock_release_irqrestore(&serial_lock, flags);
|
||||
}
|
||||
|
||||
static void serial_write_num_locked(uint32_t n) {
|
||||
if (n >= 10) serial_write_num_locked(n / 10);
|
||||
char c = '0' + (n % 10);
|
||||
while ((inb(0x3F8 + 5) & 0x20) == 0);
|
||||
outb(0x3F8, c);
|
||||
kconsole_putc(c);
|
||||
}
|
||||
|
||||
void serial_write_num(uint32_t n) {
|
||||
if (n >= 10) serial_write_num(n / 10);
|
||||
uint64_t flags = spinlock_acquire_irqsave(&serial_lock);
|
||||
serial_write_num_locked(n);
|
||||
spinlock_release_irqrestore(&serial_lock, flags);
|
||||
}
|
||||
|
||||
static void serial_write_hex_locked(uint64_t n) {
|
||||
char *hex = "0123456789ABCDEF";
|
||||
if (n >= 16) serial_write_hex_locked(n / 16);
|
||||
char c = hex[n % 16];
|
||||
while ((inb(0x3F8 + 5) & 0x20) == 0);
|
||||
outb(0x3F8, '0' + (n % 10));
|
||||
outb(0x3F8, c);
|
||||
kconsole_putc(c);
|
||||
}
|
||||
|
||||
void serial_write_hex(uint64_t n) {
|
||||
char *hex = "0123456789ABCDEF";
|
||||
if (n >= 16) serial_write_hex(n / 16);
|
||||
while ((inb(0x3F8 + 5) & 0x20) == 0);
|
||||
outb(0x3F8, hex[n % 16]);
|
||||
uint64_t flags = spinlock_acquire_irqsave(&serial_lock);
|
||||
serial_write_hex_locked(n);
|
||||
spinlock_release_irqrestore(&serial_lock, flags);
|
||||
}
|
||||
|
||||
void log_ok(const char *msg) {
|
||||
serial_write("[ ");
|
||||
kconsole_set_color(0xFF00FF00);
|
||||
serial_write("OK");
|
||||
kconsole_set_color(0xFFFFFFFF);
|
||||
serial_write(" ] ");
|
||||
serial_write(msg);
|
||||
serial_write("\n");
|
||||
}
|
||||
|
||||
void log_fail(const char *msg) {
|
||||
serial_write("[ ");
|
||||
kconsole_set_color(0xFFFF0000);
|
||||
serial_write("FAIL");
|
||||
kconsole_set_color(0xFFFFFFFF);
|
||||
serial_write(" ] ");
|
||||
serial_write(msg);
|
||||
serial_write("\n");
|
||||
}
|
||||
|
||||
|
||||
// Kernel Entry Point
|
||||
|
||||
static void fat32_mkdir_recursive(const char *path) {
|
||||
|
|
@ -141,64 +186,65 @@ static void fat32_mkdir_recursive(const char *path) {
|
|||
void kmain(void) {
|
||||
init_serial();
|
||||
vfs_init();
|
||||
serial_write("\n[DEBUG] Entering kmain...\n");
|
||||
serial_write("\n");
|
||||
|
||||
platform_init();
|
||||
serial_write("[DEBUG] platform_init OK\n");
|
||||
log_ok("Platform initialized");
|
||||
|
||||
extern uint64_t hhdm_offset;
|
||||
extern uint64_t kernel_phys_base;
|
||||
extern uint64_t kernel_virt_base;
|
||||
|
||||
serial_write("[DEBUG] HHDM Offset: 0x");
|
||||
serial_write("[INIT] HHDM Offset: 0x");
|
||||
serial_write_hex(hhdm_offset);
|
||||
serial_write("\n");
|
||||
serial_write("[DEBUG] Kernel Phys: 0x");
|
||||
serial_write("[INIT] Kernel Phys: 0x");
|
||||
serial_write_hex(kernel_phys_base);
|
||||
serial_write("\n");
|
||||
serial_write("[DEBUG] Kernel Virt: 0x");
|
||||
serial_write("[INIT] Kernel Virt: 0x");
|
||||
serial_write_hex(kernel_virt_base);
|
||||
serial_write("\n");
|
||||
|
||||
if (memmap_request.response != NULL) {
|
||||
// The memory manager will now scan the memory map and manage all usable regions.
|
||||
memory_manager_init_from_memmap(memmap_request.response);
|
||||
serial_write("[DEBUG] memory_manager_init OK\n");
|
||||
smp_init_bsp();
|
||||
serial_write("[DEBUG] smp_init_bsp OK\n");
|
||||
} else {
|
||||
serial_write("[DEBUG] ERROR: No usable memory for heap! Check Limine memmap.\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) {
|
||||
serial_write("[DEBUG] No framebuffer! Halting.\n");
|
||||
serial_write("[INIT] No framebuffer! Halting.\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
struct limine_framebuffer *fb = framebuffer_request.response->framebuffers[0];
|
||||
graphics_init(fb);
|
||||
serial_write("[DEBUG] graphics_init OK\n");
|
||||
kconsole_init();
|
||||
log_ok("Graphics and Console ready");
|
||||
|
||||
if (memmap_request.response != NULL) {
|
||||
// The memory manager will now scan the memory map and manage all usable regions.
|
||||
memory_manager_init_from_memmap(memmap_request.response);
|
||||
log_ok("Memory manager ready");
|
||||
smp_init_bsp();
|
||||
log_ok("SMP BSP initialized");
|
||||
} else {
|
||||
log_fail("No usable memory for heap! Check Limine memmap.");
|
||||
hcf();
|
||||
}
|
||||
|
||||
gdt_init();
|
||||
serial_write("[DEBUG] gdt_init OK\n");
|
||||
log_ok("GDT initialized");
|
||||
|
||||
paging_init();
|
||||
serial_write("[DEBUG] paging_init OK\n");
|
||||
log_ok("Paging ready");
|
||||
|
||||
syscall_init();
|
||||
serial_write("[DEBUG] syscall_init OK\n");
|
||||
log_ok("Syscalls ready");
|
||||
|
||||
idt_init();
|
||||
idt_register_interrupts();
|
||||
idt_load();
|
||||
serial_write("[DEBUG] idt_init OK\n");
|
||||
log_ok("IDT ready");
|
||||
|
||||
process_init();
|
||||
|
||||
|
||||
fat32_init();
|
||||
serial_write("[DEBUG] fat32_init OK\n");
|
||||
log_ok("FAT32 ready");
|
||||
fat32_mkdir("/bin");
|
||||
fat32_mkdir("/Library");
|
||||
fat32_mkdir("/Library/images");
|
||||
|
|
@ -214,11 +260,9 @@ void kmain(void) {
|
|||
vfs_mount("/proc", "procfs", "procfs", procfs_get_ops(), NULL);
|
||||
|
||||
if (module_request.response == NULL) {
|
||||
serial_write("[DEBUG] ERROR: Limine Module Response is NULL!\n");
|
||||
log_fail("Limine module response NULL");
|
||||
} else {
|
||||
serial_write("[DEBUG] Limine Module Response found. Count: ");
|
||||
serial_write_num(module_request.response->module_count);
|
||||
serial_write("\n");
|
||||
log_ok("Limine modules loaded");
|
||||
for (uint64_t i = 0; i < module_request.response->module_count; i++) {
|
||||
struct limine_file *mod = module_request.response->modules[i];
|
||||
|
||||
|
|
@ -230,7 +274,7 @@ void kmain(void) {
|
|||
while(clean_path[len]) len++;
|
||||
|
||||
if (len >= 4 && clean_path[len-4] == '.' && clean_path[len-3] == 't' && clean_path[len-2] == 'a' && clean_path[len-1] == 'r') {
|
||||
serial_write("[DEBUG] Parsing TAR initrd: ");
|
||||
serial_write("[INIT] Parsing TAR initrd: ");
|
||||
serial_write(clean_path);
|
||||
serial_write("\n");
|
||||
tar_parse(mod->address, mod->size);
|
||||
|
|
@ -260,7 +304,7 @@ void kmain(void) {
|
|||
// Initialize fonts now that FAT32 and modules are loaded
|
||||
uint64_t current_rsp;
|
||||
asm volatile("mov %%rsp, %0" : "=r"(current_rsp));
|
||||
serial_write("[DEBUG] Stack Alignment: 0x");
|
||||
serial_write("[INIT] Stack Alignment: 0x");
|
||||
serial_write_hex(current_rsp);
|
||||
serial_write("\n");
|
||||
|
||||
|
|
@ -276,11 +320,9 @@ void kmain(void) {
|
|||
// Initialize SMP
|
||||
if (smp_request.response != NULL) {
|
||||
uint32_t online = smp_init(smp_request.response);
|
||||
serial_write("[DEBUG] SMP init complete, CPUs online: ");
|
||||
serial_write_num(online);
|
||||
serial_write("\n");
|
||||
log_ok("SMP initialized");
|
||||
} else {
|
||||
serial_write("[DEBUG] No SMP response from bootloader\n");
|
||||
serial_write("[INIT] No SMP response from bootloader\n");
|
||||
smp_init(NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ static int next_sd_index = 0; // For sda, sdb, sdc...
|
|||
|
||||
extern void serial_write(const char *str);
|
||||
extern void serial_write_num(uint64_t num);
|
||||
extern void log_ok(const char *msg);
|
||||
extern void log_fail(const char *msg);
|
||||
|
||||
// === String Helpers ===
|
||||
|
||||
|
|
@ -306,14 +308,16 @@ void disk_register_partition(Disk *parent, uint32_t lba_offset, uint32_t sector_
|
|||
dm_strcpy(mount_path + 5, part->devname);
|
||||
|
||||
if (vfs_mount(mount_path, part->devname, "fat32", fat32_get_realfs_ops(), vol)) {
|
||||
serial_write("[VFS] Mounted ");
|
||||
serial_write(mount_path);
|
||||
serial_write(" to VFS\n");
|
||||
char ok_msg[64];
|
||||
dm_strcpy(ok_msg, "Mounted ");
|
||||
dm_strcpy(ok_msg + 8, mount_path);
|
||||
log_ok(ok_msg);
|
||||
wm_notify_fs_change();
|
||||
} else {
|
||||
serial_write("[VFS] Failed to mount ");
|
||||
serial_write(mount_path);
|
||||
serial_write("\n");
|
||||
char fail_msg[64];
|
||||
dm_strcpy(fail_msg, "Failed to mount ");
|
||||
dm_strcpy(fail_msg + 16, mount_path);
|
||||
log_fail(fail_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -499,7 +503,7 @@ void disk_manager_init(void) {
|
|||
next_sd_index = 0;
|
||||
next_drive_letter_idx = 0;
|
||||
|
||||
serial_write("[DISK] Disk manager initialized (VFS mode)\n");
|
||||
log_ok("Disk manager ready");
|
||||
// NOTE: Ramdisk (A:) is no longer registered here.
|
||||
// RAMFS is managed directly by fat32.c and mounted at "/" via VFS.
|
||||
}
|
||||
|
|
@ -509,12 +513,13 @@ void disk_manager_scan(void) {
|
|||
ahci_init();
|
||||
|
||||
if (ahci_get_port_count() == 0) {
|
||||
serial_write("[DISK] No AHCI ports found, falling back to legacy IDE PIO...\n");
|
||||
serial_write("[DISK] No AHCI ports found, falling back to legacy IDE...\n");
|
||||
try_add_ata_drive(ATA_PRIMARY_IO, false, "IDE Primary Master");
|
||||
try_add_ata_drive(ATA_PRIMARY_IO, true, "IDE Primary Slave");
|
||||
try_add_ata_drive(ATA_SECONDARY_IO, false, "IDE Secondary Master");
|
||||
try_add_ata_drive(ATA_SECONDARY_IO, true, "IDE Secondary Slave");
|
||||
log_ok("IDE probing complete");
|
||||
} else {
|
||||
serial_write("[DISK] AHCI initialized successfully, skipping legacy IDE.\n");
|
||||
log_ok("AHCI ports initialized, skipping IDE");
|
||||
}
|
||||
}
|
||||
|
|
@ -189,7 +189,7 @@ void vfs_init(void) {
|
|||
}
|
||||
mount_count = 0;
|
||||
|
||||
serial_write("[VFS] Virtual File System initialized\n");
|
||||
serial_write("[VFS] Ready\n");
|
||||
}
|
||||
|
||||
// ===============
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ void memory_validate(void) {
|
|||
}
|
||||
|
||||
if (errors == 0) {
|
||||
cmd_write("Memory validation: OK\n");
|
||||
cmd_write("Memory validation: [OK]\n");
|
||||
} else {
|
||||
cmd_write("Memory validation failed with ");
|
||||
cmd_write_int(errors);
|
||||
|
|
|
|||
|
|
@ -1133,7 +1133,6 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
|||
(cpcb->remote_port == port) &&
|
||||
ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
|
||||
ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
|
||||
/* linux returns EISCONN here, but ERR_USE should be OK for us */
|
||||
return ERR_USE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ int network_init(void) {
|
|||
ipv4_address_t ip;
|
||||
network_get_ipv4_address(&ip);
|
||||
extern void serial_write(const char *str);
|
||||
serial_write("[NETWORK] IP Assigned: ");
|
||||
serial_write("[NET] IP Assigned: ");
|
||||
char buf[32];
|
||||
k_itoa(ip.bytes[0], buf); serial_write(buf); serial_write(".");
|
||||
k_itoa(ip.bytes[1], buf); serial_write(buf); serial_write(".");
|
||||
|
|
@ -96,7 +96,7 @@ int network_init(void) {
|
|||
k_itoa(ip.bytes[3], buf); serial_write(buf); serial_write("\n");
|
||||
} else {
|
||||
extern void serial_write(const char *str);
|
||||
serial_write("[NETWORK] DHCP Failed during init\n");
|
||||
serial_write("[NET] DHCP Failed during init\n");
|
||||
}
|
||||
|
||||
// Set default DNS server (1.1.1.1)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
|
|||
size_t elf_load_size = 0;
|
||||
uint64_t entry_point = elf_load(filepath, new_proc->pml4_phys, &elf_load_size);
|
||||
if (entry_point == 0) {
|
||||
serial_write("[PROCESS] Failed to load ELF: ");
|
||||
serial_write("[PROC] Failed to load ELF: ");
|
||||
serial_write(filepath);
|
||||
serial_write("\n");
|
||||
// We technically leak the page table here, but let's ignore cleanup for now
|
||||
|
|
@ -371,7 +371,7 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
|
|||
current_process[0]->next = new_proc;
|
||||
spinlock_release_irqrestore(&runqueue_lock, rflags);
|
||||
|
||||
serial_write("[PROCESS] Spawned ELF Executable: ");
|
||||
serial_write("[PROC] Exec: ");
|
||||
serial_write(filepath);
|
||||
serial_write("\n");
|
||||
return new_proc;
|
||||
|
|
|
|||
|
|
@ -37,10 +37,13 @@ static uint32_t read_lapic_id(void) {
|
|||
}
|
||||
|
||||
uint32_t smp_this_cpu_id(void) {
|
||||
if (total_cpus <= 1) return 0;
|
||||
if (total_cpus <= 1 || !cpu_states) return 0;
|
||||
|
||||
// Use GS-based self-pointer to get the structure first
|
||||
cpu_state_t *state;
|
||||
cpu_state_t *state = NULL;
|
||||
// Safely check GS:0. If GS is not set or base is 0, this should be handled carefully.
|
||||
// In BoredOS, if GS is not set, this might still fault depending on address space.
|
||||
// However, the cpu_states check above covers the most likely early-boot failure.
|
||||
asm volatile("movq %%gs:0, %0" : "=r"(state) : : "memory");
|
||||
if (state) return state->cpu_id;
|
||||
|
||||
|
|
|
|||
|
|
@ -203,12 +203,14 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
|
||||
if (cmd == GUI_CMD_WINDOW_CREATE) {
|
||||
extern void serial_write(const char *str);
|
||||
serial_write("Kernel: GUI_CMD_WINDOW_CREATE\n");
|
||||
|
||||
const char *title = (const char *)arg2;
|
||||
|
||||
serial_write("[WM] CreateWindow: ");
|
||||
serial_write(title ? title : "Unknown");
|
||||
serial_write("\n");
|
||||
uint64_t *u_params = (uint64_t *)arg3;
|
||||
if (!u_params) {
|
||||
serial_write("Kernel: Error - params is NULL\n");
|
||||
serial_write("[WM] Error - params is NULL\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -216,14 +218,14 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
uint64_t params[4];
|
||||
for (int i = 0; i < 4; i++) params[i] = u_params[i];
|
||||
|
||||
serial_write("Kernel: Window params copied.\n");
|
||||
// params verified
|
||||
|
||||
Window *win = kmalloc(sizeof(Window));
|
||||
if (!win) {
|
||||
serial_write("Kernel: Error - kmalloc failed for Window\n");
|
||||
serial_write("[WM] Error - kmalloc failed for Window\n");
|
||||
return 0;
|
||||
}
|
||||
serial_write("Kernel: Window allocated.\n");
|
||||
// win allocated
|
||||
|
||||
extern void mem_memset(void *dest, int val, size_t len);
|
||||
mem_memset(win, 0, sizeof(Window));
|
||||
|
|
@ -240,11 +242,8 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
kernel_title[i] = title[i];
|
||||
}
|
||||
kernel_title[title_len] = '\0';
|
||||
serial_write("Kernel: Title copied: ");
|
||||
serial_write(kernel_title);
|
||||
serial_write("\n");
|
||||
} else {
|
||||
serial_write("Kernel: Warning - kernel_title kmalloc failed\n");
|
||||
serial_write("[WM] Warning: kernel_title kmalloc failed\n");
|
||||
}
|
||||
|
||||
// Basic initialization
|
||||
|
|
@ -254,7 +253,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
win->w = (int)params[2];
|
||||
win->h = (int)params[3];
|
||||
|
||||
serial_write("Kernel: Init win dims.\n");
|
||||
// dims ready
|
||||
|
||||
// Sanity checks for dimensions
|
||||
if (win->w <= 0 || win->w > 4096) win->w = 400;
|
||||
|
|
@ -268,7 +267,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
win->font = NULL;
|
||||
win->lock = SPINLOCK_INIT;
|
||||
|
||||
serial_write("Kernel: Dims initialized.\n");
|
||||
// ready
|
||||
|
||||
size_t pixel_size = 0;
|
||||
// Safe allocation
|
||||
|
|
@ -283,7 +282,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
win->comp_pixels = kmalloc(pixel_size);
|
||||
}
|
||||
|
||||
serial_write("Kernel: Buffers allocated.\n");
|
||||
// buffs ok
|
||||
|
||||
if (win->pixels) {
|
||||
extern void mem_memset(void *dest, int val, size_t len);
|
||||
|
|
@ -294,7 +293,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
mem_memset(win->comp_pixels, 0, pixel_size);
|
||||
}
|
||||
|
||||
serial_write("Kernel: Buffers cleared.\n");
|
||||
serial_write("[WM] Buffers ready\n");
|
||||
|
||||
// Set callbacks
|
||||
win->paint = user_window_paint;
|
||||
|
|
@ -800,7 +799,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
Window *win = (Window *)arg2;
|
||||
if (win) {
|
||||
extern void serial_write(const char *str);
|
||||
serial_write("Kernel: Setting window resizable to ");
|
||||
serial_write("[WM] Resizable: ");
|
||||
serial_write(arg3 ? "true\n" : "false\n");
|
||||
win->resizable = (arg3 != 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,8 +239,8 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
if (strcmp(argv[1], "init") == 0) {
|
||||
if (sys_network_init() == 0) printf("Network OK\n");
|
||||
else printf("Network Fail\n");
|
||||
if (sys_network_init() == 0) printf("Network [OK]\n");
|
||||
else printf("Network [FAIL]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "io.h"
|
||||
#include "font_manager.h"
|
||||
#include "../mem/memory_manager.h"
|
||||
#include "sys/spinlock.h"
|
||||
|
||||
static struct limine_framebuffer *g_fb = NULL;
|
||||
static uint32_t g_bg_color = 0xFF696969;
|
||||
|
|
@ -25,6 +26,7 @@ static int g_bg_image_h = 0;
|
|||
static bool g_use_image = false;
|
||||
|
||||
static DirtyRect g_dirty = {0, 0, 0, 0, false};
|
||||
static spinlock_t graphics_lock = SPINLOCK_INIT;
|
||||
|
||||
|
||||
#define MAX_FB_WIDTH 2048
|
||||
|
|
@ -163,15 +165,19 @@ void graphics_mark_dirty(int x, int y, int w, int h) {
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t flags = spinlock_acquire_irqsave(&graphics_lock);
|
||||
merge_dirty_rect(x, y, w, h);
|
||||
spinlock_release_irqrestore(&graphics_lock, flags);
|
||||
}
|
||||
|
||||
void graphics_mark_screen_dirty(void) {
|
||||
uint64_t flags = spinlock_acquire_irqsave(&graphics_lock);
|
||||
g_dirty.x = 0;
|
||||
g_dirty.y = 0;
|
||||
g_dirty.w = get_screen_width();
|
||||
g_dirty.h = get_screen_height();
|
||||
g_dirty.active = true;
|
||||
spinlock_release_irqrestore(&graphics_lock, flags);
|
||||
}
|
||||
|
||||
DirtyRect graphics_get_dirty_rect(void) {
|
||||
|
|
@ -179,11 +185,9 @@ DirtyRect graphics_get_dirty_rect(void) {
|
|||
}
|
||||
|
||||
void graphics_clear_dirty(void) {
|
||||
extern uint64_t wm_lock_acquire(void);
|
||||
extern void wm_lock_release(uint64_t);
|
||||
uint64_t rflags = wm_lock_acquire();
|
||||
uint64_t flags = spinlock_acquire_irqsave(&graphics_lock);
|
||||
g_dirty.active = false;
|
||||
wm_lock_release(rflags);
|
||||
spinlock_release_irqrestore(&graphics_lock, flags);
|
||||
}
|
||||
|
||||
void graphics_clear_dirty_no_lock(void) {
|
||||
|
|
@ -796,12 +800,22 @@ void graphics_clear_back_buffer(uint32_t color) {
|
|||
}
|
||||
|
||||
void graphics_flip_buffer(void) {
|
||||
if (!g_fb || !g_dirty.active) return;
|
||||
if (!g_fb) return;
|
||||
|
||||
uint64_t flags = spinlock_acquire_irqsave(&graphics_lock);
|
||||
if (!g_dirty.active) {
|
||||
spinlock_release_irqrestore(&graphics_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
int x = g_dirty.x;
|
||||
int y = g_dirty.y;
|
||||
int w = g_dirty.w;
|
||||
int h = g_dirty.h;
|
||||
|
||||
// Clear dirty state
|
||||
g_dirty.active = false;
|
||||
spinlock_release_irqrestore(&graphics_lock, flags);
|
||||
|
||||
if (x < 0) { w += x; x = 0; }
|
||||
if (y < 0) { h += y; y = 0; }
|
||||
|
|
@ -1021,3 +1035,26 @@ void graphics_blit_buffer(uint32_t *src, int dst_x, int dst_y, int w, int h) {
|
|||
}
|
||||
}
|
||||
}
|
||||
void graphics_scroll_back_buffer(int lines) {
|
||||
if (!g_fb || lines <= 0 || lines >= (int)g_fb->height) return;
|
||||
|
||||
extern uint64_t wm_lock_acquire(void);
|
||||
extern void wm_lock_release(uint64_t);
|
||||
uint64_t rflags = wm_lock_acquire();
|
||||
|
||||
int sw = (int)g_fb->width;
|
||||
int sh = (int)g_fb->height;
|
||||
|
||||
for (int y = 0; y < sh - lines; y++) {
|
||||
uint32_t *dst = &g_back_buffer[y * sw];
|
||||
uint32_t *src = &g_back_buffer[(y + lines) * sw];
|
||||
for (int x = 0; x < sw; x++) dst[x] = src[x];
|
||||
}
|
||||
|
||||
for (int y = sh - lines; y < sh; y++) {
|
||||
uint32_t *dst = &g_back_buffer[y * sw];
|
||||
for (int x = 0; x < sw; x++) dst[x] = 0;
|
||||
}
|
||||
|
||||
wm_lock_release(rflags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ void graphics_clear_dirty_no_lock(void);
|
|||
// Double buffering
|
||||
void graphics_flip_buffer(void);
|
||||
void graphics_clear_back_buffer(uint32_t color);
|
||||
void graphics_scroll_back_buffer(int lines);
|
||||
|
||||
// Clipping
|
||||
void graphics_set_clipping(int x, int y, int w, int h);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void wallpaper_process_pending(void) {
|
|||
const char *path = (const char *)pending_wallpaper_path;
|
||||
pending_wallpaper_path = NULL;
|
||||
|
||||
serial_str("[WP] Processing wallpaper: ");
|
||||
serial_str("[WM] Processing wallpaper: ");
|
||||
serial_str(path);
|
||||
serial_str("\n");
|
||||
|
||||
|
|
|
|||
25
src/wm/wm.c
25
src/wm/wm.c
|
|
@ -21,6 +21,7 @@
|
|||
#include "disk.h"
|
||||
#include "../sys/work_queue.h"
|
||||
#include "../sys/smp.h"
|
||||
#include "../core/kconsole.h"
|
||||
|
||||
|
||||
// Hello developer,
|
||||
|
|
@ -44,6 +45,8 @@ void wm_lock_release(uint64_t flags) {
|
|||
}
|
||||
|
||||
extern void serial_write(const char *str);
|
||||
extern void log_ok(const char *msg);
|
||||
extern void log_fail(const char *msg);
|
||||
|
||||
static bool str_eq(const char *s1, const char *s2) {
|
||||
if (!s1 || !s2) return false;
|
||||
|
|
@ -1919,7 +1922,7 @@ void wm_remove_window(Window *win) {
|
|||
force_redraw = true;
|
||||
} else {
|
||||
wm_lock_release(rflags);
|
||||
serial_write("WM: Window not found in all_windows list!\n");
|
||||
log_fail("Window not found in all_windows list!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3096,25 +3099,33 @@ void wm_process_deferred_thumbs(void) {
|
|||
|
||||
void wm_init(void) {
|
||||
disk_manager_init();
|
||||
log_ok("Disk Manager ready");
|
||||
|
||||
disk_manager_scan();
|
||||
log_ok("Disk scanning complete");
|
||||
|
||||
cmd_init();
|
||||
log_ok("Command CLI ready");
|
||||
|
||||
explorer_init();
|
||||
log_ok("Explorer ready");
|
||||
|
||||
wallpaper_init();
|
||||
log_ok("Wallpaper engine ready");
|
||||
|
||||
file_index_init();
|
||||
log_ok("File Indexer ready");
|
||||
|
||||
// Try to load the file index from persistent cache
|
||||
// If it doesn't exist, queue an async build
|
||||
if (!file_index_load()) {
|
||||
// No cache exists - queue async build to background
|
||||
log_ok("No Index cache, background build started");
|
||||
work_queue_submit(build_file_index_async, NULL);
|
||||
} else {
|
||||
// Cache loaded - mark as ready
|
||||
log_ok("Index cache loaded");
|
||||
lumos_index_built = true;
|
||||
}
|
||||
|
||||
refresh_desktop_icons();
|
||||
log_ok("Desktop icons refreshed");
|
||||
|
||||
// Initialize z-indices
|
||||
win_cmd.z_index = 0;
|
||||
|
|
@ -3131,6 +3142,10 @@ void wm_init(void) {
|
|||
win_cmd.visible = false;
|
||||
|
||||
force_redraw = true;
|
||||
|
||||
serial_write("[WM] Initialization complete, transitioning to GUI\n");
|
||||
kconsole_set_active(false);
|
||||
graphics_flip_buffer();
|
||||
}
|
||||
|
||||
uint32_t wm_get_ticks(void) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue