
معمارية آلة بسيطة مع خلفية مترجم LLVM، ومنفذ لينكس، وآلة افتراضية لإنشاء كبسولات برمجية ذاتية الاحتواء تبقى قابلة للتشغيل إلى أجل غير مسمى دون تبعيات معقدة.
هذا هو المستودع الجذر لـ مبادرة البرمجيات الأبدية.
تعرّف ESI بنية آلة بسيطة (مبنية على تعديل لـ Subleq OISC) بسيطة لدرجة أن مواصفاتها الكاملة يمكن كتابتها على منديل. ثم نوفر خلفية مُصرِّف LLVM لهذه البنية، ومنفذًا لنواة Linux، ومنافذ لمكتبات وقت التشغيل C/C++، وأدوات أخرى (بما في ذلك تنفيذ مرجعي لآلة افتراضية في حوالي 50 سطرًا من C) مطلوبة لبناء وتشغيل "كبسولة" قائمة بذاتها من برمجيات موجودة.
ما الهدف من كل هذا؟ تشغيل برمجيات اليوم يتطلب حزمة معقدة من التبعيات (مُصرِّفات، ومكتبات، وأطر عمل، ونظام تشغيل) فوق عتاد احتكاري وموثّق بشكل غير كامل، مما يجعل من الصعب جدًا ضمان استمرار عمل برمجيات اليوم في المستقبل. مشكلة "التلف الرقمي" هذه معروفة جيدًا لأي شخص يحافظ على برمجيات قديمة على مدى سنوات أو عقود، لكن تخيّل الآن مؤرخًا بعد 1,000 عام يحاول فهم حياة القرن الحادي والعشرين، التي يُعاش الكثير منها عبر البرمجيات. حتى لو حُفظت ملفات برمجيات اليوم التنفيذية، فمن المستبعد جدًا تخيّل أن تظل هذه الملفات قابلة للتشغيل. المحاكيات مثل 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
ستحتاج إلى 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
مُقدَّم لمطوري اليوم لفهم البنية وسلسلة الأدوات. لا شيء من هذا (باستثناء المنديل) مطلوب لشخص بعد 1,000 عام لإحياء كبسولة وتشغيل البرمجيات بداخلها.
make مكتمل تورينغيًا لذا يمكنه تشغيل آلة Subleq افتراضيةإذا قمت بنقل آلة ESI الافتراضية إلى منصة جديدة، فيرجى إخبارنا بفتح Issue وسنضيفها إلى هذه القائمة.
نسخة مصغّرة من آلة ESI الافتراضية (في 366 بايت من C) كانت من الفائزين في مسابقة IOCCC التاسعة والعشرين.