LinuxTTY 子系统2

LinuxTTY 子系统2(基于Linux6.6)---tty架构

一、 软件架构

Linux kernel TTY framework位于“drivers/tty”目录中,其软件框架如下所示:

Linux其它的framework类似,TTY framework通过TTY core屏蔽TTY有关的技术细节,对上以字符设备的形式向应用程序提供统一接口,对下以TTY device/TTY driver的形式提供驱动程序的编写框架。

1.1、TTY Core

TTY core是TTY framework的核心逻辑,功能包括:

1)以字符设备的形式,向用户空间提供访问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转串口终端
…                         …                                             …

2)通过设备模型中的struct device结构抽象TTY设备,并通过struct tty_driver抽象该设备的驱动,并提供相应的register接口。TTY驱动程序的编写,简化为填充并注册相应的struct tty_driver结构。

注2:TTY framework弱化了TTY设备(图片1中使用虚线框标注)的概念,通常情况下,可以在注册TTY驱动的时候,自动分配并注册TTY设备。

3)使用struct tty_struct、struct tty_port等数据结构,从逻辑上抽象TTY设备及其“组件”,以实现硬件无关的逻辑。

4)抽象出名称为线路规程(Line Disciplines)的模块,在向TTY硬件发送数据之前,以及从TTY设备接收数据之后,进行相应的处理(如特殊字符的转换等)。

1.2 System Console Core

在 Linux 内核中,system console(系统控制台)主要有两个功能:

1. 显示内核信息

系统控制台用于输出内核启动过程中的各种信息。具体来说,当 Linux 内核启动时,会将内核的日志信息(包括启动时的初始化过程、驱动加载、硬件检测等)打印到控制台设备上。这些信息对调试和系统诊断非常重要。

  • 启动信息:系统控制台会显示内核引导信息,例如内核版本、硬件信息、磁盘驱动加载情况、网络接口配置等。
  • 错误信息:当系统发生错误或崩溃时,系统控制台也会显示相关的错误信息,帮助系统管理员进行问题定位。例如,如果发生内核恐慌(Kernel Panic),错误信息会被打印到控制台。

通过控制台输出,管理员可以在没有图形界面的情况下,看到系统的运行状态和错误日志。通常,内核会通过虚拟终端(如 /dev/tty0)或者串行端口(如 /dev/ttyS0)来输出这些信息。

2. 与用户进行交互

系统控制台还可以作为一个与内核交互的接口,允许系统管理员在系统出现问题时执行一些紧急操作或修复。例如:

  • 中断控制台操作:在某些情况下,内核可能会通过控制台显示一个提示信息,等待用户的输入(例如,在发生严重错误时)。管理员可以使用控制台来输入调试命令或选择恢复操作。

  • 远程控制台管理:在服务器和嵌入式系统中,系统控制台还可以通过串口或网络进行远程管理(如通过 SSH 登录或串行控制台进行交互)。通过远程控制台,管理员可以在系统无法正常启动时(比如没有图形界面)访问并诊断系统。

1.3 TTY Line Disciplines

TTY Line Discipline 的基本概念

TTY Line Discipline(简称 LDISC)可以理解为一组负责终端数据处理和流控制的内核模块。每个终端设备(如 /dev/tty/dev/pts 等)都与一个 TTY Line Discipline 相关联,用于执行对终端数据的操作,包括输入、输出、特殊字符处理等。

在 Linux 中,TTY Line Discipline 可以理解为类似于驱动程序的功能模块,每个终端设备都有一个 LDISC 模块来定义其行为。

主要的 TTY Line Disciplines

Linux 内核中有多种 TTY Line Discipline,用于处理不同类型的终端或特定场景的需求。最常见的 TTY Line Discipline 包括:

1. 标准行规程(canonical line discipline, LDISC 0)

