boot.S Nedir? Neden Var?
boot.S, TAI-OS çekirdeğinin ilk çalışan (entry-stage) kodudur. Bu dosya:
- CPU’yu tanımlı bir başlangıç durumuna getirir (interrupt maskeleri, istisna vektör tablosu vb.),
- Mimariye özel ARM64 donanım kayıtlarını ayarlar,
- Sonraki aşamada C koduna kernel güvenle geçişe zemin hazırlar.
Bu seviyede C çalışma zamanı henüz hazır değil. (stack, .bss temizliği, global init vs. yapılmamıştır). Bu yüzden boot aşamasında assembly tercih edilir. boot.S ayrıca linker script ile yakından ilişkilidir: kodun hangi bellek bölümüne yerleşeceğini, vektör tablosunun hizalamasını ve giriş sembolünü _start linker belirler.
Kısaca CPU’yu deterministik hale getir, minimum gereklileri kur, sonra C’ye bırak.
Önemli Notlar
- Dosya uzantısının .S (büyük S) olması GNU as’ın C-önişlemcisini de cpp çalıştırmasına izin verir ki böylelikle macro ve #define önişlemcileri kullanabilelim.
- ARM64 için aarch64-none-elf- veya aarch64-linux-gnu- toolchain’ler yaygındır.
- Linker, ENTRY(_start) ile giriş noktasını _start sembolüne bağlar.
Normal de tüm boot.S’i anlatacaktım ama bu kısma olanı anlatacağım ki, çok sıkıcı olmasın ki zaten yeterince sıkıcı oldu :D
Boot Entry’ye Kadar, Satır Satır Açıklama
1) Dosya üst bilgisi
- Yalnızca bilgilendirme amaçlı bir yorum.
2) Özel kod bölümü seçimi
Bu direktif, derleyiciye ve linker’e bu kodun .text.boot isimli ayrı bir
kod bölümüne konulacağını söyler.
Peki neden ayrı bir bölüm? Cevap: Linker script’te genelde şöyle bir blok olur:
3) Giriş sembolünü dışa açma
_startetiketini global görünür yapar.- Linker,
ENTRY(_start)ile program girişini bu sembole bağlar.
4) Exception Vektör Tablosu Başlığı
- Amaç: ARM64’te istisna (exception) vektör tablosu, 2048 bayt hizalı bir adreste olmalıdır.
exception_vector_table:etiketi, tablonun başlangıç adresini belirler.
Not: Bazı platformlarda .align 2^n hizalama iken bazılarında
n bayt hizalama davranabilir. ARM64 tarafında 2^n olarak çalışır;
en güvenlisi .balign 2048 kullanmaktır. Eğitim metninde
.align 11 yeterli, ama üretimde: .balign 2048 olmalı.
Bu tabloyu .vectors gibi ayrı bir bölüme koyup linker’da
ile çöp toplayıcıdan korunmuş ve zorunlu hizalanmış hale getirmek iyi
pratiktir. Bu örnekte tablo .text.boot içindedir; yine de hizalama garantili
olduğu sürece sorun yok.
5) 16 Adet Vektör Slotu Üretme
Bu blok, 16 adet vektör girişini minimal bir “iskele” ile üretir:
.rept 16, .endr: İçerideki talimatları 16 kez tekrarlar. ARMv8-A, AArch64 vektör tablosunun 16 slotu vardır:
| Slot | Exception Type | Source |
|---|---|---|
| 0-3 | Current EL with SP_EL0 | Sync, IRQ, FIQ, SError |
| 4-7 | Current EL with SP_ELx | Sync, IRQ, FIQ, SError |
| 8-11 | Lower EL (AArch64) | Sync, IRQ, FIQ, SError |
| 12-15 | Lower EL (AArch32) | Sync, IRQ, FIQ, SError |
.align 7 → 2^7 = 128 bayt hizalama: ARM64’te her vektör girişi 128 baytlık bir slot kabul edilir. Burada her tekrarın başında hizalama ile bir sonraki 128 bayt sınırına atlanır.
b hang: Her slotun ilk talimatı, şimdilik basitçe hang fonksiyonuna dalan bir branch. Bu minimalist yaklaşım şunları garanti eder:
- Her istisna, geçici olarak aynı “bekleme” döngüsüne yönlendirilir (sistem donmaz, kontrol sizde kalır).
- Slotların geri kalan padding alanı,
.alignsayesinde otomatik doldurulur; böylece bir sonraki slot tam 128 bayt sınırında başlar
Not: “128 bayt slot = 128 bayt kod yazmak zorundasın” demek değildir. İlk komut (branch) fiilen birkaç bayt; kalan alan hizalama dolgusu. Donanım, slot başlangıcındaki kodu yürütür; içeride daha sonra ister ayrıntılı handler, ister kayıt dökümü koyabilirsiniz.
Bu tarz doldurmalar genelde kriptografide de vardır ama konumuz bu değil. Konu bu değil olm, konu bu değil :D
Bu Noktada Ne Oldu?
- Vektör tablosu 2048B hizayla belleğe yerleştirildi.
- İçinde 16 adet, 128B hizalı slot üretildi.
- Tüm slotlar, şimdilik güvenli bir yere (sonsuz bekleme döngüsü hang) branch ediyor.
- Henüz VBAR_EL1, EL2, EL3 gibi kayıtlar ayarlanmadı
(bu, Boot Entry’den sonra yapılacak iş). Yani tabloyu oluşturduk, ama
CPU’ya “vektör tabanın bu” demedik. O kısım
_startsonrasındaki init aşamasında.
Devamı Gelecek…
Gördüğünüz gibi, BOOT ENTRY kısmına anca gelebildik. Ama burada duralım onu diğer makaleye bırakalım. Eğer ikinci makaleye geçerseniz, bu işi sevdiniz demektir. Bırakırsanız da çok normal, çünkü çok sıkıcı :D
Boot Entry kısmı da şu şekilde gözükecek en azından fikir olması açısından:
Bu serinin devamında CPU initialization, memory management, ve C runtime setup’ını detaylı olarak inceleyeceğiz. ARM64’ün güzelliklerini ve Apple Internals’in derinliklerini birlikte keşfedeceğiz.
Sonraki bölümde: Exception Level management, Stack pointer setup, ve BSS section clearing işlemlerini göreceğiz.