Master the fundamental concepts of bios & uefi programming through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksGOP replaces legacy VESA BIOS extensions with a UEFI protocol that sets a framebuffer mode and returns a pointer to pixel memory. Locate EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID via LocateProtocol or the handle database, then call SetMode and QueryMode. For example, mode 0 might be 1024x768x32 with a linear framebuffer at a physical address stored in Mode->FrameBufferBase.
cLoading…
ExitBootServices unless the driver marks otherwiseCall QueryMode for every index from zero to Mode->MaxMode - 1 before picking a resolution. Some firmware exposes 1024x768 and 1920x1080 with different pixel formats; treat PixelsPerScanLine as stride, not width. After ExitBootServices, GOP may disappear; kernels that need a framebuffer must copy mode info first. OVMF usually offers GOP on a PCI video device even without a full OS driver stack.
You will compute the exact addresses a GOP writer produces: the framebuffer size from stride and height, and for each pixel the byte offset offset = (y * PixelsPerScanLine + x) * bpp plus the packed BGRX dword 0x00RRGGBB. This exercise requires getting stride math right even when PixelsPerScanLine is padded larger than the visible width.
UEFI's Graphics Output Protocol hands you a linear framebuffer. A row can be longer than the visible width (PixelsPerScanLine includes padding), so a pixel's position is:
cLoading…
In the common BGRX layout a 32-bit pixel reads as 0x00RRGGBB.
First pixels_per_scanline height bytes_per_pixel, then zero or more pixel lines x y r g b until the end of input. Colour components are 0-255.
First fb_size N, where N = pixels_per_scanline * height * bytes_per_pixel. Then one line per pixel:
cLoading…
The value is (r << 16) | (g << 8) | b as 6 uppercase hex digits.