feat(gui): Enable direct boot to GUI Desktop with emergency kernel TTY fallback

- Integrate Bochs/QEMU VBE physical LFB mapping directly to hardware video memory (0xFD000000)
- Update kernel boot sequence to directly boot into GUI Desktop by default
- Fall back to Emergency Kernel TTY Mode upon GUI exit (Esc key / Exit menu item)
- Support 'nogui', 'text', 'emergency', and 'single' boot arguments to boot directly into text mode
- Remove frame limits so GUI runs persistently
This commit is contained in:
subhobhai943 committed 2026-08-21 03:08:31 +05:30
1 parent 81a17aae37
commit 56d8b3af1a
5 files changed
+75 -49

No files matched your search

+46 -41
View File
@@ -1,3 +1,4 @@
// Bochs / QEMU VBE Display Adapter Driver for SUB-OS
#include <drivers/bochs.h>
#include <arch/x86_64/io.h>
#include <drivers/pci.h>
@@ -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;
}
+13 -1
View File
@@ -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;
-6
View File
@@ -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");
+1
View File
@@ -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);
+15 -1
View File
@@ -66,6 +66,8 @@
#include <drivers/virtio_gpu.h>
#include <drivers/cpufreq.h>
#include <drivers/virtio_input.h>
#include <gui/gui.h>
#include <init/init.h>
#include <kernel/rust.h>
#include <kernel/sub_lang.h>
#include <kernel/cpp_kernel.h>
@@ -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) {