雖然一直作嵌入式Linux,宿主機和開發板通訊每天都在用tty設備通訊,可是其實本身對TTY設備及終端的概念認識幾乎是0。對於Linux內核的終端、tty、控制檯等概念的認識很模糊。因爲在學習的時候碰到了重定向console的問題,因此藉機學習下tty的知識。如下是我對tty的認識總結,信息來源於網絡和內核文檔。參考資料見文章末尾。html
tty一詞源於Teletypes,或Teletypewriters,它是最先出現的一種終端設備,相似電傳打字機,由Teletype公司生產。最初tty是指鏈接到Unix系統上的物理或者虛擬終端。終端是一種字符型設備,一般使用tty來統稱各類類型的終端設備。隨着時間的推移,當經過串行口可以創建起終端鏈接後,這個名字也用來指任何的串口設備。它還有多種類,例如串口(ttySn、ttySACn、ttyOn)、USB到串口的轉換器(ttyUSBn),還有須要特殊處理才能正常工做的調制解調器(好比傳統的WinModem類設備)等。tty虛擬設備支持虛擬控制檯,它能經過鍵盤及網絡鏈接或者經過xterm會話登陸到計算機上。node
- 其實起初終端和控制檯都不是我的電腦的概念,而是多人共用的小型中型大型計算機上的概念。
- 終端爲主機提供了人機接口,每一個人都經過終端使用主機的資源。終端有字符終端和圖形終端兩種。一臺主機能夠連不少終端。
- 控制檯是一種特殊的人機接口, 是人控制主機的第一人機接口。而主機對於控制檯的信任度高於其餘終端。
對此還能夠結合內核啓動代碼中init進程打開/dev/console和執行兩次sys_dup(0),以及標準輸入、標準輸出、標準出錯,還有就是進程fork後的標準輸入輸出的複製狀況來一塊兒理解。
- 而我的計算機只有控制檯,沒有終端。固然願意的話,能夠在串口上連一兩臺字符啞終端。可是linux按POSIX標準把我的計算機當成小型機來用,在控制檯上經過getty軟件虛擬了六個字符啞終端(或者叫虛擬控制檯終端tty1-tty6)(數量能夠在/etc/inittab裏本身調整)和一個圖型終端, 在虛擬圖形終端中又能夠經過軟件(如rxvt)再虛擬無限多個僞終端(pts/0等)。但這全是虛擬的,雖然用起來同樣,但實際上沒有物理實體。因此在我的計算機上,只有一個實際的控制檯,沒有終端,全部終端都是在控制檯上用軟件模擬的。要把我的計算機當主機再經過串口或網卡外連真正的物理終端也能夠,論成本,誰會怎麼作呢。
終端按照其自身能力分類,能夠分爲:linux
一、啞終端(瘦客戶端)shell
早期的計算機終端是經過串行RS-232通訊的,它只能解釋有限數量的控制碼(CR,LF等),但沒有能力處理執行特殊的轉義序列功能(如清行、清屏或控制光標的位置)。簡單來講就是處理能力有限的終端機,他們通常基本上只具備和機械電傳打字機相似的有限功能。這種類型的終端稱爲啞終端。如今仍然在現代類Unix系統上獲得支持,經過設置環境變量TERM=dumb。啞終端有時用來指任何類型的經過RS-232鏈接的傳統計算機終端,不對數據進行本地處理或本地執行用戶程序的串行通訊終端。啞終端有時也指功能有限,只有單色文本處理能力或直接傳輸每個鍵入的字符而不等待主機輪詢的公共計算機終端。編程
二、智能終端(胖客戶端)windows
智能終端就是有能力處理轉義序列,也就是說處理能力較強的終端機。網絡
Linux系統的終端設備通常有如下幾種:session
/dev/console是系統控制檯,是與操做系統交互的設備。系統所產生的信息會發送到該設備上。平時咱們看到的PC只有一個屏幕和鍵盤,它其實就是控制檯。目前只有在單用戶模式下,才容許用戶登陸控制檯/dev/console。(能夠在單用戶模式下輸入tty命令進行確認)。app
console有緩衝的概念,爲內核提供打印輸出。內核把要打印的內容裝入緩衝區__log_buff,而後由console來決定打印到哪裏(好比是tty0仍是ttySn等)。
console指向激活的終端。歷史上,console指主機自己的屏幕和鍵盤,而tty指用電纜連接的其它位置的控制檯。
某些狀況下console和tty0是一致的,就是當前所使用的是虛擬終端,也是激活虛擬終端。因此有些資料中稱/dev/console是到/dev/tty0的符號連接,可是這樣說如今看來是不對的:根據內核文檔,在2.1.71以前,/dev/console根據不一樣系統設定,符號連接到/dev/tty0或者其餘tty*上,在2.1.71版本以後則徹底由內核代碼內部控制它的映射。 ssh
若是一個終端設備要實現console功能,必須向內核註冊一個struct console結構,通常的串口驅動中都會有。若是設備要實現tty功能,必需要內核的tty子系統註冊一個struct tty_driver結構,註冊函數在drivers/tty/tty_io.c中。一個設備能夠同時實現console和tty_driver,通常串口都這麼作。
這是應用程序中的概念,若是當前進程有控制終端(Controlling Terminal),那麼/dev/tty就是當前進程控制檯的設備文件。對於你登陸的shell,/dev/tty就是你使用的控制檯,設備號是(5,0)。不過它並不指任何物理意義上的控制檯,/dev/tty會映射到當前設備(使用命令「tty」能夠查看它具體對應哪一個實際物理控制檯設備)。輸出到/dev/tty的內容只會顯示在當前工做終端上(不管是登陸在ttyn中仍是pty中)。你若是在控制檯界面下(即字符界面下)那麼dev/tty就是映射到dev/tty1-6之間的一個(取決於你當前的控制檯號),可是若是你如今是在圖形界面(Xwindows),那麼你會發現如今的/dev/tty映射到的是/dev/pts的僞終端上。/dev/tty有些相似於到實際所使用終端設備的一個聯接。
你能夠輸入命令 「tty",將顯示當前映射終端如:/dev/tty1或者/dev/pts/0等。也可使用命令「ps -ax」來查看其餘進程與哪一個控制終端相連。
在當前終端中輸入 echo 「tekkaman」 > /dev/tty ,都會直接顯示在當前的終端中。
/dev/ttyn是進程虛擬控制檯,他們共享同一個真實的物理控制檯。
若是在進程裏打開一個這樣的文件且該文件不是其餘進程的控制檯時,那該文件就是這個進程的控制檯。進程printf數據會輸出到這裏。在PC上,用戶可使用alt+Fn切換控制檯,看起來感受存在多個屏幕,這種虛擬控制檯對應tty1~n,其中 :
例如當使用ALT+F2進行切換時,系統的虛擬控制檯爲/dev/tty2 ,當前控制檯(/dev/tty)則指向/dev/tty2
在UNIX系統中,計算機顯示器一般被稱爲控制檯(Console)。它仿真了類型爲Linux的一種終端,而且有一些設備特殊文件與之相關聯:tty0、tty一、tty2等。當你在控制檯上登陸時,使用的是tty1。使用Alt+[F1—F6]組合鍵時,咱們就能夠切換到tty二、tty3等上面去。
你能夠登陸到不一樣的虛擬控制檯上去,於是可讓系統同時有幾個不一樣的會話存在。
而比較特殊的是/dev/tty0,他表明當前虛擬控制檯,是當前所使用虛擬控制檯的一個別名。所以無論當前正在使用哪一個虛擬控制檯(注意:這裏是虛擬控制檯,不包括僞終端),系統信息都會發送到/dev/tty0上。只有系統或超級用戶root能夠向/dev/tty0進行寫操做。tty0是系統自動打開的,但不用於用戶登陸。在Framebuffer設備沒有啓用的系統中,可使用/dev/tty0訪問顯卡。
僞終端(Pseudo Terminal)是終端的發展,爲知足如今需求(好比網絡登錄、xwindow窗口的管理)。它是成對出現的邏輯終端設備(即master和slave設備, 對master的操做會反映到slave上)。它多用於模擬終端程序,是遠程登錄(telnet、ssh、xterm等)後建立的控制檯設備。
歷史上,有兩套僞終端軟件接口:
BSD接口:較簡單,master爲/dev/pty[p-za-e][0-9a-f] ;slave爲 /dev/tty[p-za-e][0-9a-f] ,它們都是配對的出現的。例如/dev/ptyp3和/dev/ttyp3。但因爲在編程時要找到一個合適的終端須要逐個嘗試,因此逐漸被放棄。
Unix 98接口:使用一個/dev/ptmx做爲master設備,在每次打開操做時會獲得一個master設備fd,並在/dev/pts/目錄下獲得一個slave設備(如 /dev/pts/3和/dev/ptmx),這樣就避免了逐個嘗試的麻煩。因爲可能有好幾千個用戶登錄,因此/dev/pts/*是動態生成的,不象其餘設備文件是構建系統時就已經產生的硬盤節點(若是未使用devfs、udev、mdev等) 。第一個用戶登錄,設備文件爲/dev/pts/0,第二個爲/dev/pts/1,以此類推。它們並不與實際物理設備直接相關。如今大多數系統是經過此接口實現pty。
咱們在X Window下打開的終端或使用telnet 或ssh等方式登陸Linux主機,此時均經過pty設備。例如,若是某人在網上使用telnet程序鏈接到你的計算機上,則telnet程序就可能會打開/dev/ptmx設備獲取一個fd。此時一個getty程序就應該運行在對應的/dev/pts/*上。當telnet從遠端獲取了一個字符時,該字符就會經過ptmx、pts/*傳遞給 getty程序,而getty程序就會經過pts/*、ptmx和telnet程序往網絡上返回「login:」字符串信息。這樣,登陸程序與telnet程序就經過「僞終端」進行通訊。
- telnet<--->/dev/ptmx(master)<--->pts/*(slave)<--->getty
若是一個程序把 pts/*看做是一個串行端口設備,則它對該端口的讀/寫操做會反映在該邏輯終端設備對的另外一個/dev/ptmx上,而/dev/ptmx則是另外一個程序用於讀寫操做的邏輯設備。這樣,兩個程序就能夠經過這種邏輯設備進行互相交流,這很象是邏輯設備對之間的管道操做。對於pts/*,任何設計成使用一個串行端口設備的程序均可以使用該邏輯設備。但對於使用/dev/ptmx的程序,則須要專門設計來使用/dev/ptmx邏輯設備。
經過使用適當的軟件,就能夠把兩個甚至多個僞終端設備鏈接到同一個物理串行端口上。
- 實驗:
- 一、在X下打開一個或N個終端窗口
- 二、#ls /dev/pts/*
- 三、關閉這個X下的終端窗口,再次運行;比較兩次輸出信息就明白了。
- 輸出爲/dev/ptmx /dev/pts/1存在一(master)對多(slave)的狀況
串行端口終端(Serial Port Terminal)是使用計算機串行端口鏈接的終端設備。計算機把每一個串行端口都看做是一個字符設備。有段時間串行端口設備一般被稱爲終端設備,那時它的最大用途就是用來鏈接終端,因此這些串行端口所對應的設備名稱是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev /ttyS1)等,設備號分別是(4,0)、(4,1)等(對應於win系統下的COM一、COM2等)。若要向一個端口發送數據,能夠在命令行上把標準輸出重定向到這些特殊文件名上便可。
例如,在命令行提示符下鍵入:echo tekkaman> /dev/ttyS1會把「tekkaman」發送到鏈接在ttyS1(COM2)端口的設備上。
在2.6之後的內核中,部分三星芯片(例如S3C24x0等)將串口終端設備節點命名爲ttySACn。TI的Omap系列芯片從2.6.37開始芯片自帶的UART設備開始使用專有的的omap-uart驅動,故設備節點命名爲ttyOn,以區別於使用8250驅動時的設備名「ttySn」。
還針對不少不一樣的字符設備存在有不少其它種類的終端設備特殊文件,例如針對ISDN設備的/dev/ttyIn終端設備等。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
其實在理解以上概念的時候,若是瞭解終端的發展歷程,就能夠比較容易理解tty、終端的概念。因此請你們閱讀最後推薦的wiki英文網頁,有助於理解上面的概念。固然,內核文檔也是必不可少的參考資料,我順手翻譯了一下。
內核文檔/Documentation/devices.txt翻譯節選:
- **** 終端設備
- Terminal, or TTY devices are a special class of character devices. A
- terminal device is any device that could act as a controlling terminal
- for a session; this includes virtual consoles, serial ports, and
- pseudoterminals .
- 終端或這TTY設備是一類特殊的字符設備。
- 一個終端設備是任何對於一個會話能夠做爲控制終端的設備。
- 這包括虛擬控制檯、串口和僞終端(PTYs)。
- All terminal devices share a common set of capabilities known as line
- disciplines; these include the common terminal line discipline as well
- as SLIP and PPP modes.
- 全部終端設備共享一系列常規能力-線路規程。
- 這包含常見的終端線路規程,例如SLIP和PPP模式。
- All terminal devices are named similarly; this section explains the
- naming and use of the various types of TTYs. Note that the naming
- conventions include several historical warts; some of these are
- Linux-specific, some were inherited from other systems, and some
- reflect Linux outgrowing a borrowed convention.
- 全部終端設備的命名都比較簡單。本節介紹不一樣類型TTY的命名和用途。
- 注意命名的約定包含了一些歷史需求:
- 某些是Linux特定的,
- 某些是從其餘的系統中繼承下來的,
- 還有一些則反映了Linux從借鑑來的約定中發展而來的。
- A hash mark (#) in a device name is used here to indicate a decimal
- number without leading zeroes.
- 設備名中的(#)標誌用於標識一個不以0開頭的10進制數。
- Virtual consoles and the console device
- 虛擬控制檯和控制檯設備
- Virtual consoles are full-screen terminal displays on the system video
- monitor. Virtual consoles are named /dev/tty#, with numbering
- starting at /dev/tty1; /dev/tty0 is the current virtual console.
- /dev/tty0 is the device that should be used to access the system video
- card on those architectures for which the frame buffer devices
- (/dev/fb*) are not applicable. Do not use /dev/console
- for this purpose.
- 虛擬控制檯是在系統視頻監視器上全屏的顯示終端。
- 虛擬控制檯設備名爲/dev/tty#,編號開始於/dev/tty1。
- /dev/tty0是當前虛擬控制檯。
- /dev/tty0在那些幀緩衝設備(/dev/fb*)不適用的構架下能夠被用來訪問系統顯卡。
- 而/dev/console並不用於此目的。
- The console device, /dev/console, is the device to which system
- messages should be sent, and on which logins should be permitted in
- single-user mode. Starting with Linux 2.1.71, /dev/console is managed
- by the kernel; for previous versions it should be a symbolic link to
- either /dev/tty0, a specific virtual console such as /dev/tty1, or to
- a serial port primary (tty*, not cu*) device, depending on the
- configuration of the system.
- 控制檯設備/dev/console是一個接受系統信息並在單用戶模式下容許登陸的設備。
- 從Linux 2.1.71開始,/dev/console由內核管理,
- 而之前的版本是一個到/dev/tty0、一個特定的虛擬控制檯(如/dev/tty1)或者一個串口主(tty*,非cu*)設備動態連接,這些依賴系統配置。
- Serial ports are RS-232 serial ports and any device which simulates
- one, either in hardware (such as internal modems) or in software (such
- as the ISDN driver.) Under Linux, each serial ports has two device
- names, the primary or callin device and the alternate or callout one.
- Each kind of device is indicated by a different letter. For any
- letter X, the names of the devices are /dev/ttyX# and /dev/cux#,
- respectively; for historical reasons, /dev/ttyS# and /dev/ttyC#
- correspond to /dev/cua# and /dev/cub#. In the future, it should be
- expected that multiple letters will be used; all letters will be upper
- case for the "tty" device (e.g. /dev/ttyDP#) and lower case for the
- "cu" device (e.g. /dev/cudp#).
- 串行端口是RS-232串口和任何相似的設備,不管是硬件的(如內部調制解調器)或者軟件(如ISDN驅動)。
- 在Linux下,每一個串口有兩個設備名,主要的(callin設備)和備用的(callout設備),每類設備都經過不一樣的字母標識。對於任何字母X,設備名分別是/dev/ttyX# 和/dev/cux#;因爲歷史緣由,/dev/ttyS#和/dev/ttyC#對應於/dev/cua#和/dev/cub#。將來,對於「tty」多字母的名字將會被使用,全部的字母都將是大寫(如/dev/ttyDP#),對於"cu"設備則使用小寫字母(如/dev/cudp#)。
- The names /dev/ttyQ# and /dev/cuq# are reserved for local use.
- 名字(/dev/ttyQ#和/dev/cuq#)保留,用於本地使用。
- The alternate devices provide for kernel-based exclusion and somewhat
- different defaults than the primary devices. Their main purpose is to
- allow the use of serial ports with programs with no inherent or broken
- support for serial ports. Their use is deprecated, and they may be
- removed from a future version of Linux.
- 備用設備提供基於內核的exclusion和某些與主要設備不一樣的默認配置。他們的主要目的是容許那些對於串口並不是內部支持或是有必定問題的程序使用串口。他們的使用已通過時,他們可能會從將來的Linux版本中刪除。
- Arbitration of serial ports is provided by the use of lock files with
- the names /var/lock/LCK..ttyX#. The contents of the lock file should
- be the PID of the locking process as an ASCII number.
- 串口的仲裁是經過鎖文件(/var/lock/LCK..ttyX#)來提供的。
- 鎖文件的內容應該是鎖定進程PID的ASCII碼。
- It is common practice to install links such as /dev/modem
- which point to serial ports. In order to ensure proper locking in the
- presence of these links, it is recommended that software chase
- symlinks and lock all possible names; additionally, it is recommended
- that a lock file be installed with the corresponding alternate
- device. In order to avoid deadlocks, it is recommended that the locks
- are acquired in the following order, and released in the reverse:
- 安裝一個例如/dev/modem的連接來指向串口是常見的作法。
- 爲了確保適當鎖定在這些環節的存在,建議軟件追蹤符號並鎖定全部可能的名字;
- 此外,建議爲相應的備用設備安裝一個鎖文件。
- 爲了不死鎖,建議按如下順序獲取鎖,並按反向的順序釋放:
- 1. The symbolic link name, if any (/var/lock/LCK..modem)
- 2. The "tty" name (/var/lock/LCK..ttyS2)
- 3. The alternate device name (/var/lock/LCK..cua2)
- 一、符號連接名,若是有(/var/lock/LCK..modem)
- 二、「tty」名(/var/lock/LCK..ttyS2)
- 三、備用設備名(/var/lock/LCK..cua2)
- In the case of nested symbolic links, the lock files should be
- installed in the order the symlinks are resolved.
- 在符號連接嵌套的狀況下,鎖定文件應按照符號連接的順序來安裝以解決問題。
- Under no circumstances should an application hold a lock while waiting
- for another to be released. In addition, applications which attempt
- to create lock files for the corresponding alternate device names
- should take into account the possibility of being used on a non-serial
- port TTY, for which no alternate device would exist.
- 在任何狀況下,應用程序應該等待另外一個程序釋放鎖後,持有這個鎖。
- 此外,試圖爲相應的備用設備名建立鎖文件的應用程序應考慮被用於非串口的TTY端口的可能性,此時沒有備用設備存在。
- Pseudoterminals (PTYs)
- 僞終端(PTYs)
- Pseudoterminals, or PTYs, are used to create login sessions or provide
- other capabilities requiring a TTY line discipline (including SLIP or
- PPP capability) to arbitrary data-generation processes. Each PTY has
- a master side, named /dev/pty[p-za-e][0-9a-f], and a slave side, named
- /dev/tty[p-za-e][0-9a-f]. The kernel arbitrates the use of PTYs by
- allowing each master side to be opened only once.
- 僞終端(或PTYs)用於建立登陸會話或提供給其餘須要tty線路規程(包括SLIP或PPP能力)能力以生成數據的進程。
- 每一個PTY有一個主端(/dev/pty[p-za-e][0-9a-f])和一個從端(/dev/tty[p-za-e][0-9a-f])。
- 內核經過只容許每一個主端僅容許打開一次來仲裁PTY的使用。
- Once the master side has been opened, the corresponding slave device
- can be used in the same manner as any TTY device. The master and
- slave devices are connected by the kernel, generating the equivalent
- of a bidirectional pipe with TTY capabilities.
- 一旦主端被打開,相應的從設備能夠像任何TTY設備同樣的方式被使用。
- 主從設備都和內核鏈接,產生至關於一個帶TTY功能的雙向管道。
- Recent versions of the Linux kernels and GNU libc contain support for
- the System V/Unix98 naming scheme for PTYs, which assigns a common
- device, /dev/ptmx, to all the masters (opening it will automatically
- give you a previously unassigned PTY) and a subdirectory, /dev/pts,
- for the slaves; the slaves are named with decimal integers (/dev/pts/#
- in our notation). This removes the problem of exhausting the
- namespace and enables the kernel to automatically create the device
- nodes for the slaves on demand using the "devpts" filesystem.
- Linux內核的最近版本和GNU庫包含了對於System V和Unix98對PTY命名方式的支持。
- 它分配一個共用的設備(/dev/ptmx)給全部的主端(打開它會自動給你一個之前未分配的PTY)和一個子目錄(/dev/pts)用於從端;從端經過十進制整數(/dev/pts/#)命名。
- 這消除了命名空間枯竭的問題,並使內核經過「devpts」文件系統按需自動爲從端動建立設備節點。
對於TTY系統的理解(圖解):

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
推薦閱讀:《Linux C編程一站式學習》----第 34 章 終端、做業控制與守護進程---1. 終端
wiki百科關於終端的網頁:Computer terminal | System console | Linux console
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以上是我參考了網上的資料後對tty的認識整理,參考資料以下:
linux tty pty pts 概念 區別
終端 /dev/console /dev/tty tty
終端tty、虛擬控制檯、FrameBuffer的切換過程詳解
LINUX下的tty,console與串口分析
linux下tty,控制檯,虛擬終端,串口,console(控制檯終端)詳解
LINXU下的TTY、CONSOLE、串口
Linux下的console和terminal