从 TTY 到 PTY,程序的输入、输出与控制

TTY 设备在 Linux 系统中的应用比较广泛,但很少有人去深度探讨 TTY 设备在整个 Linux 系统交互中起到的关键性作用。本文整合了几篇较为经典的文章对 TTY 设备整体工作原理、机制及应用的探讨,希望能够为读者带来帮助。 从功能性的角度看 其实,从功能性的角度来看,Linux 的 TTY 设备就是受操作系统管理的双向管道,用户通过外设(一般是键盘)输入的数据会进入到 TTY 设备文件,经过终端驱动,传递给操作系统进行处理,操作系统输出到 TTY 设备的数据则会被输出到外设(一般是屏幕),让用户能够看见,本质上就是一个从外设到操作系统的双向管道。 PTY 和 TTY 在功能上是一致的,不过它可以被用户进程创建。用户进程可以通过 Linux 系统提供的接口创建一个 PTS Pair,一个 PTS Pair 分为 Master 设备和 Slave 设备两种,输出到 Master 设备的数据会被传递到 Slave 设备的输入,而输出到 Slave 设备的数据会被传递到 Master 设备的输入。如果我们将显示器绑定到 Master 设备的输出上面,再将键盘绑定到 Master 设备的输入上面,那么我们就能够通过 Master 设备间接操作绑定到 Slave 设备的进程了。因为 PTY 和 TTY 本身并没有太大的差别,为避免过于啰嗦,在下面我只针对 PTY 进行讲述。 一个例子:SSH SSH 的设计中也使用了 PTY 设备,我们在通过 SSH 登入主机进入 Shell 后,可以通过 tty 命令去获取当前的 Shell 进程运行在哪个 PTY 上面。 上面tty命令给出的结果/dev/pts/dev是当前运行的 Shell 绑定的 PTY Slave 设备,而对应的 Master 设备文件描述符只有通过 /dev/ptmx创建 PTY Pair 的进程持有,都指向/dev/ptmx,可以通过sudo lsof /dev/ptmx查看。我们在使用 SSH 的时候,本地的 Terminal Emulator 将输入的字符发送到 SSH 进程,SSH 进程收到字符以后通过网络传输给服务器上面的 SSHD 进程,SSHD 进程将字符写入到 Master 设备,Shell 就能够从 Slave 设备中读取到字符。同理,Shell 的输出写入到 Slave 设备,被 SSHD 从 Master 设备处读取,通过网络传递给 SSH 客户端,最终 SSH 客户端将字符显示到屏幕上(当然,一般我们都是在 Terminal Emulator 里面运行的 SSH 进程,所以本地的 SSH 进程也是要通过 TTY 设备和键盘以及屏幕通讯的,这里图方便就没有画出来,大概样子和图 1 差不多)。...

March 3, 2023 · 3 min · H1R4

Netlink 笔记

在用户空间的程序有的时候可能需要和内核进行消息交互,内核需要提供一种机制来满足用户空间程序的这一需求。虽然系统调用确实提供了一个用户空间程序和内核的交互机制,但是系统调用在一些轻量级的交互上未免显得过于重量级。为此,Linux 内核在用于请求特定信息的经典系统调用以外,还提供了另外的几种用户空间和内核的通信接口,分别是procfs,sysctl,sysfs,ioctl以及 netlink 套接字。procfs和sysfs都是虚拟文件系统,这一部分暂且不提,sysctl对应的是/proc/sys文件,实际上是一个内核变量,这一部分也不在这里详谈,ioctl则是在设备控制上做的工作,细说起来估计也能单开一篇文章了。本文主要还是对 Netlink 的机制做一个简单的概括与总结。 Netlink 是什么?为什么是 Netlink? 按书里的描述总结来看,Netlink 是一个允许内核内部以及内核与用户空间的程序相互进行通信的消息传输机制,是对标准套接字实现的拓展。在 Netlink 诞生之前,一般使用 procfs、sysfs 和 ioctl 来进行内核和用户空间程序之间的数据交互。相比其他机制,Netlink 具有一些更明显的优势: 任何一方都不需要轮询,像 procfs 和 sysfs 这类利用文件进行信息传递的机制,用户空间程序需要不断轮询文件来及时获取信息的更新。 系统调用和 ioctl 也能够从用户空间向内核传递信息,但是相比 Netlink 更难以实现。另外,使用 Netlink 不会与其他的内核模块产生冲突,但模块和系统调用显然配合得不是很好。(这里是《深入 Linux 内核架构》的原话,不过我还不是很理解) 内核可以直接向用户层发送信息,而不需要用户空间程序事先向内核请求。这一点使用文件也能做到,但是系统调用和 ioctl 显然不能够做到。 用户只需要使用标准的套接字和内核进行交互。 内核不仅支持单播消息,也支持多播,并且 Netlink 的工作方式是异步的。Netlink(3) 和 Netlink(7) 两个手册页提供了 Netlink 机制的文档,其中 netlink(3) 描述了内核中用于操作、访问、创建 Netlink 数据报的宏。手册页 netlink(7) 包含了有关 Netlink 套接字的一般性信息,并给出了这里其的数据结构的文档。另外,/proc/net/netlink里面包含了关于当前活动的 Netlink 连接的一些信息。 Netlink 是怎么工作的? 从创建说起 从用户空间程序来看,Netlink 和普通的 BSD 套接字长得很像。在创建 Netlink 套接字的时候,也需要用socket()函数创建一个 socket 描述符,再为其分配一个地址。创建 Netlink 套接字的时候,需要指定 family 为AF_NETLINK,而 type 既可以指定为SOCK_RAW,也可以是SOCK_DGRAM,最终创建的都是一个netlink_sock对象。至于 protocol,根据该 Netlink 套接字的用途,有不同的选择,具体可以看《深入 Linux 内核架构》第 650 页或者是 Netlink 的手册。...

