linux TTY子系统(2) -- 软件框架
linux TTY子系统(2) -- 软件框架
了解tty 子系统
1.TTY的子系统
??在Linux kernel中,TTY就是各类终端(Terminal)的简称。为了简化终端的使用,以及终端驱动程序的编写,Linux kernel抽象出了TTY framework:对上,向应用程序提供使用终端的统一接口;对下,提供编写终端驱动程序(如serial driver)的统一框架。TTY framework通过TTY core屏蔽TTY有关的技术细节,对上以字符设备的形式向应用程序提供统一接口。
??软件框架所示:
1.1.TTY core是TTY framework的核心逻辑,功能包括:
以字符设备的形式,向用户空间提供访问TTY设备的接口,例如:
设备号(主, 次) 字符设备 备注
(5, 0) /dev/tty 控制终端(Controlling Terminal)
(5, 1) /dev/console 控制台终端(Console Terminal)
(4, 0) /dev/vc/0 or /dev/tty0 虚拟终端(Virtual Terminal)
(4, 1) /dev/vc/1 or /dev/tty1 同上
… … …
(x, x) /dev/ttyS0 串口终端(名称和设备号由驱动自行决定)
… … …
(x, x) /dev/ttyUSB0 USB转串口终端
… … …
通过设备模型中的struct device结构抽象TTY设备,并通过struct tty_driver抽象该设备的驱动,并提供相应的register接口。TTY驱动程序的编写,简化为填充并注册相应的struct tty_driver结构。
注:TTY framework弱化了TTY设备的概念,通常情况下,可以在注册TTY驱动的时候,自动分配并注册TTY设备。
使用struct tty_struct、struct tty_port等数据结构,从逻辑上抽象TTY设备及其“组件”,以实现硬件无关的逻辑。
抽象出名称为线路规程(Line Disciplines)的模块,在向TTY硬件发送数据之前,以及从TTY设备接收数据之后,进行相应的处理(如特殊字符的转换等)。
1.2 System Console Core
Linux kernel的system console主要有两个功能:
向系统提供控制台终端(Console Terminal) ,以便让用户登录进行交互操作。
提供printk功能,以便kernel代码进行日志输出。
??System console core模块使用struct console结构抽象system console功能,具体的driver不需要关心console的内部逻辑,填充该接口并注册给kernel即可。
1.3 TTY Line Disciplines
??线路规程(Line Disciplines)在TTY framework中是一个非常优雅的设计,可以把它看成设备驱动和应用接口之间的一个适配层。从字面意思理解,就是辅助TTY driver,将我们通过TTY设备键入的字符转换成一行一行的数据,当然,实际情况远比这复杂,例如存在如下的Line Disciplines(以n_为前缀):
$ ls drivers/tty/n_*
drivers/tty/n_gsm.c drivers/tty/n_r3964.c drivers/tty/n_tracesink.c drivers/tty/n_tty.c
drivers/tty/n_hdlc.c drivers/tty/n_tracerouter.c drivers/tty/n_tracesink.h
1.4 TTY Drivers以及System Console Drivers
??最后,对内核以及驱动工程师来说,更关注的还是具体的TTY设备驱动。主要的TTY driver有两类:
虚拟终端(Virtual Terminal,VT)驱动,位于drivers/tty/vt中,负责实现VT有关的功能。
串口终端驱动,也即serial subsystem,位于drivers/tty/serial中。
2.内部结构
计算机为了支持这些teletype,于是设计了名字叫做TTY的子系统,内部结构如下:
UART driver对接外面的UART设备。
Line discipline主要是对输入和输出做一些处理,可以理解它是TTY driver的一部分。
大多数用户都会在输入时犯错,所以退格键会很有用。这当然可以由应用程序本身来实现,但是根据UNIX设计“哲学”,应用程序应尽可能保持简单。为了方便起见,操作系统提供了一个编辑缓冲区和一些基本的编辑命令(退格,清除单个单词,清除行,重新打印),这些命令在行规范(line discipline)内默认启用。高级应用程序可以通过将行规范设置为原始模式(raw mode)而不是默认的成熟或准则模式(cooked and canonical)来禁用这些功能。大多数交互程序(编辑器,邮件客户端,shell,及所有依赖curses或readline的程序)均以原始模式运行,并自行处理所有的行编辑命令。行规范还包含字符回显和回车换行(译者注:\r\n 和 \n)间自动转换的选项。如果你喜欢,可以把它看作是一个原始的内核级sed(1)。
另外,内核提供了几种不同的行规范。一次只能将其中一个连接到给定的串行设备。行规范的默认规则称为N_TTY(drivers/char/n_tty.c,如果你想继续探索的话)。其他的规则被用于其他目的,例如管理数据包交换(ppp,IrDA,串行鼠标),但这不在本文的讨论范围之内。
TTY driver用来处理各种终端设备。
用户空间的进程通过TTY driver来和终端打交道。
用户可能想要同时运行多个程序,并且一次只与其中一个交互。如果一个程序进入无限循环,用户可能想要终止或挂起它。在后台启动的程序应该能够独立运行,直到它们尝试向终端写入(被挂起)。同样,用户的输入应该指向前台程序。对于这些功能,操作系统是在TTY驱动程序( TTY driver drivers/char/tty_io.c)中实现的。
在操作系统中,如果已经进程有执行上下文,我们就说它是“活着的”(有一个执行上下文),这也意味着它可以独立执行操作。而TTY驱动程序不是“活”的; 在面向对象的术语中,TTY驱动程序是被动对象(passive object)。它有一些数据字段和一些方法,但让它做某事的唯一方法是当它的某个方法从别的进程的上下文或内核中断处理程序中调用时。行规范(line discipline)同样是一个被动对象。
3.TTY设备
??对于每一个终端,TTY driver都会创建一个TTY设备与它对应,如果有多个终端连接过来,那么看起来就是这个样子的:
??当驱动收到一个终端的连接时,就会根据终端的型号和参数创建相应的tty设备(上图中设备名称叫ttyS0是因为大部分终端的连接都是串行连接),由于每个终端可能都不一样,有自己的特殊命令和使用习惯,于是每个tty设备的配置可能都不一样。比如按delete键的时候,有些可能是要删前面的字符,而有些可能是删后面的,如果没配置对,就会导致某些按键不是自己想要的行为,这也是我们在使用模拟终端时,如果默认的配置跟我们的习惯不符,需要做一些个性化配置的原因。
??后来随着计算机的不断发展,teletype这些设备逐渐消失,我们不再需要专门的终端设备了,每个机器都有自己的键盘和显示器,每台机器都可以是其它机器的终端,远程的操作通过ssh来实现,但是内核TTY驱动这一架构没有发生变化,我们想要和系统中的进程进行I/O交互,还是需要通过TTY设备,于是出现了各种终端模拟软件,并且模拟的也是常见的几种终端,如VT100、VT220、XTerm等。
??可以通过命令toe -a列出系统支持的所有终端类型,可以通过命令infocmp来比较两个终端的区别,比如infocmp vt100 vt220将会输出vt100和vt220的区别。
4.程序如何和TTY打交道
??在讨论TTY设备是如何被创建及配置之前,我们先来看看TTY是如何被进程使用的:
#先用tty命令看看当前bash关联到了哪个tty
[email protected]:~$ tty
/dev/pts/1
#看tty都被哪些进程打开了
[email protected]:~$ lsof /dev/pts/1
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 907 dev 0u CHR 136,1 0t0 4 /dev/pts/1
bash 907 dev 1u CHR 136,1 0t0 4 /dev/pts/1
bash 907 dev 2u CHR 136,1 0t0 4 /dev/pts/1
bash 907 dev 255u CHR 136,1 0t0 4 /dev/pts/1
lsof 1118 dev 0u CHR 136,1 0t0 4 /dev/pts/1
lsof 1118 dev 1u CHR 136,1 0t0 4 /dev/pts/1
lsof 1118 dev 2u CHR 136,1 0t0 4 /dev/pts/1
??通过上面的lsof可以看出,当前运行的bash和lsof进程的stdin(0u)、stdout(1u)、stderr(2u)都绑定到了这个TTY上。
linux TTY子系统(2) -- 软件框架相关教程
课程1-3-前后端项目部署到linux服务器上
课程1-3-前后端项目部署到linux服务器上 前后端项目部署到linux服务器上 按下图点击构建后端项目; 找到自己的项目路径,找到打包好的后端jar包; 根据下图构建前端项目; 构建完成,生成的打包文件如下,同样,在电脑中找到该文件; 准备linux服务器,linux
Linux node环境配置
Linux node环境配置 nodejs下载地址http://nodejs.cn/download/ 下载页面中选择Linux二进制文件(x64)鼠标右键复制链接地址 输入命令下载:wget 【复制的链接地址】 解压文件: tar -xvf node-v14.14.0-linux-x64 配置环境变量: vim /etc/profile#在末尾处
Makefile 的使用
Makefile 的使用 在 Linux 中使用 make 命令来编译程序,特别是大程序;而 make 命令所执行的动作依赖于 Makefile 文件。最简单的 Makefile 文件如下: hello: hello.cgcc -o hello hello.cclean:rm -f hello 将上述 4 行存为 Makefile 文件(注意必须以 Tab
QProcess在Linux下双向通信
QProcess在Linux下双向通信 1、父进程 QProcess pro; pro.setReadChannelMode(QProcess::MergedChannels); pro.connect(pro, QProcess::readyRead, []{ QMessageBox::information(0, recv, pro.readAllStandardOutput()); }); pro.start(./testProcess); pro.
linux下如何使用mv命令移动文件到指定目录
linux下使用mv命令移动文件到指定目录的方法:执行【mv source destination】命令即可。源可以是一个或多个文件或目录,目标可以是单个文件或目录。 mv命令(move的简称)用于将文件和目录从一个位置重命名和移动到另一个位置。 (视频教程推荐:linux视频教
LINUX命令行安装DM8数据库
LINUX命令行安装DM8数据库 1.安装前准备工作 在安装DM之前需要检查或修改操作系统的配置,以保证DM正确安装和运行。 包括Linux、AIX、HP-UNIX、Solaris和 FreeBSD 操作系统。以下安装程序说明将以 Red Hat Enterprise Linux 6 for x86-64系统为例,由于不同操
Linux控制台重定向方法及原理
Linux控制台重定向方法及原理 Linux控制台重定向方法 本文介绍一种通过文件描述符重定向终端输入/输出的方法。 一些嵌入式设备,一般都会留有调试串口,经由RS232/485标准与PC的COM口相连,将打印输出在PC上显示,并可以接收PC端的输入,如下图所示: 设备出
Ubuntu linux命令练习1 shell seq rand 格式化
Ubuntu linux命令练习1 shell seq rand 格式化 一些基础命令,以下为方便演示均用shell脚本演示 od #!/bin/bash -vecho -n $IFS | od -cecho -n $IFS | od -b#左侧输出为变量地址(八进制)# -c 选择可打印字符或反斜杠转义# -b 选择八进制字节 type #!/bin/b