
最小限のマシンアーキテクチャ、LLVMコンパイラバックエンド、Linux移植版、および仮想マシンを備え、複雑な依存関係なしに無期限に実行可能な自己完結型ソフトウェアカプセルを作成します。
これは Eternal Software Initiative のルートリポジトリです。
ESI は、その完全な仕様をナプキンに書き留めることができるほど単純な、最小限のマシンアーキテクチャ(Subleq OISC の改変に基づく)を定義しています。そして、このアーキテクチャ向けの LLVM コンパイラバックエンド、Linux の移植、C/C++ ランタイムライブラリの移植、および既存のソフトウェアから自己完結型の「カプセル」をビルドして実行するために必要なその他のツール(約50行の C によるリファレンス仮想マシン実装を含む)を提供しています。
これは一体何のためでしょうか?今日のソフトウェアを実行するには、プロプライエタリで不完全にしか文書化されていないハードウェアの上に、複雑な依存関係のスタック(コンパイラ、ライブラリ、フレームワーク、OS)が必要であり、今日のソフトウェアが将来にわたって動作し続けることを保証するのは非常に困難です。この「ビットロット」問題は、何年あるいは何十年にもわたってレガシーソフトウェアを保守している人なら誰でもよく知っていますが、ここで1,000年後の歴史家が、その多くがソフトウェアを通じて体験される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
ESI 仮想マシンをビルドするには SDL3 が必要です。例えば 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 と入力して VM を終了します。
標準的なクロスコンパイルのワークフローです。すぐに始められるように、環境をセットアップして clang を呼び出す便利なスクリプト (clang_userspace.sh) を提供しています。
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/vm linux/vmlinux.bootimage
Linux が起動したら:
./hello.elf
今日の開発者がアーキテクチャとツールチェーンを理解するために提供されています。1,000年後の誰かがカプセルを復活させてその中のソフトウェアを実行するために、これら(ナプキンを除く)のいずれも必要ありません。
make はチューリング完全なので Subleq VM を実行できますESI 仮想マシンを新しいプラットフォームに移植した場合は、Issue を提出してお知らせください。このリストに追加します。
ESI 仮想マシンの縮小版(C で366バイト)は、第29回 IOCCC コンテストの受賞作品となりました。