
Architecture machine minimale avec backend de compilateur LLVM, port Linux et machine virtuelle pour créer des capsules logicielles autonomes qui restent exécutables indéfiniment sans dépendances complexes.
Ceci est le dépôt racine de l'Initiative du Logiciel Éternel.
L'ESI définit une architecture machine minimale (basée sur une modification du Subleq OISC) si simple que sa spécification complète peut être écrite sur une serviette. Nous fournissons ensuite un backend de compilateur LLVM pour cette architecture, un port de Linux, des ports des bibliothèques runtime C/C++, et d'autres outils (dont une implémentation de machine virtuelle de référence en ~50 lignes de C) nécessaires pour construire et exécuter une 'capsule' autonome à partir d'un logiciel existant.
Quel est l'intérêt de tout cela ? Exécuter les logiciels d'aujourd'hui nécessite une pile complexe de dépendances (compilateurs, bibliothèques, frameworks, OS) sur du matériel propriétaire et incomplètement documenté, rendant très difficile d'assurer que ces logiciels continueront de fonctionner dans le futur. Ce problème de 'pourriture numérique' est bien connu de quiconque maintient des logiciels hérités sur des années ou des décennies, mais imaginez maintenant un historien dans 1 000 ans essayant de comprendre la vie du 21e siècle, dont une grande partie est vécue à travers des logiciels. Même si les binaires des logiciels d'aujourd'hui sont préservés, il est peu probable que ces binaires soient encore exécutables. Les émulateurs comme QEMU déplacent ce problème mais ne le résolvent pas : ils ont eux aussi une pile complexe de dépendances logicielles et matérielles, et ne seront donc pas exécutables dans un futur lointain.
L'ESI résout ce problème en (1) définissant une architecture assez simple pour être écrite sur une serviette mais assez puissante pour représenter efficacement n'importe quel logiciel, sans nécessiter la connaissance d'aucun matériel propriétaire, logiciel, framework, etc., et (2) en implémentant une chaîne d'outils pour compiler tout logiciel existant en une 'capsule' autonome pour cette architecture. Cela garantit que, pourvu que le binaire de la capsule et les instructions de la serviette soient préservés, le logiciel peut être ranimé et expérimenté dans un futur lointain sans supposer aucune connaissance des systèmes informatiques actuels.
Ce dépôt contient tout le nécessaire pour construire et exécuter votre propre machine ESI, et construire des 'capsules' ESI à partir de logiciels existants.
Pour plus d'informations sur la mission de l'ESI, voir : https://www.eternal-software.org
Ce dépôt inclut, en tant que sous-modules, des forks ESI de la chaîne d'outils LLVM, du noyau Linux, de uClibc-ng et de Busybox. Ils doivent tous être récupérés ensemble.
git clone --recurse-submodules https://github.com/adriancable/eternal
Vous aurez besoin de SDL3 pour construire la machine virtuelle ESI. Installez avec par exemple apt install libsdl3-dev. Il n'y a pas d'autres dépendances. SDL3 peut facilement être remplacé par tout autre moyen d'écrire des pixels et de capturer les événements clavier, maintenant ou dans le futur.
cd eternal/vm
make
xz -d ../capsules/vmlinux.bootimage.xz
./vm ../capsules/vmlinux.bootimage
Quand Linux a démarré, essayez par exemple :
cd doom
./doom
La chaîne d'outils ESI devrait se construire sur n'importe quel système Linux avec un effort minimal. Nous l'avons également construite avec succès sur macOS, avec quelques modifications. Assurez-vous d'avoir gcc, python3, CMake, ninja, flex, bison installés et opérationnels.
Commencez dans le dossier eternal récupéré.
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
Tapez exit une fois terminé pour terminer la VM.
Flux de travail standard de cross-compilation. Pour démarrer rapidement, nous fournissons un script pratique (clang_userspace.sh) qui configure l'environnement et appelle 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
Reconstruisez ensuite l'initramfs et la 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
Démarrez la VM :
./vm/vm linux/vmlinux.bootimage
Une fois Linux démarré :
./hello.elf
Fournie pour que les développeurs d'aujourd'hui comprennent l'architecture et la chaîne d'outils. Rien de tout cela (sauf la serviette) n'est nécessaire pour quelqu'un dans 1 000 ans pour ranimer une capsule et exécuter le logiciel qu'elle contient.
Si vous avez porté la machine virtuelle ESI sur une nouvelle plateforme, veuillez nous le signaler en soumettant un Issue et nous l'ajouterons à cette liste.
Une version minifiée de la machine virtuelle ESI (en 366 octets de C) a été lauréate du 29e concours IOCCC.