这是永恒软件倡议的根仓库。
ESI 定义了一种最小的机器架构(基于 Subleq OISC 的修改),其完整规范可以写在餐巾纸上。然后我们为此架构提供了一个 LLVM 编译器后端、一个 Linux 移植版、C/C++ 运行时库移植版,以及其他工具(包括一个约 50 行 C 语言的参考虚拟机实现),用于从现有软件构建和运行自包含的“胶囊”。
这一切的意义何在?运行当今的软件需要一个复杂的依赖栈(编译器、库、框架、操作系统),并且依赖于专有且文档不完整的硬件,这使得确保当今软件在未来仍能运行变得非常困难。任何在数年或数十年间维护遗留软件的人都深知“比特腐烂”这一问题,但想象一下,一千年后的历史学家试图理解 21 世纪的生活,而其中很大一部分是通过软件体验的。即使当今的软件二进制文件被保存下来,也很难想象这些二进制文件仍然可以运行。像 QEMU 这样的模拟器只是转移了问题,但并未解决:它们同样拥有复杂的软件和硬件依赖栈,因此在遥远的未来也无法运行。
ESI 通过以下方式解决这个问题:(1) 定义一种足够简单且可写在餐巾纸上、但又足够强大以高效表示任何软件的架构,且无需了解任何专有硬件、软件、框架等;(2) 实现一个工具链,将任何现有软件编译成针对此架构的自包含“胶囊”。这确保了只要保留了胶囊二进制文件和餐巾纸说明,软件就能在遥远的未来被复活并体验,而无需假设了解当今的计算系统。
此仓库包含了构建和运行你自己的 ESI 机器,以及从现有软件构建 ESI“胶囊”所需的一切。
更多关于 ESI 使命的信息,请见:https://www.eternal-software.org
此仓库以子模块形式包含了 LLVM 工具链、Linux 内核、uClibc-ng 和 Busybox 的 ESI 分支。它们必须一起检出。
git clone --recurse-submodules https://github.com/adriancable/eternal
你需要 SDL3 来构建 ESI 虚拟机。例如,使用 apt install libsdl3-dev 安装。没有其他依赖。现在或将来,SDL3 可以很容易地被任何其他用于写入像素和捕获键盘事件的方式替代。
cd eternal/vm
make
xz -d ../capsules/vmlinux.bootimage.xz
./vm ../capsules/vmlinux.bootimage
当 Linux 启动后,例如可以尝试:
cd doom
./doom
ESI 工具链应在任何 Linux 系统上轻松构建。我们也在 macOS 上成功构建,但需要一些修改。确保你已安装并运行了 gcc、python3、CMake、ninja、flex、bison。
在检出的 eternal 文件夹中开始。
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
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
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
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
cd ..
python3 tools/make_boot_image.py --stack-size 536870912 linux/vmlinux
./vm/vm linux/vmlinux.bootimage
完成后输入 exit 以终止虚拟机。
标准交叉编译工作流程。为快速上手,我们提供了一个便利脚本 (clang_userspace.sh),用于设置环境并调用 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
然后重建 initramfs 和胶囊:
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
启动虚拟机:
./vm/vm linux/vmlinux.bootimage
Linux 启动后:
./hello.elf
为当今的开发者提供,以理解架构和工具链。一千年后的人复活胶囊并运行其中的软件时,这些(除了餐巾纸说明)都不需要。
如果你已将 ESI 虚拟机移植到新平台,请通过提交 Issue 告知我们,我们会将其添加到本列表中。
ESI 虚拟机的一个精简版(366 字节 C 语言)荣获了第 29 届 IOCCC 竞赛的优胜。