PUBLIC DEVELOPMENT LOG

Gerçek bir
aarch64 Microkernel
inşa ediyoruz.

ASELSAN Milli Telefon vizyonu için sıfırdan, Android'siz, capability-based Rust microkernel geliştirme süreci.

M2
M1 TAMAMLANDI 100 Hz drift-free tick · sıradaki: M2 (MMU + allocator)
SON TAMAMLANAN — M1 KAPANDI
M1.4 — 100 Hz drift-free tick + irq_lock!
CVAL ile mutlak çapaya geçtik: 6 sn'de birikmeyen ~120 µs drift (önceki TVAL: ~100 ms, lineer büyüyor). M3 scheduler için stabil bir kalp ritmi.
QEMU'da Doğrulandı
Günlüğü Gör
YOL HARİTASI
7 Milestone
M0
İlk Boot
TAMAMLANDI
QEMU virt üzerinde aarch64 kernel boot + PL011 UART ile log yazma
19 Mayıs 2026
M1
Exception & Timer
TAMAMLANDI
VBAR_EL1 + Exception handler + ARM Generic Timer + irq_lock!
✓ M1.1
✓ M1.2
✓ M1.3
✓ M1.4
M2
Memory Management
SIRADAKİ
Physical allocator + MMU + Kernel heap + identity mapping
M2.1 frame allocator → M2.2 page tables → M2.3 MMU enable → M2.4 kernel heap
M3
Scheduler
PLANLANDI
Context switch + Preemptive task scheduling
M4 — M7
User Mode + Capability + IPC
M4: EL0 + Syscall
M5: Capability System
M6: Gerçek IPC
M7: Orijinal Demo
GELİŞTİRME GÜNLÜĞÜ
Adım adım ne yaptık
M0
İlk Bare-Metal Kernel
19 Mayıs 2026 • 1 gün
TAMAMLANDI
Yapılanlar
  • Proje yapısı temizlendi (simulation + kernel)
  • aarch64 bare-metal iskeleti oluşturuldu
  • linker.ld + boot.S yazıldı
  • QEMU virt + PL011 UART ile ilk boot
Karşılaşılan Zorluklar
Node sürümü nedeniyle Astro kullanılamadı → Basit ve güçlü tek dosya Tailwind çözümü tercih edildi.
Linker script yolu workspace vs kernel klasörü sorunu çözüldü (build.rs ile).
M1.1
Exception Vector Table
19 Mayıs 2026 • aynı gün
QEMU'da DOĞRULANDI
Yapılanlar
  • 16 entry'lik aarch64 vektör tablosu (2 KB hizalı)
  • SAVE_CONTEXT / RESTORE_CONTEXT trampoline'ları (x0–x30 + ELR + SPSR)
  • Rust handler'lar (sync / IRQ / FIQ / SError / invalid)
  • VBAR_EL1 kurulumu + ESR.EC decode'u
  • brk #0xdead ile sync exception → handler → eret başarılı
QEMU UART çıktısı
[BOOT] Şu anki Exception Level: EL1
[M1.1] VBAR_EL1 = 0x0000000040000800
[M1.1] Exception handler'lar aktif.

