1

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?

  • 1
    Strictly speaking, the console /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. jdebp.uk./Proposals/linux-kvt-manual-pages.html – JdeBP Feb 21 at 15:34
2

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

| improve this answer | |
0

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.

| improve this answer | |

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.