I installed FreeBSD 11.2 on my DELL Latitude E7470 with UEFI (might be important). By default it does not install a GUI and that is fine by me (for now). Using the <Alt>+<Fn> keys I can switch between different virtual terminals.

I cannot change the colors with vt

I tried with the following in /boot/loader.conf but this had no effect:

# definitions for all other colors follow but omitted in this example

Additionally, I changed /etc/ttys to set xterm-256color in the third column instead of xterm but this does not enable 256 color support.

I want to stress that I want to change the number of colors when locally accessing the computer via its own keyboard and monitor in text mode (no gnome, Xorg, KDE...). Accessing the computer over SSH is something completely different.

  • That won't ever work, since FreeBSD console won't support it. It's only a subset of xterm, in any case. Dec 4, 2018 at 21:03
  • Possible duplicate of Changing terminal emulators Dec 4, 2018 at 21:03
  • Then what are those options for? (kern.vt.color.X.rgb)? So there is no way to make the console support more than 8 colors?
    – Tommiie
    Dec 4, 2018 at 21:04
  • 2
    I don't believe that to be a duplicate because they are talking about terminal capabilities over SSH while I want to increase the number of colors while directly accessing the machine via its own keyboard and monitor.
    – Tommiie
    Dec 4, 2018 at 21:08

2 Answers 2


FreeBSD console imitates xterm using teken (see earlier discussion here, and mailing list). It is not a complete implementation; the FreeBSD developers have trimmed out a few items from the terminal description (making the real xterm less useful on that platform).

FreeBSD console (teken) doesn't actually implement 256 colors. See the source-code:

499    /**
500      * The xterm-256 color map has steps of 0x28 (in the range 0-0xff), except
501      * for the first step which is 0x5f.  Scale to the range 0-6 by dividing
502      * by 0x28 and rounding down.  The range of 0-5 cannot represent the
503      * larger first step.
504      *
505      * This table is generated by the follow rules:
506      * - if all components are equal, the result is black for (0, 0, 0) and
507      *   (2, 2, 2), else white; otherwise:
508      * - subtract the smallest component from all components
509      * - if this gives only one nonzero component, then that is the color
510      * - else if one component is 2 or more larger than the other nonzero one,
511      *   then that component gives the color
512      * - else there are 2 nonzero components.  The color is that of a small
513      *   equal mixture of these components (cyan, yellow or magenta).  E.g.,
514      *   (0, 5, 6) (Turquoise2) is a much purer cyan than (0, 2, 3)
515      *   (DeepSkyBlue4), but we map both to cyan since we can't represent
516      *   delicate shades of either blue or cyan and blue would be worse.
517      *   Here it is important that components of 1 never occur.  Blue would
518      *   be twice as large as green in (0, 1, 2).
519      */

Those steps map application's attempts to use 256 colors onto the console's 16 colors.

Since it's not capable of doing what's asked, setting TERM to xterm-256color will not be very effective.

The rgb code is supported in a different part of the kernel, which lets one set the values in the (16-)color palette:

41  static struct {
42          unsigned char r;        /* Red percentage value. */
43          unsigned char g;        /* Green percentage value. */
44          unsigned char b;        /* Blue percentage value. */
45  } color_def[NCOLORS] = {
46          {0,     0,      0},     /* black */
47          {50,    0,      0},     /* dark red */
48          {0,     50,     0},     /* dark green */
49          {77,    63,     0},     /* dark yellow */
50          {20,    40,     64},    /* dark blue */
51          {50,    0,      50},    /* dark magenta */
52          {0,     50,     50},    /* dark cyan */
53          {75,    75,     75},    /* light gray */
55          {18,    20,     21},    /* dark gray */
56          {100,   0,      0},     /* light red */
57          {0,     100,    0},     /* light green */
58          {100,   100,    0},     /* light yellow */
59          {45,    62,     81},    /* light blue */
60          {100,   0,      100},   /* light magenta */
61          {0,     100,    100},   /* light cyan */
62          {100,   100,    100},   /* white */
63  };

In the mailing list, I mentioned these screenshots: teken - 88colors teken - 256colors


As M. Dickey says, the FreeBSD kernel's built-in terminal emulator simply does not have either indexed or 24-bit direct colour support. Really, one should not treat it as xterm at all, and this is yet another case of the xterm terminal type being the wrong thing to use. It is quite significantly different from actual XTerm in this and other respects.

The terminfo database record for it uses the name teken. I have a teken termcap entry which I add to FreeBSD termcap. With these the TERM environment variable value can be set to its proper value of teken, not xterm or xterm-256color.

I ship my termcap entry with the nosh toolset, in the nosh-bundles binary package. It is set up by the external configuration import subsystem, which uses cap_mkdb to create a combined termcap database (which also includes additions for interix and linux) in /etc/system-control/convert/termcap/termcap.db, which can be symbolically linked from /etc/termcap.db. Or one can use the raw constituents in /etc/system-control/convert/termcap/ to make a termcap database by hand onesself.

It also has a teken-256color entry. This isn't for the FreeBSD terminal emulator. It is for my terminal emulator, that provides a superset of teken that includes indexed and 24-bit direct colour capabilities amongst other things. It is designed to be faithful to teken for the most part, that extending even to employing the same undocumented admixture of DECFNK and Xenix Console function key sequences that the FreeBSD terminal emulator actually generates.

JdeBP % console-decode-ecma48                          
SCO Level2+F1
SCO Level2+F2
SCO Level2+F3
SCO Level2+F4
SCO Control+F5
SCO Control+F6
SCO Control+F7
SCO Control+F8
SCO Control+Level2+F9
SCO Control+Level2+F10
SCO Control+Level2+F11
SCO Control+Level2+F12
JdeBP %

One of its uses is as a user-space replacement for the FreeBSD kernel terminal emulator that does not require X11, rendering to the framebuffer and reading input from keyboard and mouse HIDs. The same colour cube as in M. Dickey's answer looks somewhat different:

user-space virtual terminal
(source: jdebp.eu)

Because it is user-space, rather than built in to the kernel, it can afford to include multiple-font Unicode support, CIN-file-driven CJKV input methods, and compatibility with other built-in kernel terminal emulators, including the Linux one (hence the similarly enhanced linux termcap entry).

If you want more than 16 colours without X11, my terminal emulator or one of the several other full-screen framebuffer terminal emulators is the route that you have to take.

Further reading

  • This is a lot of information and I'm afraid I don't understand it all. It will take me a few days of rereading your answer and "further reading" articles hoping I will eventually understand it. Since teken is the built-in terminal emulater, I thought I could "replace" it by simply starting tmux from the shell but then I can't get 256 colors either. On the other hand, logging in via PuTTY over SSH does give me 256 colors. Did I just misconfigure tmux? Or is there something else still at play here?
    – Tommiie
    Dec 6, 2018 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.