starkernel: item 4.3.1 -- framebuffer orientation test, found and fixed a real color-swap bug
Adds fb_draw_orientation_test() (framebuffer.c/.h): fills the four raster corners RED/GREEN/BLUE/YELLOW via fb_fill_rect. Wired into kernel_main.c calling fb_init() directly -- console_fb_init()/vt100_init() removed from the boot path, since vt100.c/console.c are superseded by the Console drawing-fabric redesign (FABRIC.md ss27) and should not be exercised even incidentally. The diagnostic caught a real, pre-existing bug on its first run: framebuffer.c's pack_pixel() had its FB_PIXEL_RGBX32/FB_PIXEL_BGRX32 branches swapped relative to UEFI GOP's own byte-order naming convention, producing a clean R<->B channel swap (G unaffected). Spatial placement was already correct -- no flip/rotation. Fixed by swapping pack_pixel's two return bodies to match framebuffer.h's already-correct doc comments; kernel_main.c's GOP-format switch needed no change. Also item 4.3.2 -- QEMU screenshot capability. scripts/qemu_screenshot.sh already existed (monitor socket + socat + HMP screendump), just unwired and unused this session. Redirected its PNG output to a new top-level fb/ directory (tracked in git, not logs/, not a gitignored temp dir) and added a python3+PIL fallback for PPM->PNG conversion since imagemagick isn't installed here. Left as a standalone script for now, not wired into a Makefile target. FABRIC.md items 4.3.1 and 4.3.2 marked done with acceptance evidence.
This commit is contained in:
@@ -66,17 +66,27 @@ static FbState g_fb;
|
||||
* Internal helpers
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
/* Convert our 0x00RRGGBB to the hardware BGRX / RGBX 32-bit word */
|
||||
/*
|
||||
* Convert our 0x00RRGGBB to the hardware 32-bit word.
|
||||
*
|
||||
* GOP format names describe increasing byte address in memory (little-endian
|
||||
* uint32 store), e.g. PixelRedGreenBlueReserved8BitPerColor means byte0=R,
|
||||
* byte1=G, byte2=B, byte3=X -- which as a little-endian uint32 puts R in
|
||||
* bits[7:0], G in bits[15:8], B in bits[23:16]. The two branches below were
|
||||
* previously swapped relative to that (found via FABRIC.md item 4.3.1's
|
||||
* orientation test: corners rendered with R and B channels exchanged).
|
||||
*/
|
||||
static uint32_t pack_pixel(uint32_t rgb)
|
||||
{
|
||||
uint32_t r = FB_R(rgb);
|
||||
uint32_t g = FB_G(rgb);
|
||||
uint32_t b = FB_B(rgb);
|
||||
if (g_fb.fmt == FB_PIXEL_RGBX32) {
|
||||
return (r << 16) | (g << 8) | b; /* RGBX: R@[23:16] */
|
||||
/* RGBX byte order R,G,B: byte0=R@[7:0] byte1=G@[15:8] byte2=B@[23:16] */
|
||||
return (b << 16) | (g << 8) | r;
|
||||
}
|
||||
/* BGRX (default): B@[23:16] G@[15:8] R@[7:0] */
|
||||
return (b << 16) | (g << 8) | r;
|
||||
/* BGRX (default), byte order B,G,R: byte0=B@[7:0] byte1=G@[15:8] byte2=R@[23:16] */
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
@@ -197,6 +207,42 @@ void fb_draw_glyph(uint32_t px, uint32_t py, uint8_t ch,
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* Boot diagnostic: orientation test pattern
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* fb_draw_orientation_test — one-time boot diagnostic (FABRIC.md item 4.3.1).
|
||||
*
|
||||
* Fills each raster corner with a distinct solid color so a screendump
|
||||
* immediately reveals whether the image is flipped or rotated. Not part of
|
||||
* the Console drawing fabric itself -- diagnostic-only, analogous to item
|
||||
* 4.2's self-test scaffolding.
|
||||
*
|
||||
* Corner colors (raster/top-left-origin coordinates, pre-Cartesian-flip):
|
||||
* top-left RED
|
||||
* top-right GREEN
|
||||
* bottom-left BLUE
|
||||
* bottom-right YELLOW
|
||||
*/
|
||||
void fb_draw_orientation_test(void)
|
||||
{
|
||||
uint32_t block_w, block_h;
|
||||
|
||||
if (!g_fb.ready) return;
|
||||
|
||||
block_w = g_fb.width / 8u;
|
||||
block_h = g_fb.height / 8u;
|
||||
if (block_w == 0) block_w = 1;
|
||||
if (block_h == 0) block_h = 1;
|
||||
|
||||
fb_fill_rect(0, 0, block_w, block_h, FB_RGB(0xFF, 0x00, 0x00)); /* top-left: RED */
|
||||
fb_fill_rect(g_fb.width - block_w, 0, block_w, block_h, FB_RGB(0x00, 0xFF, 0x00)); /* top-right: GREEN */
|
||||
fb_fill_rect(0, g_fb.height - block_h, block_w, block_h, FB_RGB(0x00, 0x00, 0xFF)); /* bottom-left: BLUE */
|
||||
fb_fill_rect(g_fb.width - block_w, g_fb.height - block_h, block_w, block_h,
|
||||
FB_RGB(0xFF, 0xFF, 0x00)); /* bottom-right: YELLOW */
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* Scrolling
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
@@ -796,7 +796,13 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
if (mama->halted) goto idle;
|
||||
#endif
|
||||
|
||||
/* Activate framebuffer VT100 now that POST is done — REPL-only */
|
||||
/*
|
||||
* FABRIC.md item 4.3.1 -- raw framebuffer boot diagnostic.
|
||||
* console.c / vt100.c are superseded by the Console drawing-fabric
|
||||
* redesign (FABRIC.md §27) and are deliberately not invoked here.
|
||||
* fb_init() wires the raw GOP framebuffer directly; the orientation
|
||||
* test pattern is drawn on a blank framebuffer, nothing else touches it.
|
||||
*/
|
||||
if (boot_info->framebuffer.base != NULL && boot_info->framebuffer.size > 0) {
|
||||
FbPixelFormat fb_fmt;
|
||||
switch (boot_info->framebuffer.pixel_format) {
|
||||
@@ -804,7 +810,8 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
case (UINT32)PixelBlueGreenRedReserved8BitPerColor: fb_fmt = FB_PIXEL_BGRX32; break;
|
||||
default: fb_fmt = FB_PIXEL_BGRX32; break;
|
||||
}
|
||||
console_fb_init(&boot_info->framebuffer, fb_fmt);
|
||||
fb_init(&boot_info->framebuffer, fb_fmt);
|
||||
fb_draw_orientation_test();
|
||||
}
|
||||
|
||||
/* Clear reboot-tries counter: we reached the REPL cleanly */
|
||||
|
||||
Reference in New Issue
Block a user