[TEST] Sync exception tetikleniyor (brk #0xdead)...

[EXC] ----- Senkron exception (EL1, SP_ELx) -----
  ESR_EL1 = 0xf200dead  (EC=0x3c → BRK)
  FAR_EL1 = 0x0000000000000000
  ELR_EL1 = 0x00000000400025b8
[EXC] BRK #0xdead yakalandı. Sonrakine atlanıyor.
[TEST] Exception'dan başarıyla geri döndük.
[OK] M1.1 doğrulandı.
kernel/src/arch/aarch64/exceptions.Sexceptions.rsmod.rs
Karşılaşılan zorluklar: Cargo workspace içinde target/ dizini kernel altında değil workspace kökündeydi (Makefile düzeltildi). .cargo/config.toml içinde [target.aarch64-unknown-none] iki kez tanımlanmıştı — birleştirildi. Vektör tablosunun 0x800 hizalı olması için linker script'e açık ALIGN(0x800) + ayrı .text.exceptions bölümü eklendi.
M1.2
Çalışan Exception Handler — EC-bazlı policy
19 Mayıs 2026 • aynı gün
3/3 PATH DOĞRULANDI
Yapılanlar
  • trigger_brk(), trigger_svc(), trigger_undefined() test API'si
  • Sync handler'a match ec tabanlı policy
  • BRK (EC=0x3c) → recover, ELR += 4
  • SVC (EC=0x15) → recover (HW otomatik), imm16 logla
  • UDF (EC=0x00) → panic, dump_context
  • Data Abort (EC=0x25) ve Instruction Abort (EC=0x21) için panic path'leri hazır (FAR_EL1 raporlu)
QEMU UART çıktısı
[TEST] (1/3) BRK — brk #0xdead
[EXC] BRK #0xdead (EC=0x3c) — recover (ELR += 4)
[TEST] (1/3) BRK'tan geri döndük. OK.

[TEST] (2/3) SVC — svc #0x42
[EXC] SVC #0x0042 (EC=0x15) — supervisor call
[TEST] (2/3) SVC'den geri döndük. OK.

[TEST] (3/3) UDF — udf #0xbeef
[EXC] !!! UNDEFINED / UNKNOWN INSTRUCTION !!!
  ESR_EL1 = 0x02000000  ELR = 0x400027a4
!!! KERNEL PANIC !!!
Dosya: kernel/src/arch/aarch64/exceptions.rs:120
Mesaj: undefined instruction
kernel/src/arch/aarch64/exceptions.rsmod.rs • kernel/src/main.rs
Karşılaşılan zorluk: İlk denemede core::ptr::write_volatile(null) ile data abort tetiklemeye çalıştım, ama MMU henüz aktif olmadığı için (M2'de gelecek) QEMU bunu silent geçti — kernel devam etti. Çözüm: panic path'ini gerçek-data-abort yerine udf #0xbeef ile test ettim. Gerçek MMU-bazlı data abort'u M2'de ekleyeceğiz; handler kodu zaten hazır.
M1.3
ARM Generic Timer + GICv2 — Periyodik IRQ
19 Mayıs 2026 • aynı gün • ilk denemede çalıştı
TICK ZİNCİRİ TAM
Yapılanlar
  • gic.rs — GICv2 (GICD @ 0x0800_0000, GICC @ 0x0801_0000) init + enable_irq + ack/eoi
  • timer.rs — CNTV: CNTFRQ_EL0 oku, CNTV_TVAL_EL0 arm, CNTV_CTL_EL0=0b01
  • rust_irq_handler — IAR oku → timer (PPI 27) ise ack+rearm+tick++ → EOIR
  • enable_irqs() / disable_irqs() — DAIF.I helper'ları
  • Atomic TICKS sayacı (M3 scheduler için temel)
QEMU UART çıktısı
[M1.3] GICv2 init: GICD@0x08000000, GICC@0x08010000
[M1.3] CNTFRQ_EL0 = 62500000 Hz → 2 Hz tick
       (her tick 31250000 count)
[M1.3] GICD ISENABLER: PPI 27 aktif
[M1.3] DAIF.I = 0 → IRQ'lar açıldı.

[OK] Kernel idle döngüsü (wfi). Timer bekleniyor...

[TICK 1] virtual timer (PPI 27)
[TICK 2] virtual timer (PPI 27)
[TICK 3] virtual timer (PPI 27)
[TICK 4] virtual timer (PPI 27)
...
[TICK 11] virtual timer (PPI 27)
kernel/src/arch/aarch64/gic.rstimer.rsexceptions.rsmod.rs
Niçin önemli: Artık kernel'ın bir "kalbi" var. Periyodik IRQ olmadan preemptive scheduler kurulamaz — M3'ün ön şartı bu. Şu anda wfi ile uyuyor, sadece timer IRQ ile uyanıp tick basıyor, sonra tekrar uyuyor. Tam zincir: timer → GIC → vector → SAVE → Rust → EOI → RESTORE → eret → wfi.
M1.4
100 Hz drift-free tick + irq_lock!
19 Mayıs 2026 • M1 KAPANDI
~600× DRIFT İYİLEŞMESİ
Yapılanlar
  • TICK_HZ 2 → 100 Hz
  • UART log her tick yerine her 1 saniyede "[SEC n]" özeti
  • Jitter ölçümü: CNTVCT_EL0 ile expected vs actual drift (µs)
  • TVAL → CVAL geçişi: mutlak compare register, handler latency'si birikmiyor
  • IrqGuard RAII + irq_lock!() makrosu — scope-bazlı kritik bölge (M3 scheduler kuyrukları için)
TVAL → CVAL etkisi
SüreTVAL (eski)CVAL (yeni)
1 sn+19 661 µs+127 µs
3 sn+50 820 µs+166 µs
6 sn+100 533 µs+118 µs
Eğilimlineer ↑sabit
QEMU UART çıktısı (CVAL ile)
[M1.3] CNTFRQ_EL0 = 62500000 Hz
       → 100 Hz tick (her tick 625000 count)
[M1.3] GICD ISENABLER: PPI 27 aktif
[M1.3] DAIF.I = 0 → IRQ'lar açıldı.
[M1.4] Saniyelik özet aktif.

[OK] Kernel idle döngüsü (wfi). Timer bekleniyor...

[SEC   1] ticks=100 drift=+127 µs (+7957 count)
[SEC   2] ticks=200 drift=+121 µs (+7579 count)
[SEC   3] ticks=300 drift=+166 µs (+10410 count)
[SEC   4] ticks=400 drift=+173 µs (+10868 count)
[SEC   5] ticks=500 drift=+97  µs (+6108 count)
[SEC   6] ticks=600 drift=+118 µs (+7405 count)
kernel/src/arch/aarch64/timer.rsexceptions.rsmod.rs (IrqGuard)
Niçin TVAL biriktiriyordu: Handler her tetiklendiğinde "şu andan {period} sayım sonra tekrar tetikle" diyordu — handler içinde geçen her µs bir sonraki tick'i o kadar geciktirip kalıcı borç oluşturuyordu. CVAL ile "mutlak hedef = bir önceki hedef + period" diyoruz; latency artık tek-tick'lik gecikme olur, bir sonraki tick'i etkilemez. Bu, scheduler için tek-tick jitter'ı toplam ms'lik kayma yapmadan tolere etmemizi sağlıyor.
M2
Memory Management — MMU + Physical Allocator + Kernel Heap
M1 kapandı, sıradaki büyük adım
PLAN
Önerilen alt adımlar:
  • M2.1 — Bitmap tabanlı physical frame allocator (4 KiB granül)
  • M2.2 — aarch64 page table walker (4-seviye, 48-bit VA)
  • M2.3 — Identity map kernel + UART + GIC, MMU enable (SCTLR_EL1.M=1)
  • M2.4 — Linked-list kernel heap allocator + #[global_allocator]
  • M2.5 — Gerçek data abort testi (artık MMU aktif, M1.2'de erteleyip handler'a hazırladığımız panic path'i çalışacak)