User:Isacdaavid/Linux Console

From ArchWiki

From Wikipedia:

The Linux console is a system console supported by the Linux kernel (a system console is the device which receives all kernel messages and warnings and which allows logins in single user mode). The Linux console provides a way for the kernel and other processes to send text output to the user, and to receive text input from the user.

As with all standard distributions, Arch Linux fully implements the Linux console. This article describes the configuration of the console, in terms of hardware, font display, and keyboard input.

Implementation

The console, unlike most services that interact directly with users, is implemented in the kernel. This contrasts with terminal emulation software, such as Xterm, which is implemented in user space as a normal application. The console has always been part of released Linux kernels, but has undergone changes in its history, most notably the transition to using the framebuffer and support for Unicode.

Despite many improvements in the console, its full backward compatibility with legacy hardware means it is limited compared to a graphical terminal emulator.

Virtual consoles

The console is presented to the user as a series of "virtual consoles". These give the impression that several independent terminals are running concurrently; each virtual console can run its own shell, have its own font settings, and be logged in with different users. The virtual consoles each use a device /dev/ttyX, and you can switch between them by pressing Alt+Fx (where x is equal to the virtual console number, beginning with 1). The device /dev/console is automatically mapped to the active virtual console.

Text mode

Since Linux originally began as a kernel for PC hardware, the console was developed using standard IBM CGA/EGA/VGA graphics, which all PCs supported at the time. The graphics operated in VGA text mode, which provides a simple 80x25 character display with 16 colours. This legacy mode is similar the capabilities of dedicated text terminals, such as the DEC VT100 series. It is still possible to boot in text mode if the system hardware supports it, but almost all modern distributions (including Arch Linux) use the framebuffer console instead.

Framebuffer console

As Linux was ported to other non-PC architectures, a better solution was required, since other architectures do not use VGA-compatible graphics adapters, and may not support text modes at all. The framebuffer console was implemented to provide a standard console across all platforms, and so presents the same VGA-style interface regardless of the underlying graphics hardware. As such, the Linux console is not a terminal emulator, but a terminal in its own right. It uses the terminal type linux, and is largely compatible with VT100.

Fonts

Character set

Traditionally character sets consisted of 256 codes. This is because text was represented as one character per (8-bit) byte, with each byte having a possible value of 0-255; each character that can be shown uses a different code. All Unix systems support ASCII, which takes up the majority of the codes from 0-127. The remainder are generally configured in what is called a "character set" or a "codepage". The standard VGA adapter uses IBM CP437, which is designed for the English language, together with some very common accented letters, drawing characters, and some symbols. Unix systems have instead traditionally used ISO-8859 sets, such as the very common ISO-8859-1 for "western European Latin" characters.

The Linux console supports bitmap fonts of 256 to 512 symbols (or "glyphs"). The standard is 256, and using more than this causes the number of colours to be halved to 8. With a 256-glyph font, the font is designed with the character set in mind. Thus the 'lat1' console fonts support the ISO-8859-1 set, and so on.

Unicode

Although console fonts are strictly limited to 256-512 glyphs, the console supports Unicode, and this is the default mode. Therefore fonts can include any Unicode symbols. In practice, most console fonts (being limited to 256 glyphs) support just the characters in the related character set. With 512-glyph fonts, several character sets may be covered, in which case hundreds of symbols can be displayed successfully, with the downside of reduced colours.

Setting the console font

You can view the current console font in tabular format as follows:

$ showconsolefont

The installed fonts are located in /usr/share/kbd/consolefonts/. Generally the font name contains the character set it is designed for and the size of the font. For example, lat9w-16.psfu.gz supports the "Latin 9" ISO character set and has a size of 8x16. To load this particular font, simply run:

$ setfont lat9w-16
Note: Fonts with the psfu extension contain a Unicode mapping, which means that all of the glyphs in the font are automatically mapped correctly. The setfont command allows you to specify explicit mappings, but this is not normally necessary.

If you wish to have support for as many characters as possible, the 512-glyph fonts are recommended, especially if you do not use colours in the console. For example, LatGrkCyr-8x16.psfu.gz contains just about all common Latin accented characters, together with many Greek and Cyrillic characters. For more general work, a standard 256-glyph font appropriate for your language is recommended, since this will not affect the console colours. The default (CP437) font is suitable for many people, but it does not support the Euro symbol.

Keyboard

Keymap

Scan codes

Modifying keymaps

Color Palette

Just as most terminal emulator applications, the Linux virtual terminal/console/tty uses a 16-color configurable palette. There are many methods to change the default colors with varying degrees of persistence. Note that the default palette chosen by Linux won't necessarily be (and usually isn't) the same as the one in xterm, rxvt, or whatever terminal emulator you use inside the graphical session. You need to configure each one separately to achieve a consistent style. This article only covers the colors you see in the kernel's built-in terminal (the text interface seen when X is not running).

After boot methods

The methods described in this section change the palette after you have logged in; default colors will be used before that. These rely on sending escape character sequences to the terminal which in turn interprets them with a special meaning, or using a more user-friendly utility like setterm to send a valid string on your behalf. Note that these sequences are not the same as the ones used to colorize terminal text using one of the 16 numbered colors as defined in the palette, since here we are concerned with changing the RGB values in the palette itself. This is a Linux-specific feature, don't try the following sequences on a different virtual terminal.

