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
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user