TTY体系中设备节点的差别--- (二)
文章代码分析基于linux-5.19.13,架构基于aarch64(ARM64)。
1. 容易混淆的设备节点和专业术语
1.1 TTY/Terminal/Console/UART
术语 | 含义 |
---|---|
TTY | 来自teletype,最古老的输入输出设备,现在用来表示内核的一套驱动系统 |
Terminal | 终端,暗含远端之意,也是一个输入输出设备,可能是真实设备,也可能是虚拟设备 |
Console | 控制台,含控制之意,也是一种Terminal,权限更大,可以查看内核打印信息 |
UART | 串口,它的驱动程序包含在TTY驱动体系之内 |
1.2 /dev/ttyS0、/dev/ttySAC0、/dev/tty、/dev/tty0、/dev/tty1、/dev/console**
设备节点 | 含义 |
---|---|
/dev/ttyS0、/dev/ttySAC0、/dev/ttySAC0 | 串口 |
/dev/tty1、/dev/tty2、/dev/tty3、…… | 虚拟终端设备节点 |
/dev/tty0 | 前台终端 |
/dev/tty | 程序自己的终端,可能是串口、也可能是虚拟终端 |
/dev/console | 控制台,内核的cmdline参数确定 |
/dev/ptmx和/dev/pts0、/dev/pts1、…… | ptmx与pts配合实现pty(伪终端) |
1.3 虚拟终端和伪终端的区别
都是计算机终端的一种形式,但它们在实现方式和应用场景上存在一些区别。
(1)虚拟终端是指在计算机操作系统中通过软件模拟出来的终端,它们在物理机上使用软件虚拟出来,而不是通过硬件实现。例如,Linux系统中默认有7个虚拟终端(其中,第1至6个虚拟终端重视字符界面,而第7个虚拟终端则总是图形化用户界面,并且必须在启动图形化用户界面后才存在),可以使用快捷键(Ctrl + Alt + F1~F6)切换。虚拟终端使用tty(teletypewriter)显示,它的数量是有限制的。
(2)伪终端则是另一种概念,它也被称作为终端模拟器,一般是指在操作系统上运行的一个应用程序,用来模拟建立一个“输入和输出的功能界面”。伪终端使用pts(pseudo-terminal slave)来表示。它常用于在图形界面下打开的命令行接口,或者通过SSH或者Telnet远程连接Linux系统等场景。伪终端的数量是不受限的。
1. devpts文件系统
devpts文件系统(Device Pseudo Terminal Slave)为伪终端提供了一个标准接口,它的标准挂接点是/dev/pts。只要pty的主复合设备/dev/ptmx被打开,就会在/dev/pts下动态的创建一个新的pty设备文件。挂接时,UID、GID及其工作模式会指定给devpts文件系统的所有pty文件,这样可以保证伪终端的安全性。
2. linux支持的两种pty
- UNIX98 pseudoterminal,使用的是devpts文件系统,挂载在/dev /pts目录
- 在UNIX98 pseudoterminal之前,master pseudoterminal名字为/dev/ptyp0,…,slave pseudoterminal名字为/dev/ttyp0,…,这个方法需要预先分配好很多的设备节点。
3. /dev/ptmx与/dev/pts/0 、/dev/pts/1 、...的关系
只有在open /dev/ptmx程序不退出的情况下,/dev/pts/目录下才会有对应的设备节点
在程序执行"open /dev/ptmx"的时候会在/dev/pts/目录下生成一个设备节点,比如0,1…,但是当程序退出的时候这个设备节点就消失了。
可以通过如下一个例子演示在"open /dev/ptmx"的时候在/dev/pts目录下生成的设备节点:
4. 伪终端详解
Linux35_TTY和伪终端
5. 使用SSH登录
当有ssh客户端连接后,sshd会fork一个进程,然后在子进程中打开一个叫做/dev/pts/1(或者2,3,4,5…)的设备,然后和sshd进程的/dev/ptmx配对,这样在ptmx与pts之间就构成了一条管道,数据可以顺利被导入到sshd,然后通过TCP/IP封装发往ssh client所在的机器
备注:上图摘自参考文档:彻底理解Linux的各种终端类型以及概念
2. 各类设备节点的差别详解
2.1 TTY子系统架构
由于历史原因,下图中两条红线之内的代码被称为TTY子系统。它既支持UART,也支持键盘、显示器,还支持更复杂的功能(比如伪终端)。
2.2 /dev/ttyN(N=1,2,3,...)
/dev/tty[0-N]只是一个虚拟控制台,如果您运行的是N代表TTY号码的 GUI 系统,您可以从主终端切换到它。默认情况下,/dev/tty0是默认的虚拟控制台。/dev/ttyN(N=1,2,3,...):表示某个程序使用的虚拟终端
// 在tty2、tty3终端来回切换(UBUNTUN系统上),执行命令
echo msg_to_tty2 > /dev/tty2
echo msg_to_tty3 > /dev/tty3
2.3 /dev/tty0
/dev/tty0:表示前台程序的虚拟终端。由于我的开发板暂时不支持GUI,因此只能在UBUNTUN系统上测试:
-
你正在操作的界面,就是前台程序
-
其他后台程序访问/dev/tty0的话,就是访问前台程序的终端,切换前台程序时,/dev/tty0是变化的
// 1. 在tty2终端执行如下命令 // 2. 然后在tty2、tty3来回切换 while [ 1 ]; do echo msg_from_tty2 > /dev/tty0; sleep 5; done
2.4 /dev/tty
/dev/tty表示本程序的终端,可能是虚拟终端,也可能是真实的终端。
程序A在前台、后台间切换时,它自己的/dev/tty都不会变。
// 1. 在tty2终端执行如下命令
// 2. 然后在tty2、tty3来回切换
while [ 1 ]; do echo msg_from_tty2 > /dev/tty; sleep 5; done
2.5 Terminal和Console的差别
Terminal含有远端的意思,中文为:终端。Console翻译为控制台,可以理解为权限更大、能查看更多信息。
比如我们可以在Console上看到内核的打印信息,从这个角度上看:
- Console是某一个Terminal
- Terminal并不都是Console。
- 我们可以从多个Terminal中选择某一个作为Console
- 很多时候,两个概念混用,并无明确的、官方的定义
2.6 /dev/console
选哪个?内核的打印信息从哪个设备上显示出来?
可以通过内核的cmdline来指定,
比如: console=ttyS0 console=tty
我不想去分辨这个设备是串口还是虚拟终端,
有没有办法得到这个设备?
有!通过/dev/console!
console=ttyS0时:/dev/console就是ttyS0
console=tty时:/dev/console就是本程序的虚拟终端
console=tty0时:/dev/console就是前台程序的虚拟终端
console=ttyN时:/dev/console就是/dev/ttyN
console有多个取值时,使用最后一个取值来判断
参考文档
本文来自博客园,作者:BSP-路人甲,转载请注明原文链接:https://www.cnblogs.com/jianhua1992/p/17698231.html,并保留此段声明,否则保留追究法律责任的权利。