## /dev/console

https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/serial-console.rst

On Linux, the kernel console can be configured using the `console=` [boot option](https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt). Kernel code which calls `printk()` may write messages to it, e.g. when a device is loaded or an error occurs. These messages are also buffered by the kernel. (See also `dmesg`). When a console device is found and started, it receives all the previously buffered messages.

You can pass `console=` multiple times to configure multiple consoles, and messages will be written to all of them. Apparently you can only select one console of each "type": you can't use both `console=ttyS0` and `console=ttyS1`.

The kernel documentation specifies `/dev/console` as a character device numbered 5:1. Opening this character device opens the "main" console, which is the last tty in the list of consoles. The initial non-kernel process `init`, aka PID 1, is started with `/dev/console` connected to standard output, standard error, and standard input.

If none of the consoles are a tty, then opening `/dev/console` returns the error `ENODEV` ("No such device"). The kernel will <del>print</del> log a message, and start `init` regardless. For an example of a kernel console which is not a tty device, see [`netconsole`](https://www.kernel.org/doc/Documentation/networking/netconsole.txt), or my favourite console [the line printer](http://cateee.net/lkddb/web-lkddb/LP_CONSOLE.html). 

You can also see a list of tty consoles by reading `/sys/class/tty/console/active`. [systemd documentation](http://0pointer.de/blog/projects/serial-console.html) points out that the _first_ device shown is the main console. The list is actually in reverse order of the kernel command line. The [current kernel documentation](https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-tty) incorrectly states that the last device shown is the main or "active" console. For some reason it is possible to poll this file for changes (in case console devices are removed?).



Inside a [`systemd-nspawn`](http://0pointer.de/blog/projects/changing-roots.html) container, the file `/dev/console` is replaced with a pseudo-terminal device, aka PTY. These would be best described as virtual terminal devices. These are created dynamically and are also used to implement graphical terminal emulators like GNOME Terminal, and for remote access like `ssh`.

## /dev/tty0

The Linux TTY [device nodes](https://www.kernel.org/doc/Documentation/admin-guide/devices.txt) `tty1` through `tty63` are always virtual terminals. They are also referred to as VTs, or as virtual consoles. They simulate multiple consoles on top of the physical console device driver. Only one virtual console is shown and controlled at a time. The active terminal can be switched, e.g. using `chvt`, or Ctrl+Alt+F1 through however many function keys you have.

You can also read and write to the current VT using `/dev/tty0`. `tty0` is the usual kernel console, e.g. if you did not select one explicitly. "The system first looks for a VGA card [which is what VTs run on] and then for a serial port". You can also set the console to a specific VT, e.g. `console=tty1`.

"If you don't have a VGA card in your system, the first serial port will automatically become the console." A "serial console" like `ttyS0` is probably the most common alternative to `tty0`. It is not possible to use the VT system on top of a serial console.

## /dev/tty

[`/dev/tty` is one of the three standard device files specified by POSIX](https://unix.stackexchange.com/questions/146735/does-posix-require-any-devices) (`/dev/` being one of the three standard directories). Opening it is equivalent to opening the controlling terminal of the current process. The controlling terminal is set when a process first opens a terminal, [at least on Linux](https://unix.stackexchange.com/a/447319/29483). For example, in `init`, it would refer to `/dev/console`.

Detaching from the controlling terminal is one of the steps traditionally required to start a background process, for example a [system logging daemon](https://debian-handbook.info/browse/squeeze/sect.syslog.html). The steps to become a background process are horribly intricate, but to be specific, the step which detaches from the controlling terminal is the [setsid](http://man7.org/linux/man-pages/man2/setsid.2.html) systemd call. In more modern systems, the init system e.g. systemd starts the service without any controlling terminal in the first place.