How do I set up a framebuffer terminal emulator and get more than 8 or 16 colors without running a display server?

What I am trying to do:

I am trying to build a lightweight computer powered by a Pi Zero 2 W, to be operated entirely from the command line with tmux and plug-ins, outputting to a permanently attached display connected by HDMI.

I would like to have more than 16 colors so that I can use nice color schemes in tux, nvim, and other text-based programs. I would also like to see Unicode characters like emojis. And in a pinch, it would be cool to be able to run lightweight graphical programs without a display server – I’m thinking viewing PDFs, for example.

Why I am attempting to run a terminal emulator without a display server:

I understand that the Linux kernel supports only 8 or 16 colors, so to do what I want, I understand that I’ll need to run a terminal emulator through a display interface.

Because I want to run as lean as possible, I don’t want to load Xorg or Wayland to do this – I understand that working directly on a framebuffer is a viable lightweight alternative.

Unfortunately, I do not yet understand enough about Linux initialization, tty, or addressing the framebuffer to set this all up correctly. It is also possible that my understanding thus far is incorrect.

Where I am stuck:

I have installed fbterm (framebuffer terminal emulator), but I can see only 8 colors (again, on the display connected by HDMI).

I have attempted to configure /usr/lib/systemd/system/getty@service to launch fbterm directly at login, but I do not know how to do that correctly, or even if that will accomplish my intended result.

