TAIOS ARM64 İşletim Sistemi - Sıfırdan Geliştirme Faz 1 (Part 2)

_start: // Interrupt'ları kapat (DAIF = Debug, SError, IRQ, FIQ) msr daifset, #0xf // DAIF registerındaki tüm mask bitlerini set et // Mevcut Exception Level'ı oku mrs x0, CurrentEL // CurrentEL register'ını x0'a al and x0, x0, #0xC // Sadece [3:2] bitlerini maskele (EL seviyesi) cmp x0, #0x8 // EL2 (0b1000) mi? b.eq init_el2 // Evetse init_el2'ye git cmp x0, #0x4 // EL1 (0b0100) mi? b.eq init_el1 // Evetse init_el1'e git b init_el3 // Değilse EL3 kabul et, init_el3'e git

Buradaki _start aslında programın ilk çalışacağı nokta. Linker'a "sen benim kodumu buradan başlat" diyoruz. ARM64 mimarisinde her şey bu etiketten sonra şekilleniyor.

Interrupt'ları Kapatmak

// Interrupt'ları kapat (DAIF = Debug, SError, IRQ, FIQ) msr daifset, #0xf // DAIF registerındaki tüm mask bitlerini set et

İlk iş olarak interrupt'ları kapatıyoruz. Çünkü henüz hiçbir şey hazır değil. Ne memory mapping var, ne stack var, ne de driver'lar.

Gerçek dünya asenkron problemleri ile uğraşmamak için mesela bir IRQ gelse (keyboarda basıldı gibi), o kod nereye gidecek? O yüzden en temelden başlayıp: "Beni rahatsız etme kardeşim" diyerek bütün kesmeleri kapatıyoruz.

Beni hor görme kardeşim
sen altınsın, ben tunç muyum?
Aynı vardan varolmuşuz,
sen gümüşsün, ben sac mıyım?

diyerek yolumuza devam ediyoruz.

Exception Level Tespiti

// Mevcut Exception Level'ı oku mrs x0, CurrentEL // CurrentEL register'ını x0'a al

Burada mrs (Move from System Register) talimatı ile şu an hangi Exception Level'de (EL0, EL1, EL2, EL3) olduğumuzu öğreniyoruz. ARM mimarisinde bu seviyeler çok kritik:

  • EL0: User mode (app'ler burada çalışır)
  • EL1: Kernel mode (işletim sistemi çekirdeği)
  • EL2: Hypervisor (sanallaştırma katmanı)
  • EL3: Secure monitor (TrustZone, firmware işleri)

Bizim hedefimiz aslında EL1'de kernel'i başlatmak, ama donanım ve firmware'e göre sistem başka bir seviyede açılabilir.

and x0, x0, #0xC // Sadece [3:2] bitlerini maskele (EL seviyesi)

Burada ufak bir bit maskesi yapıyoruz. CurrentEL register'ında daha fazla bilgi var ama bizi ilgilendiren sadece [3:2] bitleri. Çünkü exception level 2 bitten okunuyor. Yani 00, 01, 10, 11 gibi değerlerle hangi seviyede olduğumuzu anlıyoruz.