这是最常见的 LDISC 类型,也叫“标准行规程”或“规范模式”。它负责处理常规的字符输入输出操作,通常用于终端(tty)设备的基本交互。

  • 特点

    • 输入的字符会缓存在内核缓冲区中,直到用户按下回车键(或特定的终止符)后,输入的字符才会传送给应用程序。
    • 支持 行编辑特殊字符(如删除、换行、回退等)的处理。
    • 实现对字符的 输入模式设置控制字符解释(例如控制字符 Ctrl+C 发送 SIGINTCtrl+Z 发送 SIGTSTP)。
  • 用途

    • 用于标准的终端或控制台。
    • 支持交互式应用程序(如命令行交互)在标准输入输出上的操作。

2. 非规范行规程(non-canonical line discipline, LDISC 1)

与标准行规程不同,非规范行规程通常用于处理流式数据,如串行端口通信或管道中的数据。

  • 特点

    • 在非规范模式下,输入的数据不需要等待回车键,数据一旦输入就会立即传输给应用程序。
    • 数据是流式的,每个字符的输入都立即可见,不进行缓冲。
    • 通常用于实时应用,如串行通信,或者某些高性能的数据流应用。
  • 用途

    • 串行设备通信(如 /dev/ttyS0)。
    • 需要高效数据流处理的场景。

3. 伪终端行规程(pseudo-terminal line discipline, LDISC 2)

伪终端行规程主要用于处理伪终端设备,通常与图形终端仿真(如 X 终端或虚拟终端)相关。

  • 特点

    • 它允许通过伪终端设备来模拟终端交互,包括从控制台发送和接收数据。
    • 通常与图形界面的 xtermgnome-terminal 或通过 SSH 建立的远程会话等虚拟终端相关联。
  • 用途

    • 用于虚拟终端和伪终端设备(如 /dev/pts)的管理。
    • 支持图形终端和多用户会话。

4. 串行通信行规程(serial line discipline, LDISC 3)

这是一个用于串行设备的特殊行规程,通常与串行通信(如串行端口、调制解调器)相关。

  • 特点

    • 支持串行端口设备的流控制(如 XON/XOFF、RTS/CTS)和特殊字符处理。
    • 在串行通信中,对数据的流量控制、错误检测和恢复等操作至关重要。
  • 用途

    • 串口通信(如 /dev/ttyS0)。
    • 调制解调器、嵌入式系统的串行端口通信。

5. 网络行规程(network line discipline, LDISC 4)

网络行规程通常用于处理通过网络连接的终端设备,尤其是在需要网络通信时。

  • 特点

    • 实现与网络相关的特定数据传输和协议处理功能。
    • 常见的应用场景包括使用 PPP(点对点协议)或 SLIP(串行线路互联网协议)连接。
  • 用途

    • 支持远程网络设备的输入输出。
    • 用于虚拟终端和网络终端之间的数据交换。

Line Discipline 的工作原理

每个 TTY 设备都有一个关联的 Line Discipline,负责处理对终端设备的输入输出操作。在终端设备的整个数据流过程中,Line Discipline 通过一系列的输入处理和输出处理步骤来控制数据的传输行为。

1. 输入处理

当数据输入到终端设备时,Line Discipline 会根据其类型对数据进行相应的处理:

  • 规范模式 下,输入的字符会缓存在内核的输入缓冲区,直到特定的字符(如换行符)出现时,输入的完整行才会交给应用程序。
  • 非规范模式 下,字符立即被传输到应用程序,不进行缓冲。

2. 输出处理

Line Discipline 也负责控制从内核输出到终端设备的数据:

  • 规范模式:当数据传递给应用程序时,它会自动进行行编辑和控制字符的处理。
  • 非规范模式:数据会原样发送到终端设备,适用于实时流数据。

3. 控制字符的处理

Line Discipline 还需要处理控制字符,如:

  • Ctrl+C 中断当前操作(发送 SIGINT)。
  • Ctrl+Z 挂起当前进程(发送 SIGTSTP)。
  • Ctrl+D 表示输入结束(发送 EOF)。

如何管理 Line Discipline

在 Linux 中,Line Discipline 通过 /dev/tty 设备节点与内核进行交互。管理员可以通过以下命令管理和查看当前的 Line Discipline 配置:

  • 查看当前终端的 Line Discipline

  • cat /proc/tty/driver/serial
    
  • 更改 Line Discipline: 可以使用 stty 命令来配置终端的行为,虽然 stty 本身不能直接更改 Line Discipline,但它会影响终端的输入输出模式。 