tput colors through tmux in fbterm returns 256 but running this simple test script displays only 8 unique colors [https://askubuntu.com/questions/821157/print-a-256-color-test-pattern-in-the-terminal/821163#821163\].

Over ssh I can see 256 colors, and colors set by tmux plugins appear correct. My issue is that I intend to operate this machine primarily through its own physically attached display.

If anyone here is knowledgeable about doing things on the framebuffer, I would love some advice or even just corrections on any misunderstandings I may have.

Exactly, the linux console can only display 16 colors.
As far a I know fbterm also only supports 16 colors and the development is abondened.
To achieve your goal (256 colors, view PDFs and emoijs), without wayland or xserver, you would need to use

  • vc4-kms-v3d driver
  • use a wayland terminal like foot, but without using wayland (yes, this is possible) and build foot by your own, with the use of some special flags
  • create a systemd service to replace getty with foot

I will test this on my RPi 3B before I post a step-by-step guide

edit: It did not work

So kinda GUI terminal emulator without windowing system, using DRM/KMS directly. Sounds interesting.

I mean yeah, no witchcraft, just that the need for a console outside of a desktop environment, while the plain Linux console it not enough, is probably a rare thing.

foot has this client/server mode, where the server instance handles Wayland communication. So it is also starting a Wayland instance then I suppose, which starts drawing once you run footclient? Or is there really a way to use it without Wayland at all? :eyes:

All my attempts failed, foot is not working without wayland (the AI was hallucinating :sweat_smile:)
but I also got it not to work with fbterm, I only got 16 colors no matter what I tried.

There is also kmscon but I didn’t try it.

Edit:
kmscon is too old, it#s unmaintained for 12 years.
The build fails when trying to use SIGUNUSED which does not exist anymore on modern systems.

Ah, interesting – good to know but sad to hear. Thank you both for your insight and effort.

Terminology [https://github.com/borisfaure/terminology], based on the Enlightenment Foundation Libraries, purports to have the option to render directly to the framebuffer.

According to this post [ framebuffer support ? · kovidgoyal/kitty · Discussion #6098 · GitHub ], the Debian testing repository build is compiled with framebuffer support, but my naive attempt to run it from DietPi on the Pi Zero 2 W resulted in several errors (I don’t precisely recall them off-hand, but I believe they were about being unable to find or start Wayland) and no working terminology. Perhaps the aarch64 build isn’t compiled for framebuffer support? Or perhaps there’s another unmet dependency I did not see.

Has anyone here used Terminology (or Enlightenment generally) on DietPi?

I don’t have, but I will build by myself and give it a try.

edit:

Ah you have to build the enlightment core library with this, so I will not do this then. I thought it’s just about terminilogy itself.

Hmm maybe I will try to install it from debian repo, it’s even in stable:
https://packages.debian.org/trixie/terminology

Works in X11, Wayland and directly in the Linux framebuffer (fbcon)

1 Like
root@TestPi3B:~# ls /usr/lib/aarch64-linux-gnu/ecore_evas/engines
drm extn fb wayland x 

root@TestPi3B:~# ls /usr/lib/aarch64-linux-gnu/evas/modules/engines
buffer gl_generic gl_x11 software_x11 wayland_egl wayland_shm

So it’s not build with fb support, fb is missing in the second output.
I fiddled with some other things but got only black screen with terminology :melting_face:

This matches my first thought about what would be handy. Sad that it has been abandoned.

See at the bottom of the readme:

Try to export these variables:

export ELM_DISPLAY=fb
export ELM_ACCEL=none
export EVAS_FB_DEV=/dev/fb0

Maybe also ELM_DISPLAY=drm works, maybe even with ELM_ACCEL=gl. The documentation lacks details. There is one about the Python EFL class from the same parent project, but it mixes both variables together, at least I cannot see which value should be assigned to which of the two variables: https://docs.enlightenment.org/python-efl/current/elementary/window.html
EDIT: Ah the list on this page is for the ELM_ENGINE variable, which is an alternative. ELM_ACCEL=gl seems to be valid: https://docs.enlightenment.org/python-efl/current/elementary/configuration.html?highlight=accel_preference#efl.elementary.Configuration.accel_preference

But drm is there. Ah second line. Hmm, is the first maybe for builtin core engines, and the second for additional engine modules? So the sum of both is what is supported?

To be honest: idk. It was late yesterday and I tried to get it working with the help of AI. I checked the two outputs mentioned above and the conclusion was, that the framebuffer support is missing in the debian package.

I also stumbled over some kernel parameters I didn’t try, like

framebuffer_depth=32
framebuffer_ignore_alpha=1

and also

video=HDMI-A-1:3840x2160M-32@60

where the -32 sets the color depth.
Probably the linked thread is a solution?

The application is using mainly the framebuffer /dev/fb0 and QT QPaint and QImage libraries. (CM3 running without X)


This is what I did so far today:

  1. I added this to /boot/config.txt:
dtoverlay=vc4-kms-v3d
framebuffer_depth=32
framebuffer_ignore_alpha=1
video=HDMI-A-1:1920x1080M-32@60

then reboot.
fbset -i returns just 16 bit, but that’s enough to get 256 colors :smiley:

2.install tmux and set this in the tmux config:

set -g default-terminal "screen-256color"

I also made an override for tty1 service:

[Service]
Environment=TERM=screen-256color

tmux returns also screen-256color but the script show again only 16 colors.
So idk, I don’t wanna spend more time with this :sweat_smile:

Oh wow, thank you for all the effort you put into this puzzle. I did not expect this level of support on this forum!

I will continue trying things myself and report any success here if I find it.

I’ve identified a couple of other framebuffer terminals to investigate: yaft [GitHub - uobikiemukot/yaft: yet another framebuffer terminal] and fbpad [ GitHub - aligrudi/fbpad: A small Linux framebuffer virtual terminal ], the latter of which appears to have been straightforward to install on a pi for this project: TIL: running Textual on a framebuffer terminal emulator for Linux | bylr.info. (Though I am not excited about the necessary font conversion to TinyFont, which I think? is a raster format, but whatever – maybe that’s more performant than rendering vectors and it’ll be worth the hassle.)

Am I correct in understanding also that launching an alternative terminal at boot will require launching that terminal instead of agetty? Might that bypass a possible lower-level limitation on colors associated with legacy tty devices?