/dev/console
existuje především proto, aby vystavil konzoli jádra uživatelskému prostoru. Dokumentace linuxového jádra o zařízeních nyní říká
Konzolové zařízení,
/dev/console
, je zařízení, na které by se měly odesílat systémové zprávy a na kterém by mělo být povoleno přihlášení v režimu jednoho uživatele. Počínaje Linuxem 2.1.71,/dev/console
je spravováno jádrem; u předchozích verzí by to měl být symbolický odkaz buď na/dev/tty0
, konkrétní virtuální konzole, například/dev/tty1
nebo na primární sériový port (tty*
, nikolicu*
) zařízení, v závislosti na konfiguraci systému.
/dev/console
, uzel zařízení s hlavní 5 a vedlejší 1, poskytuje přístup k čemukoli, co jádro považuje za svůj primární způsob interakce se správcem systému; může to být fyzická konzole připojená k systému (s abstrakcí virtuální konzole nahoře, takže může používat tty0
nebo jakýkoli ttyN
kde N je mezi 1 a 63), nebo sériová konzole nebo konzole hypervisoru nebo dokonce braillské zařízení. Všimněte si, že samotné jádro nepoužívá /dev/console
:uzly zařízení jsou pro uživatelský prostor, nikoli pro jádro; kontroluje však, že /dev/console
existuje a je použitelný a nastavuje init
se standardním vstupem, výstupem a chybou ukazující na /dev/console
.
Jak je popsáno zde, /dev/console
je znakové zařízení s pevnou hlavní a vedlejší, protože jde o samostatné zařízení (jako prostředek pro přístup k jádru; ne o fyzické zařízení), které není ekvivalentní /dev/tty0
nebo jakékoli jiné zařízení. Toto je poněkud podobné situaci s /dev/tty
což je jeho vlastní zařízení (5:0), protože poskytuje mírně odlišné funkce než ostatní virtuální konzole nebo terminálová zařízení.
„Seznam konzol“ je skutečně seznam konzol definovaných console=
spouštěcí parametry (nebo výchozí konzole, pokud žádné nejsou). Takto definované konzole můžete vidět v /proc/consoles
. /dev/console
skutečně poskytuje přístup k poslednímu z těchto:
Na příkazovém řádku jádra můžete zadat více voleb console=. Výstup se objeví na všech z nich. Když otevřete
/dev/console
, použije se poslední zařízení .
"Co je /dev/console
." ?" je zodpovězeno v předchozí odpovědi. Možná je tato odpověď jasnější, když znáte odpovědi na další dvě otázky.
Q1. "Co je soubor zařízení představující samotný fyzický terminál?"
Žádný takový soubor zařízení neexistuje.
Q2. "Co je /dev/console
." používá se pro?"
V systému Linux /dev/console
se používá k zobrazení zpráv během spouštění (a vypínání). Používá se také pro „režim pro jednoho uživatele“, jak je uvedeno v odpovědi Stephena Kitta. Není nic moc jiného, na co by to mělo smysl používat.
"Za starých dobrých časů" Unixu, /dev/console
bylo vyhrazené fyzické zařízení. Ale to není případ Linuxu.
Související důkazy
1. "Co je soubor zařízení představující samotný fyzický terminál?"
Pokusím se to pochopit tímto způsobem.
/dev/tty{1..63}
a/dev/pts/n
jsou soubory zařízení představující samotná zařízení (ačkoli jde o emulace), nikoli ve vztahu k procesu nebo jádru./dev/tty0
představuje ten v/dev/tty{1..63}
který je momentálně něčím používán (možná kernelnebo shell proces?)./dev/tty
představuje řídicí terminál aktuálně používaný relací procesu./dev/console
představuje terminál aktuálně používaný jádrem?Co je soubor zařízení představující samotný fyzický terminál, nikoli ve vztahu k jádru nebo procesu?
Základní zařízení pro /dev/tty{1..63}
jsou struct con_driver
. Chcete-li zobrazit všechny možné ovladače, podívejte se na https://elixir.bootlin.com/linux/v4.19/ident/do_take_over_console
Pro tato základní zařízení neexistuje žádný soubor zařízení!
Pro jejich správu existuje pouze minimální uživatelské rozhraní.
$ head /sys/class/vtconsole/*/name
==> /sys/class/vtconsole/vtcon0/name <==
(S) dummy device
==> /sys/class/vtconsole/vtcon1/name <==
(M) frame buffer device
Pokud se opravdu chcete dozvědět více, (M)
znamená modul. Tj. fiktivní konzolové zařízení není poskytováno zaváděcím modulem jádra; je součástí počátečního obrazu jádra (aka "builtin").
Za druhé, bind
soubor v každém podadresáři /sys/class/vtconsole
zobrazí se, aby vám řekl, které zařízení vtconsole je aktivní. Pokud napíšu 0
k aktivnímu, zdá se, že se přepne na figurínu. (Zdá se, že GUI VT nejsou ovlivněny, ale textové VT přestanou fungovat). Zápis 1
ta figurína to totiž neaktivuje. Obě metody fungují pro přepnutí zpět na skutečnou. Pokud čtu kód správně, trik je v tom, že echo 1 > bind
má fungovat pouze pro konzolové ovladače, které jsou vytvořeny jako modul (?!).
Pro framebuffer konkrétně pro konzole, existuje několik dalších informací o vázání různých zařízení framebufferu (/dev/fb0
...) na konkrétní virtuální konzole v https://kernel.org/doc/Documentation/fb/fbcon.txt . To zahrnuje volbu jádra fbcon:map=
nebo příkaz nazvaný con2fbmap
.
Podrobnosti se samozřejmě mohou lišit v závislosti na různých verzích jádra, architektuře, firmwaru, zařízení, ovladačích atd. Ve skutečnosti jsem nikdy nemusel používat žádné z výše uvedených rozhraní. Jádro umožňuje pouze i915
/ inteldrmfb
/ jakkoli tomu chcete říkat převezměte při načtení, výměna např. vgacon
.
Vypadá to, že můj stroj EFI nikdy nemá vgacon
. Takže za prvé používá fiktivní konzolu a za druhé se po 1,2 sekundách přepne na fbcon
, běžící nad efifb
. Ale zatím jsem se nemusel starat o to, jaké jsou detaily; prostě to funguje.
$ dmesg | grep -C2 [Cc]onsole
[ 0.230822] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[ 0.233164] NR_IRQS: 65792, nr_irqs: 728, preallocated irqs: 16
[ 0.233346] Console: colour dummy device 80x25
[ 0.233571] console [tty0] enabled
[ 0.233585] ACPI: Core revision 20180810
[ 0.233838] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 133484882848 ns
--
[ 1.228393] efifb: scrolling: redraw
[ 1.228396] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
[ 1.230393] Console: switching to colour frame buffer device 170x48
[ 1.232090] fb0: EFI VGA frame buffer device
[ 1.232110] intel_idle: MWAIT substates: 0x11142120
--
[ 3.595838] checking generic (e0000000 408000) vs hw (e0000000 10000000)
[ 3.595839] fb: switching to inteldrmfb from EFI VGA
[ 3.596577] Console: switching to colour dummy device 80x25
[ 3.596681] [drm] Replacing VGA console driver
[ 3.597159] [drm] ACPI BIOS requests an excessive sleep of 20000 ms, using 1500 ms instead
[ 3.599830] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
--
[ 3.657050] e1000e 0000:00:19.0 eth0: MAC: 11, PHY: 12, PBA No: FFFFFF-0FF
[ 3.657869] e1000e 0000:00:19.0 eno1: renamed from eth0
[ 4.711453] Console: switching to colour frame buffer device 170x48
[ 4.734356] i915 0000:00:02.0: fb0: inteldrmfb frame buffer device
[ 4.778813] Loading iSCSI transport class v2.0-870.
2. "Co je /dev/console
." používá se pro?"
Jako TTY zařízení můžete použít /dev/console. Například zápis do něj zapíše do konkrétního základního zařízení, které bude mít také vlastní číslo znakového zařízení.
/dev/console je často svázán s /dev/tty0, ale někdy může být svázán s jiným zařízením.
Takže v tomto případě zápis do /dev/console zapíše do /dev/tty0. A naopak zápis do /dev/tty0 je ekvivalentní zápisu do kteréhokoli /dev/ttyN zařízení, které je aktuálně aktivní.
To ale vyvolává zajímavou otázku. Přístup k tty0
bude přistupovat k různým virtuálním konzolím v závislosti na tom, která je právě aktivní. Co vlastně lidé používají tty0
for a podobně co je console
používá se v systému Linux?
-
Technicky můžete číst a zapisovat z
console
/tty0
, například spuštěnígetty
pro umožnění přihlášení natty0
. Ale to je užitečné pouze jako rychlý hack. Protože to znamená, že nemůžete využívat výhod více virtuálních konzolí Linuxu. -
systemd
vypadá vsysfs
pro atribut spojený se zařízením /dev/console, aby bylo možné detekovat základní zařízení TTY. To umožňujesystemd
automaticky vytvořígetty
a umožnit přihlášení např. sériová konzole, když uživatel nastaví konzolu jádra zavedením pomocíconsole=ttyS0
. To je pohodlné; odpadá nutnost konfigurovat tuto konzolu na dvou různých místech. Opět vizman systemd-getty-generator
. Nicméněsystemd
ve skutečnosti neotevře/dev/console
za to. -
Během zavádění systému možná ještě nemáte připojený sysfs. Ale chcete mít možnost zobrazovat chybové zprávy a zprávy o průběhu co nejdříve! Takže kroužíme kolem do bodu 1). Jádro spouští PID 1 s stdin/stdout/stderr připojeným k
/dev/console
. Je velmi příjemné mít tento jednoduchý mechanismus nastavený hned od začátku. -
Uvnitř kontejneru Linux, soubor na
/dev/console
může být vytvořen jako něco jiného - nikoli znakové číslo zařízení5:1
. Místo toho může být vytvořen jako soubor zařízení PTS. Pak by dávalo smysl přihlásit se přes toto/dev/console
soubor.systemd
uvnitř kontejneru umožní přihlášení na takovém zařízení; vizman systemd-getty-generator
.Tento mechanismus se používá, když spouštíte kontejner s
systemd-nspawn
příkaz. (Myslím, že pouze když spustítesystemd-nspawn
na TTY, i když to z prohledávání manuálové stránky nepoznám).systemd-nspawn
vytvoří kontejner/dev/console
jako připojení připojení zařízení PTS z hostitele. To znamená, že toto zařízení PTS není uvnitř/dev/pts/
viditelné uvnitř kontejneru.Zařízení PTS jsou lokální pro konkrétní
devpts
namontovat. Zařízení PTS jsou výjimkou z běžného pravidla, že zařízení jsou identifikována číslem zařízení. Zařízení PTS jsou identifikována kombinací čísla zařízení adevpts
mount. -
Naléhavé zprávy můžete psát na číslo
console
/tty0
, pro zápis do aktuální virtuální konzoly uživatele. To by mohlo být užitečné pro naléhavé chybové zprávy v uživatelském prostoru, podobné naléhavým zprávám jádra, které se tisknou na konzoli (vizman dmesg
). To však není běžné, alespoň po dokončení bootování systému.rsyslog má na této stránce jeden příklad, který tiskne zprávy jádra na
/dev/console
; to je na Linuxu zbytečné, protože jádro to již dělá ve výchozím nastavení. Jeden příklad, který nemohu znovu najít, říká, že to není dobrý nápad používat pro zprávy mimo jádra, protože zpráv syslog je prostě příliš mnoho, zahltíte konzoli a příliš vám překáží.systemd-journald má podobně možnosti předat všechny protokoly do konzole. V zásadě to může být užitečné pro ladění ve virtuálním prostředí. I když pro ladění obvykle přeposíláme na
/dev/kmsg
namísto. To je uloží do vyrovnávací paměti protokolu jádra, takže je můžete číst pomocídmesg
. Stejně jako zprávy generované samotným jádrem mohou být tyto zprávy přenášeny do konzole v závislosti na aktuální konfiguraci jádra.