1.4 TTY Drivers以及System Console Drivers

最后,对内核以及驱动工程师来说,更关注的还是具体的TTY设备驱动。在kernel为我们搭建的如此beauty的框架下面,编写相应的driver就成为一件比较简单的事情了。当然的kernel中,主要的TTY driver有两类:

1. 字符设备驱动(Character Device Driver)

字符设备驱动主要负责管理和操作终端设备(如 /dev/tty/dev/ttyS0 等)。这些设备主要处理字节流数据,一次处理一个字符。它们包括本地终端、串行端口设备、伪终端等。

主要功能:

  • 管理字符输入输出。
  • 支持流控制、特殊字符处理等。
  • 提供基本的输入输出机制(如读写操作)。
  • 实现与内核的字符流交互。

常见的字符设备:

  • 本地终端设备(TTY):包括控制台、虚拟终端(/dev/tty1, /dev/tty2, /dev/ttyS0等)。
  • 串行端口设备:如 /dev/ttyS0,用于串行通信。
  • 伪终端设备:如 /dev/pts/0,用于虚拟终端的连接(如 X 终端和 SSH 会话)。

关键组件:

  • tty驱动(tty driver):实现与硬件设备的交互,包括读写字符的操作。
  • line discipline(LDISC):控制字符输入输出的行为,如规范模式或非规范模式。
  • tty层(TTY layer):负责管理所有的终端设备,协调驱动与应用程序之间的通信。

2. 控制台驱动(Console Driver)

控制台驱动是用于处理终端显示的驱动程序,通常与显示设备(如图形界面控制台或虚拟控制台)相关联。它管理用户与操作系统的交互,输出内核信息,并提供一个基本的界面来显示信息。

主要功能:

  • 管理显示输出(如文本输出、日志信息)。
  • 提供一个基本的用户交互界面(如 Ctrl+Alt+F1 切换虚拟控制台)。
  • 支持文本模式的输入输出。

常见的控制台驱动:

  • 本地控制台(如 /dev/console):通常是与物理显示器和键盘连接的终端设备,用于显示启动信息、内核日志以及与系统交互。
  • 虚拟控制台:如 /dev/tty1, /dev/tty2 等,用于多用户环境下的多终端管理。
  • 帧缓冲控制台(Framebuffer Console):支持图形模式的控制台,可以显示图形和文本。

关键组件:

  • console driver:实现控制台的输出和输入处理,控制字符的显示格式以及输入的处理。
  • framebuffer:提供图形界面的显示支持,允许在控制台上显示图像、字体等。

二、总结

Linux TTY 框架是一个高度模块化的软件架构,负责管理所有与终端相关的操作。TTY(TeleTYpewriter)最初是为字符终端(例如早期的电传打字机)设计的,但随着时间推移,它变得更加通用,支持多种终端类型,如虚拟终端、串行端口、伪终端等。TTY 框架的设计旨在抽象化硬件细节,提供一个一致的接口,允许用户和应用程序与终端设备交互。

2.1、TTY 框架的核心概念

TTY 框架的核心概念主要包括以下几个组成部分:

  • TTY设备:表示一个终端设备,可以是本地物理终端、虚拟终端或串行设备。
  • TTY驱动:负责与硬件或虚拟终端的通信。
  • Line Discipline(LDISC):终端的行级协议,处理输入输出流,支持终端控制(如回显、行模式)。
  • 字符设备接口:TTY设备是字符设备,提供了标准的文件操作接口(如 readwriteioctl)。
  • 控制台驱动:提供与内核的交互界面,通常与屏幕输出和用户输入相关。
  • 虚拟控制台(VC):虚拟终端是 Linux 系统支持的多个并行终端,允许用户通过多个会话同时操作系统。

2.2、TTY 框架的层次结构

TTY 框架可以从以下几个层次来看:

1. TTY 设备层(TTY Device Layer)

  • 这一层表示具体的终端设备,包括串行端口(如 /dev/ttyS0)和虚拟终端(如 /dev/tty1, /dev/pts/0)。每个设备都有一个 struct tty_struct,表示一个终端实例。
  • 这个结构体中保存了终端的状态、缓冲区、设备驱动程序的引用等信息。

关键函数:

  • tty_open(): 打开一个 TTY 设备。
  • tty_read()tty_write():实现读取和写入操作。
  • tty_ioctl():用于处理终端设备特定的控制命令。

2. Line Discipline(LDISC)层

  • Line Discipline 是一个层次化的机制,负责处理输入和输出的行级协议。每个 TTY 设备都可以关联一个 Line Discipline 来处理特定的输入输出流。
  • Line Discipline 的作用包括字符编辑、流控制、特殊字符的处理(如回车、换行、删除键等)。
  • Linux 默认的 Line Discipline 是 N_TTY,但也支持其他协议,如 N_ASKFIRSTN_SLIP

关键函数:

  • ldisc_open(): 打开 Line Discipline。
  • ldisc_receive_buf(): 处理接收到的数据。
  • ldisc_flush(): 清空 Line Discipline 中的数据缓冲区。

3. TTY 驱动层(TTY Driver Layer)

  • TTY 驱动层与硬件或虚拟终端设备进行通信,负责将用户空间的 I/O 请求映射到硬件接口。它包含了各种特定的设备驱动程序,比如串行端口驱动(ttyS 驱动)、虚拟终端驱动(tty 驱动)等。
  • 驱动层的作用是提供对硬件或伪硬件设备的访问,以便从 TTY 设备中读取或写入数据。

关键函数:

  • tty_driver 结构体:定义了设备驱动的操作(如 openclosereadwrite)。
  • tty_insert_flip_char(): 插入一个字符到 TTY 的缓冲区中。
  • tty_flip_buffer_push(): 将缓冲区中的字符推送到用户空间。

4. 控制台驱动层(Console Driver Layer)

  • 控制台驱动用于处理与控制台设备相关的输入输出,特别是在没有图形界面的情况下。
  • 主要负责将内核日志、系统消息显示到用户的控制台,并允许用户与系统进行交互。
  • 控制台驱动通常与虚拟控制台和帧缓冲设备相关联。

关键函数:

  • console_driver 结构体:定义了控制台设备的操作。
  • console_unlock():用来打印信息到控制台。
  • console_init():初始化控制台设备。

5. 伪终端(PTY)层

  • 伪终端是一种特殊的设备,通常用于实现远程会话(如 SSH)或图形化终端(如 X11)。它通过“主/从”终端设备进行通信,其中主设备(/dev/ptmx)负责创建和管理虚拟终端对,而从设备(如 /dev/pts/0)则用于和用户交互。
  • 伪终端的实现通过对 struct tty_struct 进行分配和管理,允许在用户空间和内核空间之间交换数据。

关键函数:

  • pty_open():打开伪终端设备。
  • tty_init():初始化伪终端。

2.3、TTY 框架的主要组件

  • tty_struct:每个 TTY 设备都有一个 struct tty_struct,它包含了终端的状态、输入输出缓冲区、Line Discipline、控制字符等信息。
  • tty_driver:每种终端设备类型(如串行、虚拟、伪终端)都有一个对应的 tty_driver,它定义了对设备的操作函数。
  • console_driver:控制台驱动实现,负责内核信息的显示和用户输入的处理。
  • tty_port:用于串行端口等硬件设备的表示,支持硬件中断和缓冲区的管理。

2.4、TTY 设备的工作流程

  1. 设备初始化:当 TTY 设备被打开时,内核会为每个终端分配一个 tty_struct,并初始化相关的驱动程序、Line Discipline 和缓冲区。
  2. 数据读写:用户通过 readwrite 系统调用与终端交互,内核将用户数据通过 TTY 驱动程序和 Line Discipline 传输到终端。
  3. 输入输出处理:TTY 系统通过行编辑(Line Discipline)处理输入的字符流,进行特殊字符的处理,回显或进行流控制。
  4. 输出到控制台:如果是控制台终端,数据最终将通过控制台驱动显示到屏幕上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值