When GRUB is configured with multiboot2, it may provide a graphical
(RGB) framebuffer instead of legacy VGA text mode. This happens on
UTM/QEMU on macOS and other configurations where the bootloader
switches to a pixel-based display.
- Parse multiboot2 framebuffer tag in kernel_main to detect display mode
- Identity-map the framebuffer address (often at 0xFD000000+) after
paging is enabled, with write-through caching
- Add framebuffer.h describing the boot-time display info
- Embed 8x16 VGA bitmap font (font8x16.h) for pixel-mode rendering
- Rewrite VGA driver to support both text mode and pixel mode:
- Text mode: unchanged behavior writing to 0xB8000
- Pixel mode: renders characters using the bitmap font to the
GRUB-provided framebuffer, with proper VGA color palette mapping
- Auto-detects mode from fb_info at init time
- Multiboot2 header now requests text mode via framebuffer tag, but
gracefully falls back to pixel rendering if GRUB provides RGB
- Reverted grub.cfg gfxpayload=text (caused display issues on UTM)
Tested: boots in both text mode and graphical framebuffer mode.
45 lines
1.3 KiB
C
45 lines
1.3 KiB
C
/**
|
|
* @file framebuffer.h
|
|
* @brief Framebuffer information from the bootloader.
|
|
*
|
|
* Stores the display mode and framebuffer address provided by GRUB
|
|
* via the multiboot2 framebuffer tag. The VGA driver uses this to
|
|
* decide between text-mode writes (0xB8000) and pixel rendering.
|
|
*/
|
|
|
|
#ifndef FRAMEBUFFER_H
|
|
#define FRAMEBUFFER_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/** Framebuffer types (matches multiboot2 definitions). */
|
|
#define FB_TYPE_INDEXED 0
|
|
#define FB_TYPE_RGB 1
|
|
#define FB_TYPE_EGA_TEXT 2
|
|
|
|
/**
|
|
* Framebuffer information structure.
|
|
* Populated during boot from the multiboot2 framebuffer tag.
|
|
*/
|
|
typedef struct {
|
|
uint32_t addr; /**< Physical address of the framebuffer. */
|
|
uint32_t pitch; /**< Bytes per scanline. */
|
|
uint32_t width; /**< Width in pixels (or columns for text). */
|
|
uint32_t height; /**< Height in pixels (or rows for text). */
|
|
uint8_t bpp; /**< Bits per pixel. */
|
|
uint8_t type; /**< FB_TYPE_RGB, FB_TYPE_EGA_TEXT, etc. */
|
|
|
|
/* RGB field positions (only valid when type == FB_TYPE_RGB). */
|
|
uint8_t red_pos;
|
|
uint8_t red_size;
|
|
uint8_t green_pos;
|
|
uint8_t green_size;
|
|
uint8_t blue_pos;
|
|
uint8_t blue_size;
|
|
} framebuffer_info_t;
|
|
|
|
/** Global framebuffer info, filled by kernel_main. */
|
|
extern framebuffer_info_t fb_info;
|
|
|
|
#endif /* FRAMEBUFFER_H */
|