UNIX V4 在 Low Resource Computing 上的研讨会

Lobsters Hottest 事件

摘要

作者在 Low Resource Computing 2026 活动中主持了一个关于 UNIX V4 的互动研讨会,教授使用恢复的1974年系统配合 ed 文本编辑器和多终端设置进行软件开发。

<p><a href="https://lobste.rs/s/p9kpp9/unix_v4_workshop_at_low_resource">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/27 17:27

thaliaarchi/unix-v4-demo 来源:https://github.com/thaliaarchi/unix-v4-demo

在低资源计算研讨会上的 UNIX V4 工作坊

在达特茅斯学院举办的 2026 年低资源计算 (https://lrc.cs.dartmouth.edu) 研讨会上,我主持了一场关于 UNIX V4 的互动环节。这个版本的 UNIX 最近从犹他大学发现的一盘 1974 年磁带中恢复,是 UNIX 最早的完整机器可读快照。我教授了如何使用当时的工具进行软件开发,特别是配合电传打字机的 ed 文本编辑器,参与者们解决了一个编码挑战,所有人都登录到同一台机器。这个仓库复现了工作坊的磁盘镜像终端日志,以及我的配置脚本

终端

在工作坊前,我修改了内核以支持最多 32 个同时连接的终端,从之前的 20 个增加而来。它使用了 16 个 KL 终端和 16 个 DC 终端。我本可以配置 16 个 DH 终端,使总数达到 48 个(这是该版本 UNIX 的理论极限),但 PiDP-11 分支的 SIMH 模拟器不支持这种多路复用器。

我连接了两个物理终端(一台 Silent 700 电传打字机和一台 Heathkit CRT 终端),参与者笔记本电脑的 29 个 telnet 连接,以及 PiDP-11 上的主控制台。在这个列表中找到你使用的终端:

各终端线路的日志:

我描述了我的配置以方便重现,尽管说明主要是为我自己准备的。我以后会将其修改为配置 V4–V7 的教程。

入门

我分发了打印的手册,以当时的方式教授系统。ed 手册特别有用。Alex 甚至第二天回来时用了我没教的 ed 命令,因为他通读了整本手册。

我也希望能设置 man 命令,但没能在规定时间内让它工作起来。

  • 15x ed(I) 手册 (http://squoze.net/UNIX/v4man/man1/ed.pdf) (V4)
  • 10x “UNIX 文本编辑器教程导论” (http://squoze.net/UNIX/v7/files/doc/04_edtut.pdf) (V7)
  • 10x “UNIX 初学者指南” (http://squoze.net/UNIX/v7/files/doc/03_beginners.pdf) (V7)
  • 4x as(I) 手册 (http://squoze.net/UNIX/v4man/man1/as.pdf) (V4)
  • 4x “汇编器参考手册” (http://squoze.net/UNIX/v7/files/doc/28_assembler.pdf) (V7)
  • 4x “设置 UNIX” (https://www.tuhs.org/Archive/Applications/Dennis_Tapes/Gao_Analysis/v4_dist/setup.pdf) (V4)

首先,我们为所有人创建了用户账户。由于这是通过编辑 /etc/passwd 实现的,我为大多数人操作了,以避免人们覆盖别人的更改。他们的用户 ID 很有创意。

 % cat /etc/passwd
root::0:1::/:
bin::3:1::/bin:
thalia::4:4::/usr/thalia:
ben::5:5::/usr/ben:
alex::9:9::/usr/alex:
newt::64:64::/usr/newt:
auberon::18:18::/usr/auberon:
ncb::12:12::/usr/ncb:
joe::88:88::/usr/joe:
cody::25:25::/usr/cody:
hash::31337:31337::/usr/hash:
dnm::55555:55555::/usr/dnm:
ty::1990:1990::/usr/ty:
justin::70:70::/usr/justin:
yang::16::16::/usr/yang:
doug::8:::/usr/doug:
amitb::6:6::/usr/amitb:
voytilla::7:7::/usr/voytilla:
kevin::10:10::/usr/kevin:
michael::30:30::/usr/michael:
bx::42:42::/usr/bx:
hacker::256:256::/usr/hacker:
jordan::69:69::/usr/jordan:
dominic::111:111::/usr/dominic:

特性

最大的调整也许是,每个人本能地伸手去按退格键纠正错别字,但这反而会发送一个字面的 ASCII 退格字符。这发生了数百次。早期的 UNIX 是为打印终端设计的,当然,文本一旦打印在纸上就无法清除。相反,它使用 # 擦除最后一个字符,使用 @ 擦除当前行,这是借鉴自 Multics。

一位参与者惊讶于我对此的本能反应。amitb 发现擦除字符可以通过 stty erase '^h' 配置为退格键,但遗憾的是,这只在后续版本的 UNIX 中有效。

另一个普遍存在的表面差异是,cd 在 V7 之前被命名为 chdir。参与者遇到了大约 100 次 cd: not found。但到结束时,这不再是个限制,有人修改了 shell,如果你输入 cd 会对你发出笑声:

 % cd dir
haha
 % ed /usr/source/s2/sh.c
10267
/cd/;/}/p
if(equal(cp1, "cd")) {
    prs("haha\n");
    return;
}

一个令人困惑的特性是,login 有时会使用全大写模式以兼容 Teletype Model 33。它会循环尝试终端设置直到找到一个可用的,所以如果你无法登录,它会尝试全大写模式。这尤其容易发生在 KL 终端会话中。该驱动假设终端始终连接,不等待它就绪,因此初始的 login: 提示总是丢失。按下回车后,它会循环到下一个设置并显示全大写提示,使你的整个会话都变成大写。这发生了大约 14 次。

LOGIN INCORRECT.
NAME: ROOT
# CD /USR
CD: NOT FOUND
# CHDIR /USR

纸张

我带来了我的 TI Silent 700 Model 707/1200 电传打字机,以演示在纸上的计算。在世界转向 CRT 终端之前,电传打字机会将你的会话打印到纸上。纸张就是你的显示器,剪切/粘贴是用剪刀和胶带完成的。

Alex 特别喜欢这台电传打字机,经常发现他坐在它后面。Auberon 发现那卷长长的纸如此有趣,以至于她会向她的学生展示我拿着它的这张照片,以显示计算是如何发展的。

我们用完了最后一点纸,打印了一幅一米长的土星五号火箭 ASCII 艺术品 (https://ascii.co.uk/art/apollo),前面是十个哔哔声的倒计时。纸上的红色条纹警告我们即将结束,火箭看起来血迹斑斑。

Heathkit H19 显示 LRC 2026 文本艺术使用 o8 FIGlet 字体 (https://www.figlet.org/cgi-bin/fontdb_example.cgi?font=o8.flf) 的照片成为了工作坊的非正式标志,并被打印在贴纸上。

挑战

我挑战参与者将首届国际混淆 C 代码大赛的获胜程序 mullender.c (https://www.ioccc.org/1984/mullender/) 从 1984 年的 UNIX V7 移植回 1974 年的 V4。它利用了早期 cc 的特性,移植它对于一个如此简短的程序来说,意外地涉及系统深层,令人惊讶。这是我在恢复 V4 之前用 UNIX V5 做的第一件事之一,所以我推测这对新用户来说是可行的。

这个程序打印一个 :-) 笑脸在屏幕上滚动,但它是用 PDP-11 和 VAX 机器代码编写的。如下所示:

/* Portable between VAX11 && PDP11 */
short main[] = {
    277, 04735, -4129, 25, 0, 477, 1019, 0xbef, 0, 12800,
    -113, 21119, 0x52d7, -1006, -7151, 0, 0x4bc, 020004,
    14880, 10541, 2056, 04010, 4548, 3044, -6716, 0x9,
    4407, 6, 5568, 1, -30460, 0, 0x9, 5570, 512, -30419,
    0x7e82, 0760, 6, 0, 4, 02400, 15, 0, 4, 1280, 4, 0,
    4, 0, 0, 0, 0x8, 0, 4, 0, ',', 0, 12, 0, 4, 0, '#',
    0, 020, 0, 4, 0, 30, 0, 026, 0, 0x6176, 120, 25712,
    'p', 072163, 'r', 29303, 29801, 'e'
};

我将程序放在 /usr/thalia/mullender.c,提示放在 /usr/thalia/hints/,然后让他们自由发挥。

三位用户解决了挑战:alexkevinjordan。Alex 和 Travis (https://github.com/travisgoodspeed) 合作,使用 Travis 的 HP 计算器进行进制转换。Jordan 使用 dc(桌面计算器)进行算术运算。

 % dc
_30419 15 -
p
-30434
q

原始版本使用一个不存在的系统调用来在打印之间添加延迟,但这在 V4 中不起作用,因为不存在的系统调用会以 Bad system call -- Core dumped 陷阱捕获。解决方案是将其替换为另一个不产生效果的系统调用。Alex 和 Kevin 与我的做法一致,将其切换为 getuid,但 Jordan 选择了 smdate。这个系统调用原本会设置文件的修改时间,但它被移除了,因为它对观察文件时间的工具造成了问题。它的 nullsys 处理程序没有任何效果,但它仍然消耗一个参数,所以它跳过了 sob 分支并额外快速地打印。

 % ed /usr/sys/ken/sysent.c
1957
/45/
0, &nosys,          /* 45 = tiu */
/getuid/
0, &getuid,         /* 24 = getuid */
/smdate/
1, &nullsys,        /* 30 = smdate */

Alex 编写了脚本 通过使用 Thompson shell 的旧行为来修复十六进制语法:消耗标准输入的命令会从脚本文件读取直到退出,因此命令和输入交错出现,没有像后来的 heredocs 那样的引号。

 % cat /usr/alex/hint3b
ed mullender.c
/0xbef/s//05757/
/0x52d7/s//051327/
/0x4bc/s//02274/
g/0x9/s//011/
/0x7e82/s//077202/
/0x8/s//010/
/0x6176/s//060566/
w
q
 % sh hint3b
469
469
 %

auberonbxamitb 成功移植了语法变更,cody 几乎完成了那部分。bx 学习了 db 调试器 (https://github.com/thaliaarchi/unix-v4-demo/blob/main/logs/dc10.log#L3564) 并跟踪了程序执行。amitb 将其格式化得更具艺术性:

/* Portable between VAX11 && PDP11 */
int main[] {
    277, 04735, -4129, 25, 0, 477, 1019, 3055, 0, 12800,
    -113, 21119, 21207, -1006, -7151, 0, 1212, 020004,
    14880, 10541, 2056, 04010, 4548, 3044, -6716, 9,
    4407, 6, 5568, 1, -30460, 0, 9, 5570, 512, -30419,
    32386, 0760, 6, 0, 4, 02400, 15, 0, 4, 1280, 4, 0,
    4, 0, 0, 0, 8, 0, 4, 0, 44, 0, 12, 0, 4, 0, 35,
    0, 020, 0, 4, 0, 30, 0, 026, 0, 24950, 120, 25712,
    112, 072163, 114, 29303, 29801, 101
};

之后,他们已经相当熟练地使用 ed 了。

游戏

除了编程,人们还在 /usr/games 中发现了游戏。猎杀 Wumpus 非常受欢迎,有人发现了 bj(二十一点)与传统规则的不同之处。

 % /usr/games/wump
Instructions? (y-n)
y
Welcome to 'Hunt the Wumpus.'
  The Wumpus lives in a cave of 20 rooms.
Each room has 3 tunnels leading to other rooms.

传奇人物

Doug McIlroy 在工作坊的第三天到访。他是有史以来第一位 UNIX 用户,负责将 UNIX 推广到最初的研究小组之外。他做了一个关于裸 m4 的讲座 (https://discuss.systems/@thalia/117123655247685214),这是 m4 宏处理器的单操作版本,只有 define,但仍然是图灵完备的。

之后,他在 UNIX V4 上为自己设置了一个账户 doug。他习惯了后续版本的 ed(允许省略结束斜杠)和后来的 passwd 格式,但他仍然有肌肉记忆。

我们聊起了 UNIX 的早期岁月:他们一直使用 Teletype Model 33 ASR 作为控制台电传打字机,直到最后,即使他们不用于编程,因为硬拷贝终端很有用。Ken 和 Dennis 在晚上工作,避开他的视线,尽管他们在家里设置了终端,但他们在一起工作更好,并尽职尽责地来到实验室。

早期的 UNIX 发行版是用 GE 635 制作的,因为它有磁带驱动器,而 PDP-11 没有。Bob Morris 和 Ken 写了一个打印一百万位 e 的程序,并使用了一卷纸。Doug 的语音合成器没有广泛分发,但我指出 V4 有一个 Screw Works 驱动程序。Doug 为 Multics 编写了 roff。

与 Doug 共享一个 UNIX 系统是一种荣幸。由于研究进展如此之快,这将是 52 年来他第一次使用这个版本的 UNIX。

黑客

Ben (https://kallus.org) 对用户和组 ID 的限制特别好奇,多次更改了他的 ID。

ben::5:5::/usr/ben:
ben::65535:65535::/usr/ben:
ben::-1-1::/usr/ben:
hacker::256:256::/usr/hacker:

他首先尝试了无符号 -1,然后是带符号的 -1。他假设它只是使用了 scanf,所以会接受符号,但解析更简单,仍然产生了一个可用的 uid。然而,他的条目缺少一个冒号,所以他无论如何都无法登录。

 % ed /usr/source/s1/login.c
2884
/uid =/;.+2p
uid = 0;
while (*np != ':')
    uid = uid*10 + *np++ - '0';

在阅读了 shell 源代码后,他意识到任何 uid 模 256 等于 0 的都是超级用户,所以他创建了一个 uid 为 256 的账户,并被视为 root。

 % ed /usr/source/s2/sh.c
10267
/acname =/;/}/p
acname = "/usr/adm/sh_acct";
promp = "% ";
if(((uid = getuid())&0377) == 0) {
    promp = "# ";
    acname = "/usr/adm/su_acct";
}
q
 %
^D
login: hacker
#

消息传递

我们至少有 11 个用户同时活跃,尽管在其他时间可能更多:

# who
root     tty0   Aug 18 10:36
ty       tty1   Aug 18 10:52
hash     tty2   Aug 18 10:50
root     tty8   Aug 18 10:53
ty       ttyc   Aug 18 10:54
newt     ttyk   Aug 18 10:43
cody     ttyl   Aug 18 10:48
alex     ttym   Aug 18 10:48
newt     ttyn   Aug 18 10:39
dnm      ttyq   Aug 18 10:49
ncb      ttyt   Aug 18 10:43

有些人给自己发消息:

# write root
␇␇␇Message from root...
hiiiiiii
hiiiiiii

给别人发消息:

# write alex
{not much!!! hacking the planet)
#

发送邮件:

 % mail kevin
is this thEOT
ing on
 %

我直接写入其他人的终端设备:

 % who
 % cat > /dev/tty1
hello how are you
 %

结束

到最后,我们熟悉了系统,学习了 ed,用 C 编程了一点,玩了一些游戏,互相发送了邮件,并用完了一整卷纸。巨大的成功!

login: thalia
 % cat thanks
thank_you
from_darpa_dan

相似文章

像2009年那样进行系统管理

Lobsters Hottest

Legacy Labs 是一个复古计算夏令营活动,邀请参与者在两个月内探索老旧或永久计算主题,从深入探讨Windows Server 2008 Core开始。

一人,双内核,与大量RISC-V

Hacker News Top

QRV Systems的Yuri Zaporozhets在FPGA上构建了一台基于RISC-V的个人计算机和一台大型机,并两次重写了QNX。他最新的操作系统QSOE正在FOSS世界中引起关注。

iwp9 2026

Lobsters Hottest

第 12 届 Plan 9 国际研讨会的幽默注解摘要,涵盖音频制作、安全、工具链等主题的演讲。