基于 Subleq 单指令集计算机的永恒软件计划
Eternal Software Initiative Based on Subleq One-Instruction-Set Computer

原始链接: https://github.com/adriancable/eternal

“永恒软件倡议”(ESI)旨在解决日益严重的“比特腐烂”(bit rot)问题,即软件因复杂且专有的软硬件依赖关系崩溃而无法运行。 为了确保软件能够留存数百年,ESI 定义了一种极简计算机架构——一种修改过的 Subleq OISC,其规范简单到可以写在餐巾纸上。通过提供定制的 LLVM 工具链、移植的 Linux 内核和 C 语言库,ESI 让开发者能够将软件封装进独立的“胶囊”中。 这些胶囊配合餐巾纸般简单的架构规范,消除了对现代脆弱生态系统的依赖。由于 ESI 虚拟机极其易于实现(甚至可以在不到 400 字节的 C 代码中完成),未来世代无需了解当前复杂的计算系统,就能复原并体验 21 世纪的软件。本仓库提供了构建这些永恒胶囊所需的完整工具链及参考实现。

“永恒软件计划”(Eternal Software Initiative)是阿德里安·卡布尔(Adrian Cable)发起的一个项目,旨在利用基于 Subleq 的单指令集计算机(OISC)架构,作为一种通用格式,为未来文明保存 21 世纪的软件。其构想是将软件存储为简单的数字列表,从理论上讲,这些数字可以在未来的硬件上还原。 该项目在 Hacker News 上引发了关于其可行性的争论。批评者认为,该项目提供的文档在技术上存在歧义,特别是在处理“读取按键”等输入输出(I/O)操作方面。更根本的问题是,怀疑论者指出,仅保存二进制文件并不能解决环境兼容性的难题。由于现代软件高度依赖特定的硬件时序、未记录的操作系统行为以及复杂的输入输出特性,简单的 Subleq 虚拟机很难足以运行大多数旧版程序。另一些人则认为,该项目是一项有趣但局限的“从零构建”计算实验,并指出虽然虚拟机实现起来很简单,但它未能弥合原始指令集与现代软件对复杂运行环境依赖之间的巨大鸿沟。
相关文章

原文

This is the root repository for the Eternal Software Initiative.

The ESI defines a minimal machine architecture (based on a modification of the Subleq OISC) that is so simple that its complete specification can be written down on a napkin. We then provide an LLVM compiler backend for this architecture, a port of Linux, ports of the C/C++ runtime libraries, and other tools (including a reference virtual machine implementation in ~50 lines of C) required to build and run a self-contained 'capsule' from existing software.

What's the point of all this? Running today's software requires a complex stack of dependencies (compilers, libraries, frameworks, OS) on top of proprietary and incompletely documented hardware, making it very difficult to ensure that today's software will continue to operate in the future. This problem of 'bit rot' is well known to anyone maintaining legacy software over a timespan of years or decades, but now imagine a historian 1,000 years from now trying to understand 21st century life, much of which is experienced through software. Even if today's software binaries are preserved, it is far fetched to imagine those binaries will still be runnable. Emulators like QEMU move this problem around but do not solve it: they too have a similarly complex stack of software and hardware dependencies, and so also won't be runnable in the far future.

The ESI solves this problem by (1) defining an architecture that is simple enough to write down on a napkin but powerful enough to efficiently represent any software, but does not require knowledge of any proprietary hardware, software, frameworks and so forth, and (2) implementing a toolchain to compile any existing software into a self-contained 'capsule' for this architecture. This ensures that, providing the capsule binary and the napkin instructions are preserved, the software can be revived and experienced in the far future without assuming any knowledge of present day computing systems.

This repository includes everything needed to build and run your own ESI machine, and build ESI 'capsules' from existing software.

For more information on the ESI's mission, see: https://www.eternal-software.org

This repository includes, as submodules, ESI forks of the LLVM toolchain, the Linux kernel, uClibc-ng, and Busybox. These must all be checked out together.

git clone --recurse-submodules https://github.com/adriancable/eternal

You will need SDL3 to build the ESI virtual machine. Install with e.g. apt install libsdl3-dev. There are no other dependencies. SDL3 can easily be replaced with any other means for writing pixels and capturing keyboard events, now or in the future.

cd eternal/vm
make

xz -d ../capsules/vmlinux.bootimage.xz
./vm ../capsules/vmlinux.bootimage

When Linux has booted, try for example:

The ESI toolchain should build on any Linux system with minimal effort. We have also successfully built on macOS, with some modifications. Make sure you have gcc, python3, CMake, ninja, flex, bison installed and operational.

