mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
feat(video): Add a framebuffer console so the TTY and nano work after graphics mode
Pressing Esc left the desktop and started the shell, but nothing appeared in the
emulator window -- the session was only visible on the host terminal. Once the
VBE adapter is switched into graphics mode the VGA text buffer at 0xB8000 stops
being scanned out, so every printk after that point reached serial and the
dmesg ring but never the display.
Disabling the DISPI interface does not bring the text console back; QEMU keeps
presenting the last framebuffer surface. So rather than clawing the adapter back
to text mode, the console is now rendered into the framebuffer:
drivers/video/fbcon.c draws the console with the shared 8x8 font and carries a
VT100 subset -- SGR colours, cursor addressing, relative moves, erase-display,
erase-line and save/restore. It presents a fixed 80x25 grid, because that is
the geometry the userland assumes (nano pads its bars with %-80s, the shell
wraps at TTY_WIDTH), with the glyph cell scaled to fill the active resolution.
The TTY driver became the console dispatcher: tty_write, tty_clear and
tty_set_cursor route to fbcon while it owns the display. That last one is what
makes nano work -- it positions with tty_set_cursor() rather than escapes, so
its full-screen repaint was landing as an append-only stream.
Also in this change:
- `video=WIDTHxHEIGHT` on the kernel command line selects the display mode,
defaulting to 1280x720 so a 16:9 host panel is filled rather than pillarboxed
when QEMU goes fullscreen. Rejects modes the heap cannot back.
- `make run-fullscreen`, plus zoom-to-fit on the windowed target, so scaling
preserves the guest aspect ratio instead of stretching it.
- QEMU targets raise vgamem_mb, since a 1280x720 32-bit surface exceeds the
default VGA memory.
- bochs_vbe_disable()/fb_set_active() let the framebuffer be marked dormant so
drawing routines no-op after a mode teardown.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
This commit is contained in:
1 parent
e228886adb
commit
7dd8f2219a
10 files changed
+505
-37
No files matched your search
@@ -36,6 +36,12 @@ typedef struct {
|
||||
bool bochs_vbe_init(void);
|
||||
bool bochs_vbe_is_available(void);
|
||||
int bochs_vbe_set_mode(uint32_t width, uint32_t height, uint32_t bpp);
|
||||
|
||||
// Leave graphics and hand the adapter back to VGA text mode. Disabling the
|
||||
// DISPI interface restores the mode the BIOS left behind, which is what makes
|
||||
// the 80x25 console visible again after a desktop session ends.
|
||||
void bochs_vbe_disable(void);
|
||||
bool bochs_vbe_is_enabled(void);
|
||||
const bochs_vbe_info_t* bochs_vbe_get_info(void);
|
||||
|
||||
#endif // _DRIVERS_BOCHS_H
|
||||
@@ -16,6 +16,11 @@ 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);
|
||||
|
||||
// Mark the framebuffer live or dormant. Drawing routines no-op while dormant,
|
||||
// which keeps stray writes out of video memory after a return to text mode.
|
||||
void fb_set_active(bool active);
|
||||
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);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef _DRIVERS_FBCON_H
|
||||
#define _DRIVERS_FBCON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Framebuffer console.
|
||||
//
|
||||
// Once the VBE adapter is switched into graphics mode there is no way back to
|
||||
// an 80x25 text console without reprogramming the VGA register file, and the
|
||||
// text buffer at 0xB8000 is no longer being scanned out. Anything printed after
|
||||
// that point is invisible on the display even though it still reaches serial.
|
||||
//
|
||||
// This renders the console into the framebuffer instead, the way Linux fbcon
|
||||
// does: a character grid drawn with the shared 8x8 font at double height, with
|
||||
// enough of a VT100 parser (SGR colours, cursor addressing, erase) for
|
||||
// full-screen curses-style programs such as the nano editor to work.
|
||||
|
||||
// The userland models a fixed 80x25 console -- nano pads its bars with %-80s,
|
||||
// the shell wraps at TTY_WIDTH -- so fbcon presents exactly that geometry and
|
||||
// scales the glyph cell to fill whatever resolution the adapter is running.
|
||||
#define FBCON_COLS 80
|
||||
#define FBCON_ROWS 25
|
||||
|
||||
void fbcon_init(void);
|
||||
|
||||
// While active, kernel output is drawn here instead of the VGA text buffer.
|
||||
void fbcon_enable(bool enable);
|
||||
bool fbcon_is_active(void);
|
||||
|
||||
void fbcon_write(const char* data, size_t len);
|
||||
void fbcon_putc(char c);
|
||||
void fbcon_clear(void);
|
||||
|
||||
int fbcon_cols(void);
|
||||
int fbcon_rows(void);
|
||||
void fbcon_set_cursor(int row, int col);
|
||||
void fbcon_get_cursor(int* row, int* col);
|
||||
|
||||
#endif // _DRIVERS_FBCON_H
|
||||
Reference in new issue
Block a user