Modernizing the OpenBSD console
Frederic Cambus August 31, 2020 [OpenBSD]At the beginning were text mode consoles. Traditionally, *BSD and Linux on i386 and amd64 used text mode consoles which by default provided 25 rows of 80 columns, the "80x25 mode". This mode uses an 8x16 font stored in the VGA BIOS (which can be slightly different across vendors).
OpenBSD uses the wscons(4) console framework, inherited from NetBSD.
CRT monitors allowed you to set the resolution you wanted, so on bigger monitors, the 80x25 console in textmode was fairly large but not blurry.
Framebuffer consoles allowed taking advantage of larger monitor sizes, to fit more columns and rows. With the switch to LCD monitors, also in part driven by the decreasing costs of laptops, the fixed size panels became a problem as the text mode resolution needed to be stretched, leading to distortion and blurriness.
One thing some people might not realize is the huge discrepancy between text mode and framebuffer consoles regarding the amount of data you have to write to cover the whole screen. In text mode, we only need to write 2 bytes per character: 1 byte for the ASCII code, and 1 byte for attributes. So in 80x25 text mode, we only need to write 80 * 25 * 2 bytes of data, which is 4000 bytes, and the VGA card itself takes care of plotting characters to the screen. In framebuffer, however, to fill a 4K UHD-1 (3840x2160) screen in 32bpp mode we need to send 3840 * 2160 * 4 bytes of data, which is 33177600 bytes (approximately 33 MB).
On framebuffer consoles, OpenBSD uses the rasops(9) subsystem (raster operations), imported from NetBSD in 2001.
While they had been used for a while on platforms without VGA cards, framebuffer consoles were only enabled on i386 and amd64 in 2013 for inteldrm(4) and radeondrm(4).
In recent years, rasops(9) itself and framebuffer drivers have seen some improvements:
General improvements:
- Add and enable efifb(4), EFI framebuffer driver (yasuoka@, August 2015)
- Implement counter-clockwise rotation (kettenis@, August 2017)
- Implement scrollback in rasops(9) (jcs@, April 2018)
Performance related improvements:
- Make it possible to use RI_WRONLY during early boot (kettenis@, September 2015)
- Introduce rasops_wronly_do_cursor() (kettenis@, August 2018)
- Remap EFI framebuffer early to use write combining (kettenis@, September 2018)
- Do PAT setup earlier, so mapping the framebuffer WC actually works (kettenis@, December 2018)
- Fast conditional console scrolling (John Carmack, June 2020)
- Optimize character rendering in 32bpp mode (John Carmack, June 2020)
Console fonts improvements:
- Add Spleen 5x8, targeted at small OLED displays (September 2018)
- Add Spleen 8x16, 12x24, 16x32 and 32x64 (December 2018)
- Enable Spleen in wsfont by default (January 2019)
- Add Spleen 6x12, targeted at OLED displays (July 2020)
There is an article about Spleen in the OpenBSD Journal with more information, notably on the font selection mechanism relative to screen resolution.
And work slowly continues to make framebuffer consoles more usable.
It is interesting to note that while NetBSD has been adding a lot of features to rasops(9) over the years, OpenBSD has taken a more conservative approach. There is however one major feature that NetBSD currently has which would be beneficial: the capability for loading fonts of different metrics and subsequently resizing screens.
Looking forward, the performance of various operations could likely still be improved, possibly by leveraging the new OpenBSD dynamic tracing mechanism to analyze bottlenecks.
Another open question is UTF-8 support, Miod Vallat started work in this direction back in 2013 but there are still a few things missing. I have plans to implement sparse font files support in the future, at least so one can take advantage of box drawing and possibly block elements characters.
Lastly, a major pain point has been the lack of larger fonts in RAMDISK kernels, making installations and upgrades very difficult and error-prone on large DPI monitors as the text is basically unreadable. There is no technical blocker to make this happen, which ironically makes it the most difficult kind of issue to tackle.