December 12, 2022 · 2 min · H1R4

《Linux 内核设计的艺术》第一部分笔记

前言 最近粗略拜读了朋友推荐的《Linux 内核设计的艺术》这本书。不过相比于 Linux 内核设计的艺术,我从这本书中获得的最大启发其实是 Linux 启动的流程。尽管这本书中的 Linux 版本比较古早,和现行的 Linux 发行版的启动方式大相径庭,不过也从一个更底层的角度向我展示了整个操作系统的引导流程,不管是 I/O 子系统还是中断子系统,也让我对内核的工作方式和存在结构有了全新的认识。遗憾的是,我的这些问题,如果早点读到《操作系统真象还原》这本书的话,可能能得到更好的解答(当然,《操作系统真象还原》这本书讲的并不是 Linux,而是 x86 体系上的通用操作系统概念)。下文的讲述将可能引用《操作系统真象还原》这本书的内容,简洁起见(省得打字),下面将《操作系统真象还原》简称为《真象》,而《Linux 内核设计的艺术》简称为《艺术》。 第一行指令 在先前的计算机组成课中,我了解到了指令在系统中是如何流转的,但这种就是一个比较底层的视角,我还是没能计算机组成与操作系统这两门课很好地结合到一起。这本书与其他讲述 Linux 内核的书籍不同之处在于,不是一上来就基于代码模块对整个 Linux 内核进行分块的剖析,而是从按下开机键上电到 Linux 启动完毕的流程娓娓道来,这正是我所欠缺的,将操作系统与计算机组成统一起来的视角。 指令从何而来? 计算机的心脏,CPU,从上电那一刻起就在不停地搏动。那么第一下搏动从何而来呢?每条指令需要在 CPU 上执行,才能产生效果,因此触发第一条指令执行的,必定不是某一条指令,而是只有不需要前置条件,上电即可触发的硬件。在 Intel 8086 CPU 架构中,上电之后 CPU 的 CS:IP 会被指向地址0xFFFF0,这个地址下会有一条指令,跳转到 BIOS 程序的真正入口点。那么问题又来了,这第一条指令又是从哪里来的呢? 这个点在《真象》里面是这么解释的。在 I/O 子系统中,我们曾经学过一种 CPU 的 I/O 方式,即内存映射 IO,内存映射 I/O 通过将外设于一块特别的内存区域绑定到一块,这样指令可以直接通过访问那块区域的内存来读写外设上面的数据。在 CPU 能够访问到的地址空间里面,我们可以将一部分地址空间用于 I/O,剩下的内存地址空间再绑定到物理内存上面。因为 BIOS 是计算机上面执行的第一行指令,所以 BIOS 必定是由硬件加载的,而这里的硬件,就是 ROM。ROM 也是一块内存,不过这块内存是非易失性的,这块内存的地址空间被硬件映射到内存地址空间0xF0000~0xFFFFF处,因此,当我们访问这块地址的时候,实际上我们是在访问 ROM 中的内容,就不会有加载的问题。 BIOS 的工作是什么? 当 BIOS 的第一行指令开始上 CPU 执行后,BIOS 的指令就会被源源不断地读进 CPU 并执行了。现在 CPU 正处于一个叫做实模式的状态下。为什么会是这个模式,以及实模式和保护模式的区别将在后续的内容中讲到,这里只需要注意,实模式下的访存方式,和我们在计算机组成里面学到的访存机制基本一致,是直接将 CS:IP 的值组装成地址之后通过地址总线访问,不需要额外的转换工作。Intel 8086 留给实模式的地址线只有 20 根,所以只能够访问到 1MB 的内存。随着 BIOS 的指令执行,它会检查所有外设的状态信息,如果没有检测到错误,那么下一步,就要开始准备中断向量表和中断服务程序,为下面的操作系统引导铺路。...

December 10, 2022 · 2 min · H1R4