diff --git a/drivers/video/bochs.c b/drivers/video/bochs.c index 128315f..40ddeb4 100644 --- a/drivers/video/bochs.c +++ b/drivers/video/bochs.c @@ -1,3 +1,4 @@ +// Bochs / QEMU VBE Display Adapter Driver for SUB-OS #include #include #include @@ -17,46 +18,6 @@ static uint16_t vbe_read(uint16_t index) { return inw(VBE_DISPI_IOPORT_DATA); } -bool bochs_vbe_init(void) { - memset(&vbe_info, 0, sizeof(vbe_info)); - - // Probe VBE DISPI interface - uint16_t id = vbe_read(VBE_DISPI_INDEX_ID); - if ((id & 0xB0C0) == 0xB0C0) { - vbe_info.available = true; - vbe_info.vbe_version = id; - vbe_info.current_width = 1024; - vbe_info.current_height = 768; - vbe_info.current_bpp = 32; - - pci_device_t* vga_pci = pci_find_class(0x03, 0x00); - if (vga_pci) { - vbe_info.lfb_phys_addr = vga_pci->bar[0] & ~0xF; - } else { - vbe_info.lfb_phys_addr = 0xFD000000; - } - - printk(KERN_INFO "VBE: Bochs/QEMU VBE Display Adapter detected (v%04x, Linear Framebuffer: 0x%llx)\n", - vbe_info.vbe_version, vbe_info.lfb_phys_addr); - return true; - } - - // Software emulated VBE fallback - vbe_info.available = true; - vbe_info.vbe_version = 0xB0C5; - vbe_info.current_width = 800; - vbe_info.current_height = 600; - vbe_info.current_bpp = 32; - vbe_info.lfb_phys_addr = 0xFD000000; - - printk(KERN_INFO "VBE: Standard VESA/VBE Display Engine online (800x600 32bpp TrueColor)\n"); - return true; -} - -bool bochs_vbe_is_available(void) { - return vbe_info.available; -} - int bochs_vbe_set_mode(uint32_t width, uint32_t height, uint32_t bpp) { if (!vbe_info.available) return -1; @@ -70,10 +31,54 @@ int bochs_vbe_set_mode(uint32_t width, uint32_t height, uint32_t bpp) { vbe_info.current_height = height; vbe_info.current_bpp = bpp; - printk(KERN_INFO "VBE: Switched resolution to %ux%u @ %u bpp\n", width, height, bpp); + // Connect global Framebuffer driver directly to hardware video memory + fb_set_hardware_lfb((uint32_t*)vbe_info.lfb_phys_addr, width, height, (uint8_t)bpp); + + printk(KERN_INFO "VBE: Switched resolution to %ux%u @ %u bpp (LFB: 0x%llx)\n", + width, height, bpp, vbe_info.lfb_phys_addr); return 0; } +bool bochs_vbe_init(void) { + memset(&vbe_info, 0, sizeof(vbe_info)); + + // Probe VBE DISPI interface + uint16_t id = vbe_read(VBE_DISPI_INDEX_ID); + if ((id & 0xB0C0) == 0xB0C0) { + vbe_info.available = true; + vbe_info.vbe_version = id; + + pci_device_t* vga_pci = pci_find_class(PCI_CLASS_DISPLAY, PCI_SUBCLASS_ETHERNET); // Check Display class + if (!vga_pci) vga_pci = pci_find_device(0x1234, 0x1111); // QEMU Standard VGA + if (!vga_pci) vga_pci = pci_find_device(0x8086, 0x1237); // Intel PCI host + + if (vga_pci && vga_pci->bar[0] != 0) { + vbe_info.lfb_phys_addr = vga_pci->bar[0] & ~0xF; + } else { + vbe_info.lfb_phys_addr = 0xFD000000; + } + + bochs_vbe_set_mode(320, 200, 32); + + printk(KERN_INFO "VBE: Bochs/QEMU VBE Display Adapter detected (v%04x, Linear Framebuffer: 0x%llx)\n", + vbe_info.vbe_version, vbe_info.lfb_phys_addr); + return true; + } + + // Software emulated VBE fallback + vbe_info.available = true; + vbe_info.vbe_version = 0xB0C5; + vbe_info.lfb_phys_addr = 0xFD000000; + bochs_vbe_set_mode(320, 200, 32); + + printk(KERN_INFO "VBE: Standard VESA/VBE Display Engine online (320x200 32bpp TrueColor)\n"); + return true; +} + +bool bochs_vbe_is_available(void) { + return vbe_info.available; +} + const bochs_vbe_info_t* bochs_vbe_get_info(void) { return &vbe_info; } diff --git a/drivers/video/fb.c b/drivers/video/fb.c index a9b1f64..9d38782 100644 --- a/drivers/video/fb.c +++ b/drivers/video/fb.c @@ -22,13 +22,25 @@ const fb_info_t* fb_get_info(void) { return &fb_info; } +void fb_set_hardware_lfb(uint32_t* lfb_addr, uint32_t width, uint32_t height, uint8_t bpp) { + if (lfb_addr) { + fb_info.address = lfb_addr; + fb_info.width = width; + fb_info.height = height; + fb_info.pitch = width * (bpp / 8); + fb_info.bpp = bpp; + fb_info.active = true; + } +} + void fb_put_pixel(uint32_t x, uint32_t y, uint32_t color) { - if (x < fb_info.width && y < fb_info.height) { + if (fb_info.address && x < fb_info.width && y < fb_info.height) { fb_info.address[y * fb_info.width + x] = color; } } void fb_draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color) { + if (!fb_info.address) return; for (uint32_t j = y; j < y + h && j < fb_info.height; j++) { for (uint32_t i = x; i < x + w && i < fb_info.width; i++) { fb_info.address[j * fb_info.width + i] = color; diff --git a/gui/gui_desktop.c b/gui/gui_desktop.c index 9405252..3b402e1 100644 --- a/gui/gui_desktop.c +++ b/gui/gui_desktop.c @@ -236,12 +236,6 @@ int gui_desktop_run(void) { // 4. Present Framebuffer to Display gui_gfx_present(); - - frame_limit++; - if (frame_limit > 500) { - // Safety break in non-interactive batch test - break; - } } printk(KERN_INFO "GUI: Desktop session ended, restored TTY console\n"); diff --git a/include/drivers/fb.h b/include/drivers/fb.h index 685eea0..e6b2254 100644 --- a/include/drivers/fb.h +++ b/include/drivers/fb.h @@ -16,6 +16,7 @@ typedef struct { void fb_init(void); const fb_info_t* fb_get_info(void); +void fb_set_hardware_lfb(uint32_t* lfb_addr, uint32_t width, uint32_t height, uint8_t bpp); void fb_put_pixel(uint32_t x, uint32_t y, uint32_t color); void fb_draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color); void fb_clear(uint32_t color); diff --git a/kernel/main.c b/kernel/main.c index adf8819..d532891 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -66,6 +66,8 @@ #include #include #include +#include +#include #include #include #include @@ -216,7 +218,19 @@ static void subos_modular_core_boot(void) { arch_enable_interrupts(); printk(ANSI_BRIGHT_GREEN "ACTIVE\n" ANSI_RESET); - // Launch Shell + // Boot directly into GUI Desktop unless emergency text mode is requested + bool emergency_text = init_has_param("nogui") || init_has_param("text") || + init_has_param("emergency") || init_has_param("single"); + + if (!emergency_text) { + printk(KERN_INFO "INIT: Booting directly into SUB-OS Graphical Desktop Environment...\n"); + gui_start_desktop(); + printk(KERN_INFO "INIT: GUI session closed. Entering Emergency Kernel TTY Mode.\n"); + } else { + printk(KERN_INFO "INIT: Emergency text/kernel TTY mode requested via boot parameters.\n"); + } + + // Launch Shell (Emergency TTY Mode) shell_run(); while (1) {