NetBSD on a JavaStation
在JavaStation上安装NetBSD
可能难以想象,曾经有一段时间,Java 是一个崭新而令人兴奋的事物。远在它成为今天庞大笨重的后端巨兽之前,它曾经要成为一种无处不在的图形化平台,应用于从手机到超级计算机的所有设备:一次编写,随处运行。
最初,我也被洗脑了,对这种即将统治世界的新“现代”语言感到兴奋,并对基于 Java 的计算机,包含可以像原生机器码一样运行 java 字节码的 Java 芯片的概念垂涎三尺。
我甚至把一张宣传单贴在了墙上,旁边是 Lydia Lunch、鼓机和 Jimi Hendrix 的照片;上面有一张即将发布的 JavaStation 的照片,看起来像一个设计师款的紫色咖啡壶;仅仅是看着它就激发了我的想象力。
当然,事实证明,事情并没有完全按计划进行:JavaStation 很久之后才出现,而且当它出现时,它看起来不像咖啡壶,而像一个贴着 Java 标志的迷你 SPARCstation。Java 芯片这件事比预期的更难实现,因此这台机器是基于 SPARC 的,没有磁盘,旨在运行名为 JavaOS(非常聪明)的基于 Java 的操作系统中的 Java 应用。尽管它不是一台纯粹的 Java 机器,但它可以说是第一台真正的网络计算机,而我想要一台。
最终,JavaStation 2 发布了,它确实更像一个咖啡壶,但仍然“只是”一台 SPARC。它们并没有改变世界。
几十年后,我们来到了这里,我发现自己沉浸在对年轻时遥不可及的技术的怀旧之中。
经过几个月的搜索,我在加拿大找到了一台 Mr Coffee JavaStation 出售;不幸的是,卖家只接受通过加拿大银行服务的付款,这在加拿大境外几乎无法访问。几个月后,我的一个朋友搬到加拿大工作,并好心地帮我买了它并运给我。
等待包裹到达的过程是痛苦的;我痴迷地检查跟踪详情,并对它在该国以完全奇怪的方向移动感到非常沮丧和困惑。它从加拿大出发,几乎直接经过我的房子到达了一个比加拿大原始位置离我更远的邮件仓库!
但最终它还是到了,除了几处墨渍和划痕外,状况良好。顺便说一句,如果有什么关于清理它而不损坏外壳的建议,我将非常感激。
我将它连接到显示器和键盘,然后打开电源。令我高兴的是,风扇和电源 LED 都亮了起来!但屏幕上什么也没有。键盘 LED 也没有亮起……
所以,我将串口连接到一台 Mac。这涉及到从我的时光机中挖出一根旧的 DB-9 串口电缆,以及一个 RS-232 转 USB 适配器。在 Mac 上,我启动了 Minicom:什么也没有。
即使在通电的那一刻,串口也没有任何输出。这非常令人失望,但我知道我在订购它时可能需要付出一些努力,因此我花了一些时间在里面寻找任何明显烧毁的东西,然后尝试使用维修手册和万用表进行修复。值得庆幸的是,互联网上有几个很棒的 Sun 文档存档——这很方便,因为 Oracle 似乎真的竭尽全力地从历史上抹去所有 Sun 存在的痕迹。
可悲的是,维修手册没有关于维修主板的信息,只是声明它是一个“整体单元更换”。
有很多非常古老的论坛,人们讨论 JavaStation 的各种问题,但他们都关心的是可以正常工作的设备。
经过一些不尽如人意的调查后,我开始担心它出了严重的问题,需要使用示波器和逻辑分析仪进行全新级别的调查。我也远没有足够经验来完成这类事情,无法确信我能修复它,所以它成为了又一个复活美丽旧技术的失败尝试的纪念碑。
每当我想到再试一次时,我就会想起以前修复其他设备失败的经历,我无法忍受花费那么多时间尝试修复和更换组件,结果到最后仍然无法工作。
几个月后,我再次受到启发,并想看看是否有任何关于人们使用 JavaStation 的视频。我找到了一段关于一个家伙拆解 Mr Coffee 的视频,尽管他很擅长进入这个东西,但我还是看完了。
这个人显然对这个话题很了解,并指出电池备份的 NVRAM 很可能有一个没电的电池。这是我熟悉的事情,因为我过去曾复活过一些旧的 IPC/IPX 盒子。但随后他说了一些神奇的话:如果电池没电了,它根本不会启动,你需要使用串口终端对其进行配置。好吧,我曾经使用串口终端寻找生命迹象,但什么也没有。但是当我看到他做同样的事情时,我注意到了一些不同:在串口上出现任何东西之前,需要相当长的时间。大约一分钟。此外,我还没有费心检查所需的波特率(我已经很久没有担心过这些东西了)。那么,如果我的波特率错误,而且也没有等待足够长的时间才能看到任何传输,会怎么样呢?你可能知道接下来我要说什么,是的,我的 JavaStation 唯一的问题原来是一个没电的 NVRAM 电池和我缺乏耐心。使用 9600 波特率的串口连接并耐心等待后,我很高兴地收到了关于 NVRAM 损坏的一些抱怨,然后是一个“ok”提示符。
我无法向你传达看到这个时我有多么兴奋。即使我无法让这个东西启动操作系统,我也有一个可爱的基于串口的 FORTH 解释器可以玩。如果你对最后一句话感到困惑,你需要知道 Sun 在那个时期的引导加载程序环境被称为 OpenBoot,它由一个 FORTH 解释器组成,你可以从中查询设备树,并做几乎任何你想做的事情。在这一点上,JavaStation 是一台功能正常的计算机,这本身就足够了——但让它运行一个实际的操作系统将是一个不错的有趣项目。
经过一番 Google 搜索后,我选择了 NetBSD;他们的文档非常全面(BSD 经常如此),而且似乎即使在最新版本 (10.1) 中,不仅支持 SPARC,还专门支持 JavaStation。
在做任何事情之前,我们必须处理 NVRAM 电池没电的问题。没电的电池意味着,只要断电,NVRAM 中的数据就会丢失,导致垃圾内存内容。当机器启动时,它会对 NVRAM 数据的一部分(称为 IDPROM)执行校验和,如果校验和不正确,则将其重置为默认值。因此,在我们更换电池之前[这将在以后的文章中讨论],我们每次启动时都必须给 IDPROM 一些合理的(ish)值。值得庆幸的是,这非常简单,我们可以在“ok”提示符下完成所有操作。以下是它的外观:
ok 01 00 mkp
ok real-machine-type 01 mkp
ok 8 02 mkp
ok 0 03 mkp
ok 20 04 mkp
ok b0 05 mkp
ok 0b 06 mkp
ok 13 07 mkp
ok 0 08 mkp
ok 0 09 mkp
ok 0 0a mkp
ok 0 0b mkp
ok b0 0c mkp
ok 0b 0d mkp
ok 13 0e mkp
ok 0 f 0 do i idprom@ xor loop f mkp
这看起来非常复杂,但实际上非常简单。如果你不感兴趣,请跳过本节。
如上所述,我们位于一个 FORTH 解释器中,但即使你从未听说过(甚至从未听说过)FORTH,它也很容易理解,但当你第一次处理它时会有点奇怪。
“mkp”命令接受它之前的两个数字,并将第一个数字写入 IDPROM 中第二个数字的地址。因此,例如,下面的第一行“01 00 mkp”将值 1 写入地址 0。下面是对我们正在写入的数字的含义的解释:
如果你想知道我们如何知道将什么数据写入何处,请参阅 https://shrubbery.net/~heas/sun-feh-2_1/Devices/IDPROM/IDPROM_Overview.html 上的便捷指南。我正在使用的 MAC 地址是虚构的,但前三个字节 (08-00-20) 实际上是此设备的正确 Sun OUI。
“checksum”行更复杂:这是一个微小的 FORTH 程序,用于生成校验和并将其写入地址 0xF。弄清楚它是如何工作的可以留给读者作为练习。
因此,在输入这些命令后,我们已将配置写入 IDPROM,该配置足够有效,可以允许其启动。现在我们必须在不移除电源的情况下重新启动,因此我们输入“reset”。
JavaStation 重新启动,这次它很高兴开始使用其内置显示器(通过 VGA 端口):
是的!所以它对配置感到满意,但现在我们必须让它启动。它没有自己的存储,因此需要通过网络启动。
网络启动过程如下:
- JavaStation 尝试使用古老的 RARP 协议获取 IP 地址。
- 一旦它有了 IP 地址,它会想当然地认为,无论哪台机器给它 IP 地址,也将能够使用 tftp 提供第二阶段引导加载程序,并尝试获取它。
- 如果它设法通过 tftp 获取第二阶段引导加载程序,它会运行它。
- 然后,第二阶段引导加载程序尝试使用 NFS 获取并运行内核和文件系统。
除了原始的 Sun 文档外,NetBSD 还在 https://www.netbsd.org/docs/network/netboot 提供了有关引导无盘机器的出色文档,并且在该文档中,有针对特定架构和机器(包括 JavaStation)的小节。
应该很容易看出,网络启动需要网络上其他计算机的支持。NetBSD 文档描述了如何使用一堆不同的操作系统来实现这一点,但由于我手头有几个 Linux 盒子,所以我使用了它们。
首先,我们需要响应 JavaStation 的 RARP 请求。这是一个非常古老的标准,Linux 使用名为“rarpd”的软件很好地支持它。在 Ubuntu 上,你可以使用简单的命令安装它:
sudo apt install rarpd
安装完成后,你只需要编辑一个文件来配置它:/etc/ethers。只需向该文件添加一行,其中包含 JavaStation 的 MAC 地址、一个空格以及你希望它在网络上拥有的 IP 地址。在我的例子中:
08:00:20:B0:0B:13 192.168.128.45
MAC 地址由你在上面的步骤中配置到 NVRAM 中的内容定义。
接下来,我们需要能够通过 tftp 提供第二阶段引导加载程序。这也出奇地容易。在 Ubuntu 上,使用以下命令安装 tftpd:
sudo apt install tftpd
NetBSD 提供了专门用于 SPARC/JavaStation 的第二阶段引导加载程序;最新的 NetBSD 版本 (10.1) 位于 https://cdn.netbsd.org/pub/NetBSD/NetBSD-10.1/sparc/installation/netboot/。 bootjs.net 专门用于 JavaStation,但它显然是为比我的更新的 JavaStation 版本设计的,因为当我尝试时,它失败并显示“illegal instruction”错误。相反,我使用了 boot.net 版本,它可以正常工作。你需要使用特定格式重命名该文件:JavaStation 的 IP 地址,但采用 8 位大写十六进制数字,后跟一个点,然后是架构(在本例中为“SUN4M”)。因此,在本示例中,IP 地址(如上面 rarpd 中定义的那样)为 192.168.128.45,十六进制为 C0A8802D。我使用以下命令下载并重命名了引导加载程序:
curl -o /tftpboot/C0A8802D.SUN4M https://cdn.netbsd.org/pub/NetBSD/NetBSD-10.1/sparc/installation/netboot/boot.net
这应该是让第二阶段引导加载程序运行所需的一切。在这一点上,最好给 JavaStation 一个名称,这样我们就不必在进一步的配置中不断使用 IP 地址来引用它。在我的例子中,我想给它命名为“duke”,因此将以下内容添加到 /etc/hosts 文件中:
192.168.128.45 duke
引导的下一阶段涉及 JavaStation 执行 DHCP 请求,以便找到它要从中引导的 NFS 服务器。像大多数人一样,我已经在我局域网上使用 DHCP 来配置一切,但 DHCP 服务器在我的路由器上运行,而 NFS 服务器在另一台 Linux 机器上运行。因此,DHCP 服务器的响应需要包含一个字段 (“siaddr”),该字段引用 NFS 服务器的地址。虽然应该可以配置路由器的 DHCP 服务器来执行此操作,但我很难做到。所以相反,我决定配置路由器以忽略此 MAC 地址,而是在 Linux 机器上运行 DHCP 服务器。你可以使用以下命令在 Ubuntu 上安装 ISC dhcp 服务器:
sudo apt install isc-dhcp-server
然后将一个条目添加到 /etc/dhcp/dhcpd.conf 中,如下所示:
subnet 192.168.128.0 netmask 255.255.255.0 {
class "javastation-class" {
lease limit 1;
default-lease-time 3600;
max-lease-time 7200;
}
pool {
allow members of "javastation-class";
range dynamic-bootp 192.168.128.45 192.168.128.45;
}
host duke {
hardware ethernet 08:00:20:B0:0B:13;
fixed-address 192.168.128.45;
option routers 192.168.128.1;
option root-path "/export/client/root";
}
}
“host duke”部分包含我们需要 JavaStation 拥有的配置。除了 fixed-address 之外,我们还为它提供了 NFS 共享的路径,这些共享将位于同一台机器上。由于我们专门提供了一个“hardware ethernet”地址,因此此配置将仅提供给我们的 JavaStation,所有其他客户端将被忽略,让路由器 DHCP 服务器像往常一样处理其他所有事情。
最后,我们需要使用 NFS 提供 NetBSD 文件系统。值得庆幸的是,尽管它已经很老旧并且完全缺乏安全性,但 Linux 仍然很好地支持 NFS。简而言之,以下是如何设置文件系统。这些说明来自 NetBSD 的出色文档: https://www.netbsd.org/docs/network/netboot/nfs.html#linux
这些说明假定我们将文件系统托管在 /export/client,但只要你记得将路径添加到上面的 DHCP 配置中,你将它放在哪里真的取决于你。
# mkdir -p /export/client/root/dev
# mkdir /export/client/usr
# mkdir /export/client/home
# cd /export/client/root
# curl -L https://cdn.netbsd.org/pub/NetBSD/NetBSD-10.1/sparc/binary/sets/kern-MRCOFFEE.tgz | tar xvpzf -
# mknod /export/client/root/dev/console c 0 0
我建议将内核从“netbsd”重命名为“kona”,这是 JavaStation 使用的默认名称:
# mv netbsd kona
将以下行添加到 /etc/exports:
/export/client/root duke(rw,no_root_squash)
/export/client/usr duke(rw,root_squash)
/export/client/home duke(rw,root_squash)
显然,将“duke”替换为你为 JavaStation 命名的名称。
# cd /export/client/root
# curl -L https://cdn.netbsd.org/pub/NetBSD/NetBSD-10.1/sparc/binary/sets/base.tgz | tar zxvpf -
# curl -L https://cdn.netbsd.org/pub/NetBSD/NetBSD-10.1/sparc/binary/sets/etc.tgz | tar zxvpf -
# mkdir /export/client/root/kern
# dd if=/dev/zero of=/export/client/swap bs=4k count=4k
创建/编辑 /export/client/root/etc/ifconfig.<以太网设备名称>,在本例中为 ifconfig.le0,并添加以下行(为你的网络设置网络掩码和广播):
inet duke netmask 255.255.255.0 broadcast 192.168.1.255
创建/编辑 /export/client/root/etc/fstab,并添加以下行:
/swap none swap sw 0 0
nfsserver:/export/client/root / nfs rw 0 0
nfsserver:/export/client/usr /usr nfs rw 0 0
nfsserver:/export/client/home /home nfs rw 0 0
编辑 /export/client/root/etc/rc.conf。确保已设置以下内容:
hostname="client"
defaultroute="192.168.128.1"
nfs_client=YES
auto_ifconfig=NO
net_interfaces=""
将以下行添加到 /export/client/root/etc/hosts:
192.168.1.10 client.test.net client
192.168.1.5 nfsserver.test.net nfsserver
然后:
# mv /export/client/root/usr/* /export/client/usr/
如今,Linux 内核具有内置的 NFS 服务器,因此不需要额外的守护程序。你只需要确保已安装 kernel-server:
# apt install nfs-kernel-server
为了确保导出的文件系统确实已导出,你可以强制 NFS 服务器重新读取 /etc/exports:
exportfs -r
现在一切都应该到位了。因此,我们准备好尝试引导系统了。将以太网电缆插入 JavaStation,并在 ok 提示符下键入“reset”。如果一切顺利,应该获取并执行 NetBSD 第二阶段引导加载程序。
如果出现任何问题,你可以通过嗅探网络流量来了解发生了什么。就我个人而言,我更喜欢使用 tcpdump 进行捕获,然后在我的笔记本电脑上使用 Wireshark 分析转储:tcpdump 体积小且无头。例如,运行:
tcpdump -n -s0 -w boot.pcap host duke
这将创建一个捕获文件,该文件将直接加载到 Wireshark 或任何其他与 pcap 兼容的分析器中。以下是预期的内容。
最初,你将看到 RARP 响应,因为 Linux 机器告诉 JavaStation 它的 IP 地址。接下来,你将看到 JavaStation 使用 TFTP 请求第二阶段引导加载程序:
如果引导加载程序传输成功,你将看到 DHCP 事务,然后是 NFS 流量:
如果一切顺利,当你第一次引导 NetBSD 时,系统会提示你按回车键:
此时,你正在单用户模式下运行一个未配置的 NetBSD 版本。只剩下两件事要做。首先,在 dev 中创建所有特殊的设备文件:
# mount /usr
# cd /dev
# /bin/sh MAKEDEV all
这比你想象的要花费更长的时间——通过 10Mbps 的 NFS 很慢……
最后,编辑 /etc/rc.conf 并将以“rc_configured”开头的行更改为“rc_configured=yes”。注意:在你运行像 vi 这样的编辑器之前,你可能需要将终端类型设置为通用的:
# export TERM=vt100
# vi /etc/rc.conf
最后,重新启动系统:
# reboot
如果宇宙表现正常,系统将重新启动,你将获得一个登录提示。以 root 身份登录,无需密码,你就可以开始工作了!
显然,还有很多事情要做;正如你所看到的,postfix 不高兴,并且需要加强 swapfile 的安全性才能启动。但是我们现在有一个在老式网络计算机上运行的功能正常的 NetBSD 系统!