
Минимальная архитектура машины с бэкендом компилятора LLVM, портом для Linux и виртуальной машиной для создания самодостаточных программных капсул, которые остаются работоспособными неограниченно долго без сложных зависимостей.
Это корневой репозиторий Eternal Software Initiative.
ESI определяет минимальную машинную архитектуру (основанную на модификации Subleq OISC), настолько простую, что её полная спецификация может быть записана на салфетке. Затем мы предоставляем бэкенд компилятора LLVM для этой архитектуры, порт Linux, порты библиотек времени выполнения C/C++ и другие инструменты (включая эталонную реализацию виртуальной машины примерно в 50 строках C), необходимые для сборки и запуска самодостаточной «капсулы» из существующего программного обеспечения.
В чём смысл всего этого? Запуск современного программного обеспечения требует сложного стека зависимостей (компиляторы, библиотеки, фреймворки, ОС) поверх проприетарного и неполно документированного оборудования, что делает очень трудным обеспечение того, что сегодняшнее программное обеспечение продолжит работать в будущем. Эта проблема «гниения битов» хорошо известна любому, кто поддерживает устаревшее программное обеспечение на протяжении лет или десятилетий, но теперь представьте историка через 1000 лет, пытающегося понять жизнь XXI века, значительная часть которой переживается через программное обеспечение. Даже если бинарные файлы сегодняшнего программного обеспечения сохранены, трудно вообразить, что эти бинарники всё ещё можно будет запустить. Эмуляторы вроде QEMU лишь перемещают эту проблему, но не решают её: у них тоже есть аналогично сложный стек программных и аппаратных зависимостей, и поэтому они также не будут запускаться в далёком будущем.
ESI решает эту проблему путём (1) определения архитектуры, достаточно простой, чтобы записать её на салфетке, но достаточно мощной, чтобы эффективно представлять любое программное обеспечение, и при этом не требующей знания какого-либо проприетарного оборудования, программного обеспечения, фреймворков и так далее, и (2) реализации инструментальной цепочки для компиляции любого существующего программного обеспечения в самодостаточную «капсулу» для этой архитектуры. Это гарантирует, что при условии сохранения бинарного файла капсулы и инструкций на салфетке программное обеспечение можно будет возродить и испытать в далёком будущем, не предполагая никаких знаний о современных вычислительных системах.
Этот репозиторий включает всё необходимое для сборки и запуска вашей собственной машины ESI, а также для сборки «капсул» ESI из существующего программного обеспечения.
Для получения дополнительной информации о миссии ESI см.: https://www.eternal-software.org
Этот репозиторий включает в качестве подмодулей форки ESI инструментальной цепочки LLVM, ядра Linux, uClibc-ng и Busybox. Все они должны быть получены вместе.
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 по завершении, чтобы остановить виртуальную машину.
Стандартный процесс кросс-компиляции. Для быстрого старта мы предоставляем вспомогательный скрипт (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
Предоставлена для разработчиков сегодняшнего дня, чтобы понимать архитектуру и инструментальную цепочку. Ничто из этого (кроме салфетки) не нужно кому-то через 1000 лет для возрождения капсулы и запуска программного обеспечения внутри неё.