申明:本文并不是《Things Every Hacker Once Knew》的完整、准确的中译版,其中不乏自认为正确的个人观点,详情请参考原文。
硬件
现在,当两台物理机进行信息交互时,通常会遵守 TCP/IP 协议,即使是终端这样的模拟器,也同样如此。但在 1992 年之前,如果你能够接触到当时非常昂贵的工作站硬件,你会发现情况和现在是完全不同的。
20 世纪 70 年代中期,视频显示终端实际上是由“电传打字机”演变而来的,而“电传打字机”则是由维多利亚时代的电报演变而来的。1960 年末,Unix 刚出现时,主要是为打印显示终端而编写的,尤其是被称为 Teletype Model 33(简称 ASR-33)的机型,我们现在依然能在 Unix 设备上看到的 “tty” 是当时流行的 “teletype” 的缩写。
在互联网之前的,计算机之间很少交互,电传打字机和终端需要使用一种称为 “RS-232” 的硬件协议与计算机交互。RS-232 的寿命很长,20 世纪 60 年代问世,至今仍被使用,最初不是用于和计算机通信,而是用于电传打字机与调制解调器通讯。在 USB 之前,当人们谈到 "串行 "链接时,他们指的是 RS-232,有时也将使用它的设备称为 "串行终端"。
今天,一台个人电脑上有多个处理器,可以同时处理多个任务,但在过去,多个用户的多个任务被分配到一台机器的一个处理器上,这被称为“分时租凭”。20 世纪 80 年代中期的 DEC VAX 11-780 微型计算机,采用分时租赁的方式处理任务,能够支持十几个用户同时使用,但相比于 2017 年的低端智能手机,其运算能力不到它的 1/1000,可用存储空间不到它的 1/5000。
调制解调器
调制解调器起初是为 1950 年代的美军半自动地面防空系统(Semi-Automatic Ground Environment,简称 SAGE )研制,用来连接不同基地的终端,雷达站和指令控制中心到美国和加拿大的 SAGE 指挥中心。 SAGE 运行在专用线路上,但是当时两端使用的设备跟今天的调制解调器根本不是一回事。IBM 是 SAGE 系统中计算机和调制解调器的供货商。几年后美国航空的首席执行官与 IBM 一位区域经理的一次会晤促使"mini-SAGE"这种航空自动订票系统。在这系统中,一个位于票务中心的终端连接在中心电脑上,用来管理机票有效性和时间。这个系统,叫做 Sabre,是今天SABRE 系统的早期原型。 1960 年代早期,商业计算机的应用逐渐普及,加上上述技术成果,1962 年,AT&T 发布了第一个商业化调制解调器 Bell 103。使用两个音调表示 1 和 0 的移频键控技术,103 已经能够实现 300 bps的传输速度。很短时间后继版本 Bell 212 就研制出来,转移到更稳定的移相键控技术把数据速率提高到 1200 bps。 类似 Bell 201 的系统用双向信号集在4对专用线路上实现了 2400 bps。 贺氏智能调制解调器(Hayes Smartmodem)是一个重大的进步,1981年由贺氏通讯研制成功。最早的智能调制解调器是一个300 bps调制解调器,使用Bell 103通信协议标准,并内置了一个微控制器,可以让计算机发送命令来控制电话线,例如摘机、拨号、重拨、挂机等功能。这些指令被广为沿用,并逐渐扩展,被称为海斯指令集(Hayes command set)。
在智能调制解调器之前,几乎所有的调制解调器都需要两个步骤来产生一个连接:第一步,人工在电话机上拨叫对方的号码,然后将听筒放在调制解调器附带的声音耦合器(acoustic coupler)里,一个用两个橡胶杯组成的用来在声音信号和电信号之间转换的设备。使用智能调制解调器除了不需要声音耦合器,更重要的是直接将调制解调器连接在标准电话线或插座上。然后电脑就能自动完成接通电话并拨叫号码的功能。这个改变极大的简化了电子布告栏系统(BBS)的安装和使用。
核心的意义
从 1955 年到 1975 年,在半导体存储器出现之前,计算机存储器数据主要依赖于带有磁性的铜线圈,这些铜线圈被称为“铁氧体磁芯”,主存储器也因此被称为“核心存储器”或“核心”。
Unix 这个词是 20 世纪 70 年代初产生的,直到 20 世纪 90 年代,每个黑客都知道这个词的意义,然而,2000 年以后,随着多处理器系统变得越来越普遍,“处理器核心”开始简称为“核心”。2017 年以后,“核心”这个词的意义开始变得模糊,旧时的称呼已经不再被大众所理解,这个词语的意义开始变得令人费解。
36 位机器和 8 进制的持久性
现在的系统通常是 2 的 N 次方大小,8 位、16 位、32 位或者 64 位,但在 1983 年之前,曾经出现过一个 36 位的计算机系统架构,当时,关于 36 位机器的知识在黑客界得到了广泛的传播,其中最具代表性的两台机器分别是 DEC PDP-10 和 Symbolics 3600 Lisp。
现在回过头来看,16 位机器存储 2 进制的字节,这是理所应当的事情,但那时,人们普遍认为,通过在内存转存中是否能看到大于 7 的数字,就能够判断一台机器是 32 位的机器还是 36 位的机器。
下面是关于过去那台 36 位机器的一些事情:
- 36 位能够代表期待范围的正负整数和小数,32 位的标准化的过程遭到了数字分析师和科学计算领域人士的抵制,他们非常希望能够有多出来的那 4 位的精确度,但是没有成功;
- 在 36 位机器上,一个“字符”可能是 9 位,一个字就是 4 个字符,因此,为这些机器设计的键盘就会有一个键来表示这个字符是 8 位还是 9 位。
- 在 36 位机器上,一个“字符”也有可能是 6 位,也因此会有许多不同的 6 位字符编码,而且不仅不同制造商之间不统一,单个制造商也会使用不同的编码。
C 的祖先是一种写在 PDP-7 上的解释性语言,被命名为 B,在 B 语言中,以 0 开头的数字被解释为 8 进制。
PDP-7 的继任者,也是第一台 Unix 系统的机器 PDP-11,首次实现了 C 语言的雏形,它主要采用 16 进制解释器,并对其的语法进行了拓展:当字符串的反斜杠后面有一个数字时,会被识别为八进制。PDP-11 如此成功,不仅成为了主流,扼杀了 36 位机器,还影响了后来的语言(Java、Python 等)的设计,这些语言出于兼容性的考虑,复制了 C 语言低级的规则,这有时会对那些 3 比特内核的系统造成困扰,而且这个困扰或许永远也也不会消除了。
RS232 和它的不足之处
TCP/IP 就像一个简单清晰的八位字节流,数据传输的速度取决于网络传输的速度,而且错误检测/纠正是在后台进行处理的。
但 RS-232 不是这样的,使用 RS-232 协议进行数据传输的两台机器,必须使用相同的数据编码格式,在传输之前需要协商好数据传输的速度,并且错误检测和纠正也是在数据流中完成的。这就要求你在进行数据传输之前,对两端的设备进行设置,如果一端的设置和另一端不匹配,则会带来可怕的错误,在过去的那些日子里,数据传输的“脆弱性”不言而喻。
RS-232 的硬件设备也并不是同意的,1962 年定义的标准 RS-232 使用了一个 D 型的外壳,有 25 个物理针脚,远超过了物理协议的实际需求,20 年后,在 1984 年的 IBM PC-AT 推出后,大多数制造商转而使用了较小的 DB-9 连接器,最后,这些端口被 USB 和以太网淘汰了。
RS-232 在发展的过程中,存在众多令人难受的体验,比如,你无法区分一个设备是失去连接还是默默工作,在 2000 年以后,更是存在两种不同电压的外接设备,导致 TTL 端的元件在误操作的情况下发生烧毁,最终,RS-232 在 20 世纪 90 年代中后期,慢慢被人遗忘,但直到 2010 年左右,才最终从通用计算机中消失。
我之所以讨论这个问题,是因为一些设备(比如 GPS),可能仍然需要知道什么是 RS-232 “握手的过程”,比如:一个终端可以改变 DTR(数据终端就绪)线的状态,以此表明它准备接受、启动或者继续一个调制解调器会话。而且在销售系统、商业级路由器的诊断控制台和嵌入式系统的调试控制台中也被使用。
广域网时代的到来:前互联网时代
今天,TCP/IP 几乎是仅存的广域网,但在 70 年代末期到 90 年代中期,尤其是 1981 年到 1991 年间,情况却是完全不同的,当时有大量的广域网同时存在,人们有时会在宣传自己的网站时书写多个不同的网络地址。
一些年纪稍长的黑客都会记得 UUCP 和 BBS,大量的人参与过这两个活动,那时候,如果你不是隶属于联邦机构、军事项目或大学研究实验室,就很难从事“真正”的互联网(APPANET)。因此,人们尝试用他们已有的设备,调制解调器和电话线来进行信息传输。
UUCP 是 Unix to Unix Copy Program 的缩写,1979 年诞生于贝尔实验室,1990 年中期,在互联网中名声大噪,它用调制解调器和电话网络,在 Unix 站点之间提供了缓慢但非常成功的网络。 UUCP 是一个存储和转发系统,最初是为了软件的更新和发版,但它的使用场景迅速转变为电子邮件和一个叫做 USENET(Stack Overflow 和其他现代网络论坛的前身)的东西。它支持信息的分类和聚合,将这些信息通过 UUCP 从源头进行传播,最终涌向整个网络。从某种程度上来看,UUCP 和 USENET 是对当时已经存在的电话系统的破解,当时的电话分为“本地”和“长途”,“本地”电话按月收费,“长途“电话按分钟收费,价格昂贵。UUCP 的流量通过本地转换,可以进行长距离传输,在便宜的互联网到来之前,这对于黑客文化的形成,非常重要,USENET 小组可以通过这种方式分享源代码,一些惯例至今仍在使用,比如将项目根目录的数据文件命名为 README。
USENET 有两个历史上非常重要的日期,一个是 1987 年的重命名,另一个是 1993 年的“永不结束的九月”,前者对 USENET 主题分类进行了重新命名,后者可以让用户使用分时服务的 USENET。UUCP 非常难配置,以至于那些知道如何配置的人经常在他们的简历上写上这种技能,并以此获得一份工作。
与此同时,在微型计算机的世界里,一种全新的存储和转发方式也在发展——BBS(公告板系统)。BBS 是一个在计算机上运行的软件,有一个连接调制解调器的位置,可以接受电话线连接。用户可以使用他们自己的调制解调器和终端程序访问 BBS,BBS 软件允许他们互相留言,上传和下载文件,有时还可以玩游戏。
第一个 BBS 系统的商业运营在 1978 年芝加哥的超市里以社区广告牌的形式展示在大家面前,在接下来的 18 年里,有超过十万个 BBS 闪亮登场,很多时候只是系统管理员的私人电脑或者车库里的备用电脑。1984 年开始,BBS 文化发展出了一种另类的形式,叫做 “FidoNet”,支持跨网站的电子邮件和类似于 USENET 的论坛系统,也有一些 UUCP 移植到 DOS 个人电脑上,但都没有改变 UUCP 和 BBS 各自独立的现状,最终两者都被互联网的浪潮所吞没。
现在仍有少数 BBS 由一些怀旧者运营着,一些文化得以传承,但就像 UUCP 网络一样,在互联网如此廉价的今天,BBS 的存在已经失去了最初的意义,关于 BBS 的记忆几乎只剩下围绕着一系列文件传输协议——XMODEM、YMODEM 和 ZMODEM,这些在 BBS 之前就已经开发出来,主要用于 BBS 的协议。
FTP、Gopher 和被遗忘的前网络时代
在 20 世纪 90 年代初的短短几年时间里,王维网从无到有,无处不在。在此之前,,从 1971 年开始,互联网网站之间的文件传输通常是由一个名为 ftp 的工具完成的,因为它使用的是文件传输协议,但最终,ftp 被其他使用 FTP 协议的网络浏览器所取代。
与此同时,蒂姆-伯纳斯-李发明万维网的同一年(1991 年),明尼苏达大学的一群黑客设计了“Gopher”,一个以菜单为中心而不是以链接为中心的超文本协议,几年时间里,Gopher 与早期的万维网展开了激烈的竞争,许多黑客同时使用这两种协议,直到 1993 年,大学开始对其实施使用许可费后,Gopher 开始没落。尽管现在仍有一些 Gopher 服务器在运行,但 Gopher 实际上已经名存实亡了。
终端的混乱
现代 Unix 系统上的软件终端经历了一个漫长而且混乱的发展过程,它最初源于早期的显示器,有时被称为“玻璃 TTY”——因为它可以模拟打印机现实内容,但是不需要消耗纸张。
第一台终端在 1969 年出厂,其中最被大众所知的,可能是 1975 年的 ADM-3 型号。就像早期的 ASR-33 一样,这些设备有一个有趣的历史遗留问题,尽管 1975 年后制造的显示器可以展示小写字母,但 Unix (以及 2018 年之前的 Linux)对以大写字母开头的输入,会产生令人费解的结果。
终端的发展还曾经历过代码进行输出控制的过程,直到 1979 年后,一个叫做 DEC VT-100 的终端控制 ANSI 标准的出现,这个局面才得以改变。
如今,那些能够显示各种图案和颜色的显示界面被我们称为“GUI“,那些只使用字符的程序界面现在被称为”TUI“。
一些黑客会知道,屏保的出现,是为了避免阴极射线管持续受到一种叫做“荧光粉烧毁”的现象的影响,这种影响会永久性地损害屏幕。
位图显示
早期的终端机只能显示固定的字母组成的字符,1973 年,施乐公司第一个采用位图显示图像,并创造了第一个生产系统阿尔托。
早期的 Alto 显示器只有 608808 像素,1981 年,它的继任者“蒲公英”达到了 1024809 像素,施乐公司曾称其为“施乐之星”,但最终商业化运营失败。1982 年,Sun Microsystems 公司推出了 1024*800 像素的 Sun-1,这台机器的一系列产品获得了巨大的成功,直到 90 年代末 IBM PC 的出现,但是这些机器都太昂贵了。
1975 年开始,位图开始能够显示彩色,如苹果二代,但是它们的像素只有 280*192。
很长一段时间里,黑客们不得不选择分辨率较高的黑白显示器,它们相对便宜,且够大,更适合黑客们日常的工作和生活。1990 年左右,1024*1024 的彩色显示器才进入高端消费市场,但那时的显示器质量仍然很差,由于为阴极射线管制造彩色的费用相对较高,难度很大,成像存在着明显的瑕疵。这些问题直到平面显示器出现之后才得到解决。
ASCII 码
ASCII 码,即美国信息交换标准代码,是 20 世纪 60 年代初,从电传打字机上使用的一系列字符码中演变而来的。与许多早期的字符编码不同,ASCII 码至今仍被使用且可能长期被使用。如果你不知道 UTF-8 是什么样的,ASCII 码也是 UTF-8。
下表是 ASCII-1967,也是现在正在使用的版本:
Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex
0 00 NUL 16 10 DLE 32 20 48 30 0 64 40 @ 80 50 P 96 60 ` 112 70 p
1 01 SOH 17 11 DC1 33 21 ! 49 31 1 65 41 A 81 51 Q 97 61 a 113 71 q
2 02 STX 18 12 DC2 34 22 " 50 32 2 66 42 B 82 52 R 98 62 b 114 72 r
3 03 ETX 19 13 DC3 35 23 # 51 33 3 67 43 C 83 53 S 99 63 c 115 73 s
4 04 EOT 20 14 DC4 36 24 $ 52 34 4 68 44 D 84 54 T 100 64 d 116 74 t
5 05 ENQ 21 15 NAK 37 25 % 53 35 5 69 45 E 85 55 U 101 65 e 117 75 u
6 06 ACK 22 16 SYN 38 26 & 54 36 6 70 46 F 86 56 V 102 66 f 118 76 v
7 07 BEL 23 17 ETB 39 27 ' 55 37 7 71 47 G 87 57 W 103 67 g 119 77 w
8 08 BS 24 18 CAN 40 28 ( 56 38 8 72 48 H 88 58 X 104 68 h 120 78 x
9 09 HT 25 19 EM 41 29 ) 57 39 9 73 49 I 89 59 Y 105 69 i 121 79 y
10 0A LF 26 1A SUB 42 2A * 58 3A : 74 4A J 90 5A Z 106 6A j 122 7A z
11 0B VT 27 1B ESC 43 2B + 59 3B ; 75 4B K 91 5B [ 107 6B k 123 7B {
12 0C FF 28 1C FS 44 2C , 60 3C < 76 4C L 92 5C \\ 108 6C l 124 7C |
13 0D CR 29 1D GS 45 2D - 61 3D = 77 4D M 93 5D ] 109 6D m 125 7D }
14 0E SO 30 1E RS 46 2E . 62 3E > 78 4E N 94 5E ^ 110 6E n 126 7E ~
15 0F SI 31 1F US 47 2F / 63 3F ? 79 4F O 95 5F _ 111 6F o 127 7F DEL
然而这种格式因为格式问题,很少被使用,目前使用更多的是下面这种格式:
0000000 NUL 0100000 1000000 @ 1100000 `
0000001 SOH 0100001 ! 1000001 A 1100001 a
0000010 STX 0100010 " 1000010 B 1100010 b
0000011 ETX 0100011 # 1000011 C 1100011 c
0000100 EOT 0100100 $ 1000100 D 1100100 d
0000101 ENQ 0100101 % 1000101 E 1100101 e
0000110 ACK 0100110 & 1000110 F 1100110 f
0000111 BEL 0100111 ' 1000111 G 1100111 g
0001000 BS 0101000 ( 1001000 H 1101000 h
0001001 HT 0101001 ) 1001001 I 1101001 i
0001010 LF 0101010 * 1001010 J 1101010 j
0001011 VT 0101011 + 1001011 K 1101011 k
0001100 FF 0101100 , 1001100 L 1101100 l
0001101 CR 0101101 - 1001101 M 1101101 m
0001110 SO 0101110 . 1001110 N 1101110 n
0001111 SI 0101111 / 1001111 O 1101111 o
0010000 DLE 0110000 0 1010000 P 1110000 p
0010001 DC1 0110001 1 1010001 Q 1110001 q
0010010 DC2 0110010 2 1010010 R 1110010 r
0010011 DC3 0110011 3 1010011 S 1110011 s
0010100 DC4 0110100 4 1010100 T 1110100 t
0010101 NAK 0110101 5 1010101 U 1110101 u
0010110 SYN 0110110 6 1010110 V 1110110 v
0010111 ETB 0110111 7 1010111 W 1110111 w
0011000 CAN 0111000 8 1011000 X 1111000 x
0011001 EM 0111001 9 1011001 Y 1111001 y
0011010 SUB 0111010 : 1011010 Z 1111010 z
0011011 ESC 0111011 ; 1011011 [ 1111011 {
0011100 FS 0111100 < 1011100 \\ 1111100 |
0011101 GS 0111101 = 1011101 ] 1111101 }
0011110 RS 0111110 > 1011110 ^ 1111110 ~
0011111 US 0111111 ? 1011111 _ 1111111 DEL
分布式协作系统的诞生
如今,分布式版本控制的公共设施和与之相适应的分布式团队的许多做法都以标准化,但是,这些工具的发展与演变其实经历了漫长的过程。
最早的软件是通过一种叫做 DECUS 磁带的进行数据共享的,那时候,并没有版本控制、补丁和伪造者。版本控制最早诞生于 1972 年,而补丁,直到 1984 年才出现。
1989 年到 1993 年,互联网呈现出爆发式的增长,互联网的传输速度已经足够黑客们大展手脚了,接下来,他们开始考虑文化上的变化了。 1991 年,Linux Torvalds 宣布 Linux 将采用分布式协作的方式进行开发,但那时的 Linux,打补丁仍要通过类似于发邮件的方式进行,直到埃里克·斯蒂芬·雷蒙在《大教堂和市集》中宣扬——应该把公共资源库作为主项目,共享公共资源库,这一方式才得到改变。
第一个专门的维护软件机构直到 1999 年才成立,它就是 SourceForge,起初,它只支持 CVS 格式的文件,也因此促进了 CVS 的开发。2005 年,Linus Torvalds 发明了 Git,它迅速的淘汰了之前所有的版本控制系统,现在成为了黑客界的标杆。