Note: clear repaints the whole background and removes artifacts
Note: Only the current virtual console will be affected. You need any of the #During/before boot methods to make changes system-wide

Setterm

Among other things setterm will let you set the main content and background colors to any of the 16 available colors in the palette. This is equivalent to redefining the 0th and 15th color without ever leaving the default color scheme, and is a poor option as far as customisation goes but is listed here for completeness.

$ setterm --background [color_name] --foreground [color_name] --store

where [color_name] can be grey or bright or nothing, followed by any of black, red, green, yellow, blue, magenta, cyan, or white. For instance,

$ setterm --foreground black --store

will paint subsequent output in black.

Echoing raw escape sequences

Note: Issuing reset reverts the terminal to its default state.

Escape codes begin with a prefix, "e]P", indicating the "set color" escape, followed by "XRRGGBB" where X is the number from 0 to F (in hexadecimal) of the color to modify and RRGGBB is a standard 24-bit, 3-channel color with red, green and blue components written in hexadecimal. You could add the following to your ~/.bashrc to be automatically executed at every login. Change RGB values to your taste.

if [ "$TERM" = "linux" ]; then
    echo -en "\e]P0222222" #black    -> this is the background color as well.
    echo -en "\e]P1803232" #darkred
    echo -en "\e]P25b762f" #darkgreen
    echo -en "\e]P3aa9943" #brown
    echo -en "\e]P4324c80" #darkblue
    echo -en "\e]P5706c9a" #darkmagenta
    echo -en "\e]P692b19e" #darkcyan
    echo -en "\e]P7ffffff" #lightgray
    echo -en "\e]P8222222" #darkgray
    echo -en "\e]P9982b2b" #red
    echo -en "\e]PA89b83f" #green
    echo -en "\e]PBefef60" #yellow
    echo -en "\e]PC2b4f98" #blue
    echo -en "\e]PD826ab1" #magenta
    echo -en "\e]PEa1cdcd" #cyan
    echo -en "\e]PFdedede" #white    -> this is the foreground color as well.
    clear                  #repaint the whole background with the new color
fi

setcolors

An Arch user has created a package called setcolors to change the Linux virtual console palette on the fly, as well as an optional #mkinitcpio hook to achieve it from the very start. Unlike the aforementioned option, setcolors will tell the Linux kernel to change defaults so a reset command won't accidentally revert your settings. Install setcolors-gitAUR from the AUR. To run it pass it a file with sixteen hexadecimal, 8-bit per channel, RGB color values separated by new lines. Examples can be found in the package itself.

During/before boot methods

Setting the color palette at boot or at compile time has the advantage of making a system-wide consistent color experience that applies to all tty's and to the boot screen itself. A kernel like Linux is not the first thing that runs when you turn on your computer however, so you might still see firmware and bootloader output before getting to the prettified Linux boot process.

Kernel parameters

Linux exposes the default console palette setters as part of the parameters that can be passed to it at boot, therefore appending the following line to your bootloader will have the effect of changing colors from the very beginning and for all tty's, and is as effective as #hard-coding colors at compilation time. The format is vt.default_red=[color_0_red_component],[color_1_red_component],...,[color_15_red_component] vt.default_grn=[color_0_green_component],[color_1_green_component],...,[color_15_green_component] vt.default_blu=[color_0_blue_component],[color_1_blue_component],...,[color_15_blue_component].

For a completely blank screen:

vt.default_red=0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 vt.default_grn=0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 vt.default_blu=0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

Refer to kernel parameters to know where to add this line.

Recompiling the kernel

Note: This has been tested with Linux 3.12 and 3.17
Warning: Compiling Linux is a time-consuming and computationally heavy process. Consider the other methods first

At some time during the 3.x releases Linux moved the relevant virtual terminal sources to ./drivers/tty/vt/vt.c. Patch the lines where the default_red[], default_grn[] and default_blu[] arrays are initialized. The format has already been explained in #Kernel parameters. After this simple change you are ready to compile.

Consult Kernels#Compilation for guidance on how to compile Linux.

mkinitcpio hook

It's possible to modify the scheme the same way you would do #printing raw escape sequences after logging in but instead from early user-space/initramfs. This has the advantage of showing your custom colors as early as possible during the Linux boot process while it doesn't require you to compile a custom kernel nor you have to pollute bootloader configuration files with long hex strings. On the downside, relying on escape sequences falls short to keep the custom colors after a reset command, because it never actually changes the defaults.

To alleviate the reset problem and allow for a system-wide change you can combine #setcolors with a mkinitcpio hook to run setcolors from early user-space. Install mkinitcpio-colors-gitAUR from the AUR; it should pull setcolors-gitAUR as a dependency.

Define your colors in the /etc/vconsole.conf file using variables COLOR_x=RRGGBB where x is a number between 0 and 15 and RRGGBB is the RGB color hex code.

Rebuild the ramdisk image every time you modify /etc/vconsole.conf:

$ mkinitcpio -p linux

See also