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?
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.
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
[root@SpaceStation ~]# systemctl list-units | grep getty email@example.com 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 (
[root@SpaceStation ~]# systemctl list-units | grep getty firstname.lastname@example.org loaded active running Getty on tty2 email@example.com 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.