
محاكٍ لـ RISC-V بلغة Rust يُقلّع Linux مع JIT على ARM64/x86_64 وذاكرة افتراضية Sv39
مُحاكي RISC-V مكتوب بلغة Rust. يقوم بإقلاع لينكس.
ينفذ الجهاز تعليمات RV64IMAFDC مع مستويات الامتياز M/S/U والذاكرة الافتراضية Sv39.
يعمل JIT على مضيفات ARM64 و x86_64، مع العودة إلى المفسر عند الحاجة.
الملحقات هي UART 16550 و CLINT و PLIC و SBI 1.0. يوجد تبعية خارجية واحدة: zstd.
ليس أسرع محاكي. في وضع المفسر، يعمل أبطأ بحوالي ثلاث مرات من QEMU. في وضع JIT، أبطأ بحوالي تسعة وعشرين مرة. لم يتم تنفيذ ربط كتل التعليمات البرمجية بعد؛ سيساعد ذلك. نقول هذا بصراحة لأنك يجب أن تعرف ما الذي تحصل عليه.
ما يفعله بشكل جيد: بسيط التشغيل، يكشف عن واجهة HTTP للتحكم في الجهاز، يمكنه تنفيذ ELF على المعدن العاري بدون نواة، ويمكنه حفظ واستعادة حالة الجهاز بالكامل. هذه أشياء مفيدة لأعمال الأنظمة والاختبار.
cargo build --release
الملف الثنائي هو target/release/emuko. قم بإنشاء اختصار.
alias emuko=target/release/emuko
emuko dow
يقوم بتحميل نواة Debian RISC-V للتمهيد عبر الشبكة و initrd إلى ~/.emuko/.
يتم التحقق من SHA256. لا حاجة لنواة خاصة بك.
emuko start
يعمل المحاكي كخفيّة. يتم إرفاقك بوحدة التحكم الخاصة به. سترى النواة تُقلع. ستحصل على شل.
| المفتاح | التأثير |
|---|---|
| Ctrl+] | افصل (يستمر الخفيّة) |
| Ctrl+C | مقاطعة في الضيف |
| Ctrl+D | نهاية الملف في الضيف |
emuko start # إعادة ربط وحدة التحكم
emuko dump # طباعة حالة وحدة المعالجة المركزية
emuko stop # إيقاف التنفيذ مؤقتًا
emuko con # متابعة
emuko step 1000 # تنفيذ تعليمة واحدة لـ N خطوة
emuko snap # التقاط لقطة
emuko kill # إيقاف التشغيل
يستمع الخفيّة على http://127.0.0.1:7788/v1/api/ ويقبل اتصالات وحدة التحكم عبر WebSocket
على ws://127.0.0.1:7788/v1/ws/uart. كلاهما قابل للاستخدام من البرامج النصية.
أحيانًا لا تريد نظام تشغيل. تريد الجهاز، ملفًا ثنائيًا، ولا شيء بينهما.
emuko run ./my_program.elf
يعيد الخفيّة تعيين الجهاز، ويحمل مقاطع ELF في عناوينها الفعلية، ويبدأ التنفيذ. يصل الإخراج عبر وحدة تحكم UART. يجب أن يكون الخفيّة قيد التشغيل بالفعل.
للكتابة على وحدة التحكم من المعدن العاري: خزِّن بايت عند 0x1000_0000.
يحتوي دليل examples/ على برامج تعمل بهذه الطريقة.
| المثال | الوظيفة |
|---|---|
bare_printf | طباعة رسالة كل 10 ملايين تكرار. بدون libc. كتابة مباشرة إلى UART. |
مطلوب مترجم متقاطع RISC-V لبنائها.
على macOS: brew install riscv64-elf-gcc.
على Linux: apt install gcc-riscv64-linux-gnu.
emuko start
cd examples/bare_printf
make run
يمكن حفظ واستعادة حالة الجهاز — السجلات، الذاكرة، كل شيء.
emuko snap # لقطة الآن
emuko snap 5000000 # لقطة تلقائية كل 5 ملايين خطوة
emuko snap stop # إيقاف اللقطات التلقائية
emuko ls # سرد اللقطات
emuko restore <snapshot> # استعادة
يستخدم الجهاز الظاهري تخطيط MMIO ثابتًا متوافقًا مع منصة QEMU RISC-V virt.
مع الإعدادات الافتراضية (load_addr=0x80200000، 1 GiB من RAM):
0x8000_0000 ── قاعدة RAM
(فجوة — قابلة للاستخدام بواسطة برامج المعدن العاري)
0x8020_0000 ── صورة النواة
│ .text / .rodata / .data / .bss
└─ نهاية النواة
(حر)
── initrd
── DTB
── منطقة EFI (128 KiB، نوى PE/UEFI فقط)
0xBFFF_FFFF ── نهاية RAM
يتم وضع DTB و initrd و EFI لأسفل من أعلى RAM. يتحقق المحاكي من التداخل مع النواة عند الإقلاع ويتوقف مع خطأ واضح إذا كانت RAM صغيرة جدًا.
يتم وضع مقاطع ELF PT_LOAD في عناوينها p_vaddr.
bare_printf يرتبط عند 0x8000_0000:
0x8000_0000 ── .text
── .rodata
── .data
── .bss (تم التصفير بواسطة start.S)
── stack (16 KiB فوق BSS)
لا نواة. لا initrd. لا DTB. تبدأ السجلات من الصفر باستثناء sp،
الذي يقوم المحاكي بتعيينه إلى ram_base + 0x100000 قبل أن يتولى start.S التحكم.
يمكن تمرير الخيارات عبر سطر الأوامر، أو تعيينها كمتغيرات بيئة، أو وضعها في emuko.yml.
مقارنة مباشرة مع محاكيات RISC-V الشائعة.
✅ = مدعوم وموثق. — = غير مدمج.
المصادر: QEMU virt · Spike · Renode
رخصة Apache 2.0. انظر LICENSE.
| المنطقة | القاعدة | الحجم | ملاحظات |
|---|
| CLINT | 0x0200_0000 | 64 KiB | مؤقت و IRQ برمجي |
| PLIC | 0x0C00_0000 | 4 MiB | 32 مصدر مقاطعة |
| UART | 0x1000_0000 | 256 B | NS16550A، IRQ 10 |
| RAM | 0x8000_0000 | 1 GiB | قابل للتكوين |
| الخيار | متغير البيئة | الافتراضي | ملاحظات |
|---|
--ram-size | RAM_SIZE | 1 GB | RAM بالبايت |
--backend | EMUKO_BACKEND | adaptive | adaptive، arm64_jit، amd64_jit، arm64، x86_64 |
--bootargs | BOOTARGS | وحدة تحكم تسلسلية | سطر أوامر النواة |
| الميزة | emuko | QEMU | Spike | Renode |
|---|
| JIT / الترجمة الديناميكية | ✅ | ✅ | — | — |
| حفظ واستعادة اللقطات | ✅ | ✅ | — | ✅ |
| لقطة تلقائية دورية | ✅ | — | — | ✅ |
| واجهة HTTP للتحكم في الجهاز | ✅ | — | — | — |
| وحدة تحكم UART عبر WebSocket | ✅ | — | — | — |
| جسر مضيف UART قابل للبرمجة | ✅ | — | — | ✅ |
| رفع ELF على المعدن العاري (بدون نظام تشغيل) | ✅ | — | — | — |
| تنزيل النواة بأمر واحد + SHA256 | ✅ | — | — | — |
| مدقق الفروق بين JIT والمفسر | ✅ | — | — | — |
| تصحيح أخطاء GDB | — | ✅ | ✅ | ✅ |
| نظام بيئي كبير للأجهزة (PCIe, virtio) | — | ✅ | — | — |
| محاكاة متعددة العقد | — | — | — | ✅ |
| تغطية واسعة لمجموعة التعليمات (RVV, تشفير، إلخ) | — | — | ✅ | — |