With Alt
+ Fn
you can switch between virtual consoles in most Linux distributions. What application handles the switching of consoles and how? I suppose it has to read the keyboard input before all other processes. Or is it handled by a device driver or another kernel module?

- 3,782

- 13
2 Answers
There's a terminal emulator program built into the Linux kernel. It doesn't manifest as a running process with open file handles. It's layered on top of the framebuffer and the input event subsystem, which it uses internal kernel interfaces to access. It presents itself to application-mode systems as a series of kernel virtual terminal devices, /dev/tty1
and so forth, a pseudo-file under /sys
that shows the active KVT number, and a series of CGA-style video buffer devices, /dev/vcsa1
and so forth.
Normally, it is the kernel terminal emulator that recognizes the ⎇ Alt+FN key chords. It's all done entirely within kernel-mode code. (You can build a kernel that does not have this code, by using the CONFIG_VT
kernel build option.)
Applications softwares can disable this, however. An Xorg server does so, for example. When it is active on-screen, it temporarily turns off or disconnects most of the kernel terminal emulator, recognizes its own key chords (⎈ Control+⎇ Alt+FN), and uses ioctl()
system calls to switch the active KVT away under program control. Effectively, the Xorg server is using the KVT switching as a means to negotiate exclusive access to the framebuffer and the HIDs that it is sharing with the kernel's built-in terminal emulator.
Further reading

- 68,745
In systemd based distro like Enterprise Linux 7 and 8 there is systemd-getty-generator. You can read more about this solution on Lennart Poettering blog: http://0pointer.de/blog/projects/serial-console.html and on freedesktop https://www.freedesktop.org/software/systemd/man/systemd-getty-generator.html.
Simple tests. With console started on ctrl
+alt
+F2
:
[root@SpaceStation ~]# systemctl list-units | grep getty
getty@tty2.service loaded active running Getty on tty2
system-getty.slice loaded active active system-getty.slice
getty.target loaded active active Login Prompts
After entering the third console (ctrl
+alt
+F3
):
[root@SpaceStation ~]# systemctl list-units | grep getty
getty@tty2.service loaded active running Getty on tty2
getty@tty3.service loaded active running Getty on tty3
system-getty.slice loaded active active system-getty.slice
getty.target
The generated service file looks like:
cat /usr/lib/systemd/system/getty@.service
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
After=rc-local.service
# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes
# On systems without virtual consoles, don't start any getty. Note
# that serial gettys are covered by serial-getty@.service, not this
# unit.
ConditionPathExists=/dev/tty0
[Service]
# the VT is cleared by TTYVTDisallocate
ExecStart=-/sbin/agetty --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes
# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=
[Install]
WantedBy=getty.target
DefaultInstance=tty
The most important line is ExecStart=-/sbin/agetty --noclear %I $TERM
that is responsible for starting terminal.

- 1,181
/dev/console
is different to a virtual terminal, and "virtual console" is a mis-mash that just adds confusion. The console is switchable amongst several things, of which a kernel VT is merely one possibility. You are actually asking about kernel virtual terminals. http://jdebp.uk./Proposals/linux-kvt-manual-pages.html – JdeBP Feb 21 '20 at 15:34