liveBook · Manning

Frame buffer

As explained in Rust in Action: Systems programming concepts and techniques

A VGA frame buffer is a memory region whose contents represent text or pixel data displayed by VGA hardware.

A frame buffer is memory that video hardware reads to determine what appears on screen. In VGA-compatible text mode, the display is an 80 × 25 grid. The bootloader sets up its 4,000-byte frame buffer starting at address 0xb8000, so changing that memory changes the display. section 11.2.3 section 11.2.5

Each grid cell uses two bytes: one for a character and one for its display attributes. The attribute includes foreground and background color information. With 80 × 25 cells at two bytes each, the buffer occupies 4,000 bytes. section 11.2.5 section 11.5.4

Change the first cell’s color

Treat 0xb8000 as a mutable pointer to u8. An unsafe write to framebuffer.offset(1) changes the attribute byte of the first cell; writing 0x30 there paints a block of color. Because the pointer targets u8 values, offset(1) advances one byte. write_volatile() ensures the compiler does not optimize away the write to display memory. section 11.2.3 section 11.2.5

For text output, a Cursor can keep a byte position and foreground and background colors. For each character, it writes the character at that position, writes the combined color at the next byte, then advances two bytes. This gives kernel code a small printing interface over raw memory writes, useful for reporting a panic. section 11.5 section 11.5.4

Listing 11.14 Definition and methods for Cursor
25 struct Cursor {
26   position: isize,
27   foreground: Color,
28   background: Color,
29 }
30  
31 impl Cursor {
32   fn color(&self) -> u8 {
33     let fg = self.foreground as u8;           #1
34     let bg = (self.background as u8) << 4;    #1
35     fg | bg                                   #1
36   }
37  
38   fn print(&mut self, text: &[u8]) {          #2
39     let color = self.color();
40  
41     let framebuffer = 0xb8000 as *mut u8;
42  
43     for &character in text {
44       unsafe {
45         framebuffer.offset(self.position).write_volatile(character);
46         framebuffer.offset(self.position + 1).write_volatile(color);
47       }
48       self.position += 2;
49     }
50   }
51 }

The Cursor listing shows both sides of the interface: combining foreground and background into one color byte, then writing character–color pairs to the frame buffer. section 11.5.4

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Explains the 80 × 25 memory layout and volatile pointer writes, then implements character-and-color printing; stops short of broader display handling.
Examples
Shows a write to the first cell’s color byte and a Cursor that writes character–color pairs.
What it assumes
Introduces pointer offset() and write_volatile() while using Rust raw pointers in a kernel.
What you can do after
Build it from scratch: write text to the VGA frame buffer through a small Cursor interface.
How it connects
Connects the frame buffer to VGA text mode, raw pointers, volatile writes, bootloaders, and kernel panic reporting.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.