The terminal driver provides a text-mode interface built on top of the framebuffer driver. It renders characters using PSF (PC Screen Font) fonts and supports a subset of ANSI escape sequences for colored output.
Overview
The terminal operates in character-based coordinates while rendering to a pixel-based framebuffer. It features:
- PSF2 font rendering
- 16-color ANSI color palette
- Automatic scrolling
- Cursor tracking
- Escape sequence parsing
Architecture
The terminal sits between kernel logging functions and the framebuffer:
Data Structures
The terminal uses PSF2 fonts defined by the psfont_t structure:
typedef struct {
uint32_t magic; // Magic bytes to identify PSF
uint32_t version; // Zero for PSF2
uint32_t headersize; // Offset of bitmaps in file (32)
uint32_t flags; // 0 if there's no unicode table
uint32_t numglyph; // Number of glyphs
uint32_t glyph_size; // Size of each glyph in bytes
uint32_t height; // Height in pixels
uint32_t width; // Width in pixels
uint8_t data[]; // The actual font data
} psfont_t;
ANSI Color Palette
The terminal supports 16 standard ANSI colors:
Standard Colors (30-37, 40-47)
TERM_COLOR_BLACK 0x000000
TERM_COLOR_RED 0xaa0000
TERM_COLOR_GREEN 0x00aa00
TERM_COLOR_YELLOW 0xaaaa00
TERM_COLOR_BLUE 0x0000aa
TERM_COLOR_MAGENTA 0xaa00aa
TERM_COLOR_CYAN 0x00aaaa
TERM_COLOR_WHITE 0xaaaaaa
Bright/Light Colors
TERM_COLOR_LTBLACK 0x555555
TERM_COLOR_LTRED 0xff5555
TERM_COLOR_LTGREEN 0x55ff55
TERM_COLOR_LTYELLOW 0xffff55
TERM_COLOR_LTBLUE 0x5555ff
TERM_COLOR_LTMAGENTA 0xff55ff
TERM_COLOR_LTCYAN 0x55ffff
TERM_COLOR_LTWHITE 0xffffff
Default Colors
DEFAULT_FGCOLOR TERM_COLOR_WHITE
DEFAULT_BGCOLOR TERM_COLOR_BLACK
API Functions
term_init
Initializes the terminal driver.
Implementation from term.c:174-183:
void term_init()
{
fb = fb_getinfo();
term_width = fb->width / term_font.width;
term_height = fb->height / term_font.height;
term_clear();
term_flush();
}
Calculates terminal dimensions in characters and clears the screen.
term_putchar
Outputs a single character to the terminal.
void term_putchar(uint8_t c);
Implementation from term.c:140-171:
void term_putchar(uint8_t c)
{
if (parse_cmd_byte(c))
return;
switch (c) {
case '\0':
return;
case '\n':
cursor_x = 0;
cursor_y++;
break;
case '\t':
cursor_x += (cursor_x % 4 == 0) ? 0 : (4 - cursor_x % 4);
break;
default:
putchar_at(c, cursor_x, cursor_y);
cursor_x++;
}
if (cursor_x >= term_width) {
cursor_x = 0;
cursor_y++;
}
if (cursor_y >= term_height) {
scroll();
cursor_y = term_height - 1;
}
}
Handles special characters and triggers scrolling when necessary.
term_clear
Clears the terminal screen with the background color.
Implementation from term.c:130-138:
void term_clear()
{
for (size_t y = 0; y < fb->height; y++)
for (size_t x = 0; x < fb->width; x++)
fb_putpixel(x, y, bgcolor);
cursor_x = 0;
cursor_y = 0;
}
term_flush
Flushes the terminal buffer to the display.
Implementation from term.c:124-127:
void term_flush()
{
fb_swap_buffers();
}
This calls the framebuffer’s buffer swap function to make changes visible.
term_setfgcolor / term_setbgcolor
Sets the foreground or background color.
void term_setfgcolor(uint32_t color);
void term_setbgcolor(uint32_t color);
Implementation from term.c:185-193:
void term_setfgcolor(uint32_t color)
{
fgcolor = color;
}
void term_setbgcolor(uint32_t color)
{
bgcolor = color;
}
term_getwidth / term_getheight
Returns terminal dimensions in characters.
uint32_t term_getwidth();
uint32_t term_getheight();
Implementation from term.c:195-203:
uint32_t term_getwidth()
{
return term_width;
}
uint32_t term_getheight()
{
return term_height;
}
ANSI Escape Sequences
The terminal implements a state machine parser for ANSI escape sequences:
Supported Sequences
Clear Screen
Foreground Color
Bright Foreground
Background Color
Reset
Clears the terminal screen. ESC[30m - Black
ESC[31m - Red
ESC[32m - Green
ESC[33m - Yellow
ESC[34m - Blue
ESC[35m - Magenta
ESC[36m - Cyan
ESC[37m - White
Sets foreground color to standard palette.ESC[30;1m - Bright Black
ESC[31;1m - Bright Red
ESC[32;1m - Bright Green
ESC[33;1m - Bright Yellow
ESC[34;1m - Bright Blue
ESC[35;1m - Bright Magenta
ESC[36;1m - Bright Cyan
ESC[37;1m - Bright White
Sets foreground color to bright palette.ESC[40m - Black background
ESC[41m - Red background
ESC[42m - Green background
ESC[43m - Yellow background
ESC[44m - Blue background
ESC[45m - Magenta background
ESC[46m - Cyan background
ESC[47m - White background
Sets background color.Resets colors to default (white on black).
Parser Implementation
The escape sequence parser from term.c:26-92 uses a state machine:
static bool parse_cmd_byte(uint8_t byte)
{
static enum {
READY,
CMD_WAIT,
PARAM_WAIT
} state;
static int cparams[10] = { 0 };
static int cparamcount = 0;
// State machine implementation...
}
States:
- READY - Waiting for ESC (0x1B)
- CMD_WAIT - Waiting for command character
- PARAM_WAIT - Parsing numeric parameters
Font Rendering
Characters are rendered pixel-by-pixel from the PSF font data:
Implementation from term.c:107-121:
static void putchar_at(uint8_t c, size_t px, size_t py)
{
uint8_t* glyph = &term_font.data[c * term_font.glyph_size];
size_t x = px * term_font.width, y = py * term_font.height;
static const uint8_t masks[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
for (size_t i = 0; i < term_font.height; i++) {
for (size_t j = 0; j < term_font.width; j++) {
fb_putpixel(x + j, y + i, (glyph[i] & masks[j]) ? fgcolor : bgcolor);
}
}
}
Each glyph is a bitmap where set bits represent foreground pixels.
When the cursor reaches the bottom of the screen, the terminal scrolls:
Implementation from term.c:95-104:
static void scroll()
{
for (size_t y = 0; y < fb->height - term_font.height; y++)
for (size_t x = 0; x < fb->width; x++)
fb_putpixel(x, y, fb_getpixel(x, y + term_font.height));
for (size_t y = fb->height - term_font.height; y < fb->height; y++)
for (size_t x = 0; x < fb->width; x++)
fb_putpixel(x, y, bgcolor);
}
The screen content is shifted up by one character line, and the bottom line is cleared.
Scrolling operates at the pixel level, not character level. This allows partial scrolling effects but is computationally more expensive.
Special Character Handling
| Character | Behavior |
|---|
\0 (NUL) | Ignored |
\n (LF) | Move to start of next line |
\t (TAB) | Advance to next 4-character boundary |
| ESC sequences | Color control and clear screen |
Tab implementation from term.c:154-155:
case '\t':
cursor_x += (cursor_x % 4 == 0) ? 0 : (4 - cursor_x % 4);
Source Files