Start in the checked-out eternal folder.

rm -rf llvm-project/build && mkdir -p llvm-project/build
cmake -G Ninja -S llvm-project/llvm -B llvm-project/build -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_BUILD_TOOLS=ON -DLLVM_ENABLE_ASSERTIONS=OFF -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="Subleq" -DLLVM_DEFAULT_TARGET_TRIPLE="subleq-unknown-linux" -DLLVM_FORCE_VC_REPOSITORY="ESI" -DLLVM_FORCE_VC_REVISION=""

cd llvm-project/build
ninja llc clang llvm-mc lld llvm-objcopy llvm-ar llvm-ranlib llvm-nm llvm-readelf llvm-strip llvm-objdump

Step 2: Install Linux Kernel Headers

cd ../../linux
make ARCH=subleq \
  CC=../llvm-project/build/bin/clang \
  LD=../llvm-project/build/bin/ld.lld \
  AR=../llvm-project/build/bin/llvm-ar \
  NM=../llvm-project/build/bin/llvm-nm \
  OBJCOPY=../llvm-project/build/bin/llvm-objcopy \
  INSTALL_HDR_PATH=../runtime/sysroot/kernel-headers \
  headers_install

Step 3: Build and Install ESI C Runtime (uClibc-ng)

cd ../uclibc-ng
make ARCH=subleq defconfig

make ARCH=subleq \
  CC=../llvm-project/build/bin/clang \
  LD=../llvm-project/build/bin/ld.lld \
  AR=../llvm-project/build/bin/llvm-ar \
  NM=../llvm-project/build/bin/llvm-nm \
  PREFIX=../runtime/sysroot \
  STRIPTOOL=../llvm-project/build/bin/llvm-strip \
  DEVEL_PREFIX=/ \
  install_dev

Step 4: Build ESI Core Runtimes (CPU, FPU, C++)

cd ../runtime
./build_and_install_runtime.sh
./build_libcxx.sh
ninja -C ./libcxx install
cd ../busybox
make subleq_defconfig

make CC=../llvm-project/build/bin/clang \
     AR=../llvm-project/build/bin/llvm-ar \
     STRIP=../llvm-project/build/bin/llvm-strip

mkdir ../initramfs_root/bin
cp busybox ../initramfs_root/bin/busybox
cd ../linux
export KBUILD_BUILD_USER="root"
export KBUILD_BUILD_HOST="eternal"

make ARCH=subleq \
  CC=../llvm-project/build/bin/clang \
  LD=../llvm-project/build/bin/ld.lld \
  AR=../llvm-project/build/bin/llvm-ar \
  NM=../llvm-project/build/bin/llvm-nm \
  OBJCOPY=../llvm-project/build/bin/llvm-objcopy \
  defconfig

make ARCH=subleq \
  CC=../llvm-project/build/bin/clang \
  LD=../llvm-project/build/bin/ld.lld \
  AR=../llvm-project/build/bin/llvm-ar \
  NM=../llvm-project/build/bin/llvm-nm \
  OBJCOPY=../llvm-project/build/bin/llvm-objcopy

Step 7: Build Capsule and Run VM

cd ..
python3 tools/make_boot_image.py --stack-size 536870912 linux/vmlinux
./vm/vm linux/vmlinux.bootimage

Type exit when done to terminate the VM.

Standard cross-compilation workflow. To get started quickly, we provide a convenience script (clang_userspace.sh) that sets up the environment and calls clang.

cat << 'EOF' > hello.c
#include <stdio.h>

int main() {
    printf("Hello, ESI world!\n");
    return 0;
}
EOF

tools/clang_userspace.sh hello.c
cp hello.elf initramfs_root/root

Then rebuild the initramfs and capsule:

cd linux
make ARCH=subleq \
  CC=../llvm-project/build/bin/clang \
  LD=../llvm-project/build/bin/ld.lld \
  AR=../llvm-project/build/bin/llvm-ar \
  NM=../llvm-project/build/bin/llvm-nm \
  OBJCOPY=../llvm-project/build/bin/llvm-objcopy

cd ..
python3 tools/make_boot_image.py --stack-size 536870912 linux/vmlinux

Boot the VM:

./vm/vm linux/vmlinux.bootimage

Once Linux is booted:

Provided for developers of today to understand the architecture and toolchain. None of this (except the napkin) is needed for someone 1,000 years from now to revive a capsule and run the software within.

If you've ported the ESI virtual machine to a new platform, please let us know by filing an Issue and we will add it to this list.

A minified version of the ESI virtual machine (in 366 bytes of C) was a winner of the 29th IOCCC competition.

联系我们 contact @ memedata.com