
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'Eternal Software Initiative.
L'ESI définit une architecture machine minimale (basée sur une modification du Subleq OISC) qui est 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 portage de Linux, des portages des bibliothèques d'exécution C/C++, et d'autres outils (y compris 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 de logiciels existants.
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) au-dessus de matériels propriétaires et incomplètement documentés, ce qui rend très difficile de garantir que les logiciels d'aujourd'hui continueront de fonctionner à l'avenir. Ce problème de « bit rot » (pourrissement des bits) est bien connu de quiconque maintient des logiciels hérités sur une période de plusieurs années ou décennies, mais imaginez maintenant un historien dans 1 000 ans essayant de comprendre la vie du XXIe 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 d'imaginer que ces binaires seront encore exécutables. Des émulateurs comme QEMU déplacent ce problème mais ne le résolvent pas : eux aussi ont une pile tout aussi complexe de dépendances logicielles et matérielles, et ne seront donc pas non plus exécutables dans un futur lointain.
L'ESI résout ce problème en (1) définissant une architecture suffisamment simple pour être écrite sur une serviette mais suffisamment puissante pour représenter efficacement n'importe quel logiciel, sans exiger la connaissance d'un quelconque matériel, logiciel, framework propriétaire, etc., et (2) en implémentant une chaîne d'outils pour compiler n'importe quel logiciel existant en une « capsule » autonome pour cette architecture. Cela garantit que, à condition que le binaire de la capsule et les instructions de la serviette soient préservés, le logiciel peut être ressuscité et expérimenté dans un futur lointain sans présumer aucune connaissance des systèmes informatiques actuels.
Ce dépôt inclut tout ce qui est 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, d'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 des événements clavier, maintenant ou à l'avenir.
cd eternal/vm
make
xz -d ../capsules/vmlinux.bootimage.xz
./vm ../capsules/vmlinux.bootimage
Une fois Linux 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 avons également réussi à la construire 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 lorsque vous avez terminé pour arrêter la VM.
Flux de travail de compilation croisée standard. Pour démarrer rapidement, nous fournissons un script de commodité (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 (à l'exception de la serviette) n'est nécessaire pour que quelqu'un dans 1 000 ans puisse ressusciter une capsule et exécuter le logiciel qu'elle contient.