本来这篇文章打算写的是kernel 0.12的终端初始化过程,但是奈何对与其有关的字符设备文件比如/dev/tty、/dev/console很不熟悉,并不清楚这些字符设备文件存在的意义;所以本篇文章我们就来简单的介绍一下终端(Terminal)的发展史,顺带再稍微的扩展一下知识面。算是对下面的文章的完善吧:
终端发展史
本小节使用到的参考资料
https://www.zhihu.com/question/20388511
https://www.zhihu.com/question/21711307
https://www.zhihu.com/question/65280843
https://taoshu.in/tty.html
提到终端就不得不提到与其概念相近的控制台(console)了,事实上现在我们经常用这两个概念表示相同的东西,即都是黑色背景下能执行命令的东西:
电影「黑客帝国」剧照
现在的一些数控设备(比如数控机床)的控制箱,通常会被称为控制台:顾名思义,控制台就是一个直接控制设备的面板,上面有很多控制按钮。相应的,在计算机的早期时代这两个概念的确指的是不同的东西,在计算机刚刚诞生的时候,一台电脑的体积非常的大,上面分布着许多的按钮,它们用来”直接控制”主机,这些按钮的集合我们可以称之为控制台(console);一台主机可以支持多个用户同时使用,每个用户使用的设备被称为终端(Terminal),每台终端需要使用物理线缆与控制台相连:
可以将上面这张图抽象为 终端设备 — 物理线缆 — 控制台:
-
注:现在每个人离不开的手机可以被称为移动终端设备。
上图展示了类似于”带有显示器”的终端设备 — 视频显示终端(Video Display Terminal),在它之前采用的是电传打字机(teletype),简称tty:
它的工作原理大致如下面代码框的图所示:
+----------+
+----------+ +-------+ Physical Line +-------+ +------+ | |
| teletype |<->| Modem |<--------------------->| Modem |<->| UART |<->| Computer |
+----------+ +-------+ +-------+ +------+ | |
+----------+
// 注:上图里是"Computer(计算机)"而非"console(控制台)"
简单的说明下:左边的电传打印机连接着”调制解调器”(Modem、Modulator-demodulator的缩写),也就是我们常说的“猫”;UART可以简单的理解为将teletype的信号转换成计算机能识别的信号的设备。下面是电传打印机作为终端的演示视频,附上链接:https://www.youtube.com/watch?v=MikoF6KZjm0;无法科学上网的可以看这个:
当然了,更早的电传打印机在二战之前就已经有了,当时只是单纯的用于传输消息而已,还没有出现控制台(console)这个东西:
1929年的teletype广告
在网上搜索资料的时候猛然发现有一篇文章写的挺好的,在这篇文章中简要的概括了计算机的发展史和硬件的演化,感兴趣可以看看:https://blog.csdn.net/heyc861221/article/details/80129426
Linux下终端核心概念
1.关于RS-232串行接口标准
串行端口(Serial port)简称”串口”,这种物理接口可以实现计算机与各种外围设备(调试解调器、终端、鼠标、键盘、路由器等)进行通信。串行串口与并行端口最大的区别就是后者可以同时传送多个bit位。现在的消费级个人电脑(PC)已经使用USB接口取代了串行端口,但是在自动化工业系统、嵌入式设备中仍然存在。
-
早期的计算机(实体)终端是通过串口RS-232与主机通信的,不过现在大多数已经被虚拟化了。
RS-232是美国电子工业联盟(EIA-Electronic Industry Association)指定的串口数据通信接口标准,该标准的全称为:数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准,它的原始编号为EIA RS-232,其中:
-
RS(Recommended Standard)表示推荐标准
-
232是标识号
-
末尾可以再跟一个字母,字母C表示RS-232的第三次修改(1969年),在这之前还有RS-232B、RS-232A
因为RS-232C的重大影响,目前已几乎不再使用RS-232中规定的25针脚而是使用9针脚,因此现在谈到RS-232时一般指的是RS-232C,如下所示:
25针脚
9针脚
9针脚串行端口注意要和传输视频信号的VGA接口区别开来,这两个长的比较像:
在ebay上仍可搜索到使用这种古老连接方式的鼠标和键盘:
2.关于Linux的字符设备
字符设备(Character Device)是指在I/O传输过程中以字符为单位进行传输的设备,键盘就是个典型的字符设备,它可以很好的说明”流”这种抽象的概念:当我们在键盘上按下一串按键时,数据会以”流”的形式”流动”到计算机中,然后应用数据读取这一串连续的数据流就可以将用户输入的字符显示到屏幕上。还有,Linux将所有连接到计算机的物理设备都映射成设备文件(Device File)来处理,应用程序可以像操作普通文件一样对硬件设备进行操作;根据类别的不同可以将这些设备划分为字符设备、块设备和网络设备三类。
-
Linux下万物皆文件?
ubuntu 18.04中键盘与鼠标的字符设备文件如下所示:
除了键盘与鼠标属于字符设备之外,在稍后篇幅中出现的Linux的tty也属于字符设备,这里就拿tty中的ttyS看下吧:
主设备号与次设备号在bootsect.S一文中有所说明,如下图所示:
主设备号、次设备号的概念
若只需要查看系统中存在的主设备号和与之对应的设备文件,执行cat /proc/devices即可:
3.终端驱动程序的3种模式的展示
要让终端正常工作就离不开终端驱动程序。在kernel 0.12中,相关程序包括终端输入输出程序tty_io.c和终端控制程序tty_ioctl.c。终端驱动程序用于控制终端设备,在终端设备和进程之间传输数据,并对所传输的数据进行一定的处理。用户在键盘上键入的原始数据(Raw data)在通过终端程序处理后,被传送到相应的进程;而进程向终端发送的数据,在终端程序处理后会被显示在终端屏幕上或者通过串行线路被发送到远程终端。
从上面这一段话可以看出,这里终端(Terminal)这个概念不再是之前的(图1),而是逐渐演化为具有更强能力和功能的软件仿真黑框框界面(图2):
物理终端(图1)
软件仿真终端(图2)
-
文章后面提到的终端均指”软件仿真的终端”。
终端的工作方式有3种模式 — 规范(canonical)模式、非规范(non-canonical)模式和原始(raw)模式。当使用前者时经过终端驱动程序的数据将被进行变换处理,然后再送出;例如把TAB字符扩展为8个空格字符, 用键入的删除字符(backspace)控制删除前面键入的字符等,此时使用的处理函数一般称为行规则(line discipline)或行规程模块。当使用后者时行规则程序仅在终端与进程之间传送数据,而不对数据进行规范模式的变换处理。(– 来自《Linux内核完全注释》)
注意:
-
原始(raw)模式是一种特殊的非规范模式。
-
有的环境下tab等于8个空格,也有的环境下tab等于4个空格,甚至不同的编译器也有所不同。
此篇文章我们就从表象看起吧(不深究其中的实现和原理)。在ubuntu 18.04下执行stty -a:
看到上图绿框中的icanon了吗?这个flag标志着canonical规范模式的开启,即icanon表示当前终端窗口使用的是规范模式。紧接着执行cat命令,输入cyberangel:
嘶~,多打了一个l,我们可以按下键盘上的Backspace(退格键)消除掉多打的”l”。下面执行stty -icanon以启用非规范模式(该设置仅在当前终端窗口生效):
执行cat,依次输入cyberangel这10个字母:
可以发现字符都双写了,此时按下退格键会发现不起作用:
规范模式和非规范模式的差距不止这一种,由于篇幅限制,这里就不在说了,多余的内容放到下一篇来讲。
-
补充:stty -echo会导致用户在输入时不会回显(也就是不能在屏幕上看到输入的内容)。
除了在现代Linux中执行stty,kernel 0.12也可:
与ubuntu 18.04的表现略有不同,kernel 0.12是可以使用退格键消除字符的,具体的实现细节我放在后面的源码篇幅再讲。
4.Linux的console、tty、pts、ptmx、Terminal
由于历史的原因,现在”tty”这个名词不再指明一个具体的事物,在Linux中tty变为了一个抽象的字符设备:有时它指的是一个物理输入设备(如:前面说的串行端口),有时它指的是一个允许用户和系统交互的虚拟终端(Virtual Terminal)。但是字符设备文件/dev/ttyN与/dev/tty只是表示虚拟终端。
-
下面讲述的知识可能在不同linux发行版下表现有所差异,甚至包括同一版本下纯命令行版本与桌面版本都有差异,演示的桌面版本为ubuntu 18.04。
1、关于控制台console与终端Terminal
如果现在我们在ubuntu 18.04打开一个终端,即鼠标右键后点击“Open Terminal”就会出现一个黑框框的东西(当然在ubuntu下可能不能称作黑框框,而是叫深红色的框框,哈哈):
现在所说的终端(Terminal)是由软件模拟的,换句话说就是终端模拟器(Terminal Emulator、或终端仿真器)【如上图所示】。随着计算机的发展已经见不到专门的终端硬件了,但是由于人们的习惯性称呼,现在仍然会将终端模拟器称之为(或简称为)“终端”,可以使用命令toe -a查看系统支持的终端类型:
可以通过命令infocmp来比较两个终端的区别,比如infocmp vt100 vt220将会输出vt100和vt220的区别:
哦↗,终端演化为了软件,那么之前提到过的控制台(console)呢?答案是 — 也变为了黑底的命令行界面,它的字符设备文件为/dev/console:
现在的控制台主要用于显示比如内核消息,后台服务消息等,比如在启动和关闭Linux系统时,一闪而过觉得很酷炫的命令界面就是控制台:
-
登录(login)到用户态后可以在root用户下执行dmesg查看这些日志。
我再啰里啰嗦的提上一嘴,在早期的计算机中,它们完全是不同的物理设备;但是现在有的时候名词“终端Terminal”和“控制台console”均表示能执行用户命令的界面,不进行任何的区分。哎呀,这些都是历史的遗留问题,具体情况具体分析吧。
实验1、登录ubuntu的/dev/console(登录单用户模式)
ubuntu的纯命令行(Live server)版本用户登录的是tty(使用的字符设备文件为/dev/ttyN),不是控制台(/dev/console)。登录控制台的充分必要条件是在单用户模式登录到Linux。
-
ubuntu桌面版本的终端窗口使用的是/dev/pts/N,还不是tty。
首先要让ubuntu 18.04在开机时显示GNU GRUB界面,设置方法为引用自:https://www.yuque.com/cyberangel/yal5fc/koupxd:
由于文章字数受限
可点击下方【阅读原文】阅读全篇。
分享
收藏
点赞
在看
原文始发于微信公众号(IOTsec Zone):物联网安全干货丨Linux Kernel 0.12(4-3-1)–main.c终端初始化(前奏)