Çekirdek örnekleri: KabaLang Minimal Kernel (MPL-2.0) ve üç küçük çekirdek
KabaLang'ın --yalin kipiyle yazılmış, işletim sistemi olmadan açılan x86-64 çekirdeği: kesmeler, 100 Hz zamanlayıcı, Türkçe Q klavye, Türkçe karakterli VGA ekranı, bellek haritası, sayfa ayırıcı, kabuk. Ek örnekler: merhaba, asal sayılar, VGA renkleri.
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
/* KabaLang yalın (çıplak donanım) çekirdek önyükleme parçası.
|
||||
*
|
||||
* Görevi YALNIZ: Multiboot1 başlığı (QEMU `-kernel` ve GRUB yükler),
|
||||
* 32 bit korumalı kipten 64 bit uzun kipe geçiş, yığın, ve KabaLang
|
||||
* programının giriş işlevine (`kaba_cekirdek_ana`) atlamak. Çekirdeğin
|
||||
* MANTIĞI bu dosyada değil, `.kbl` kaynağındadır.
|
||||
*
|
||||
* Bellek: ilk 1 GB, 2 MB'lık sayfalarla birebir (identity) eşlenir.
|
||||
*/
|
||||
.set MB_SIHIR, 0x1BADB002
|
||||
.set MB_BAYRAK, 0x00000003 /* sayfa hizalı modüller + bellek bilgisi */
|
||||
.set MB_SAGLAMA, -(MB_SIHIR + MB_BAYRAK)
|
||||
|
||||
.section .multiboot, "a"
|
||||
.align 4
|
||||
.long MB_SIHIR, MB_BAYRAK, MB_SAGLAMA
|
||||
|
||||
.section .bss
|
||||
.align 4096
|
||||
.global kaba_yigin_durumu
|
||||
kaba_yigin_durumu: /* yalın çalışma zamanının yığın durumu */
|
||||
.skip 64
|
||||
.align 4096
|
||||
pml4: .skip 4096
|
||||
pdpt: .skip 4096
|
||||
pd: .skip 4096
|
||||
yigin_alt:
|
||||
.skip 65536
|
||||
yigin_ust:
|
||||
|
||||
.section .data
|
||||
.align 8
|
||||
.global kaba_onyukleme_bilgisi
|
||||
kaba_onyukleme_bilgisi:
|
||||
.quad 0
|
||||
|
||||
.section .rodata
|
||||
.align 8
|
||||
gdt64:
|
||||
.quad 0 /* boş tanımlayıcı */
|
||||
.quad 0x00AF9A000000FFFF /* 64 bit kod kesimi */
|
||||
.quad 0x00CF92000000FFFF /* veri kesimi */
|
||||
gdt64_son:
|
||||
gdt64_gosterge:
|
||||
.word gdt64_son - gdt64 - 1
|
||||
.quad gdt64
|
||||
|
||||
.section .text
|
||||
.code32
|
||||
.global _start
|
||||
_start:
|
||||
cli
|
||||
mov $yigin_ust, %esp
|
||||
mov %ebx, kaba_onyukleme_bilgisi /* Multiboot bilgi yapısının adresi */
|
||||
|
||||
/* PML4[0] → PDPT, PDPT[0] → PD, PD[i] → i*2MB (büyük sayfa) */
|
||||
mov $pdpt, %eax
|
||||
or $0x3, %eax
|
||||
mov %eax, pml4
|
||||
mov $pd, %eax
|
||||
or $0x3, %eax
|
||||
mov %eax, pdpt
|
||||
xor %ecx, %ecx
|
||||
1: mov %ecx, %eax
|
||||
shl $21, %eax
|
||||
or $0x83, %eax /* var + yazılabilir + büyük sayfa */
|
||||
mov %eax, pd(,%ecx,8)
|
||||
inc %ecx
|
||||
cmp $512, %ecx
|
||||
jne 1b
|
||||
|
||||
mov $pml4, %eax /* CR3 = PML4 */
|
||||
mov %eax, %cr3
|
||||
mov %cr4, %eax /* PAE */
|
||||
or $0x20, %eax
|
||||
mov %eax, %cr4
|
||||
mov $0xC0000080, %ecx /* EFER.LME */
|
||||
rdmsr
|
||||
or $0x100, %eax
|
||||
wrmsr
|
||||
mov %cr0, %eax /* sayfalama + korumalı kip */
|
||||
or $0x80000001, %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
lgdt gdt64_gosterge
|
||||
ljmp $0x08, $uzun_kip
|
||||
|
||||
.code64
|
||||
uzun_kip:
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %ss
|
||||
xor %ax, %ax
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
mov $yigin_ust, %rsp
|
||||
xor %rbp, %rbp
|
||||
call kaba_cekirdek_ana
|
||||
2: cli
|
||||
hlt
|
||||
jmp 2b
|
||||
|
||||
/* ── Kesme girişleri ────────────────────────────────────────────────────
|
||||
* 0–31 işlemci istisnaları, 32–47 PIC donanım kesmeleri (yeniden eşlenmiş).
|
||||
* Her giriş: (hata kodu yoksa 0) + vektör yığına → ortak giriş → KabaLang
|
||||
* `kesme(vektor, kod)` (dışa `kaba_kesme`). Yazmaçlar saklanır; yığın
|
||||
* `call` anında 16 bayt hizalıdır (5 CPU + 2 giriş + 15 yazmaç = 22×8 = 176).
|
||||
* Çekirdek `-mgeneral-regs-only` derlendiği için SSE durumu saklanmaz. */
|
||||
/* CPU'nun hata kodu ittiği istisnalar: 8, 10–14, 17, 21, 29, 30. */
|
||||
.irp n, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47
|
||||
kesme_giris_\n:
|
||||
.if (\n == 8) || (\n >= 10 && \n <= 14) || (\n == 17) || (\n == 21) || (\n == 29) || (\n == 30)
|
||||
.else
|
||||
push $0
|
||||
.endif
|
||||
push $\n
|
||||
jmp kesme_ortak
|
||||
.endr
|
||||
|
||||
kesme_ortak:
|
||||
.irp r, rax,rbx,rcx,rdx,rsi,rdi,rbp,r8,r9,r10,r11,r12,r13,r14,r15
|
||||
push %\r
|
||||
.endr
|
||||
mov 120(%rsp), %rdi /* vektör */
|
||||
mov 128(%rsp), %rsi /* hata kodu */
|
||||
cld
|
||||
call kaba_kesme
|
||||
.irp r, r15,r14,r13,r12,r11,r10,r9,r8,rbp,rdi,rsi,rdx,rcx,rbx,rax
|
||||
pop %\r
|
||||
.endr
|
||||
add $16, %rsp /* vektör + hata kodu */
|
||||
iretq
|
||||
|
||||
/* Program `kesme` işlevi tanımlamadıysa: hiçbir şey yapma. */
|
||||
.weak kaba_kesme
|
||||
kaba_kesme:
|
||||
ret
|
||||
|
||||
.section .rodata
|
||||
.align 8
|
||||
.global kaba_kesme_girisleri
|
||||
kaba_kesme_girisleri:
|
||||
.irp n, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47
|
||||
.quad kesme_giris_\n
|
||||
.endr
|
||||
@@ -0,0 +1,318 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# KabaLang yalın çalışma zamanı — KabaLang ile yazılmıştır.
|
||||
#
|
||||
# Yalın (çıplak donanım) derlemelere kendiliğinden eklenir. Buradaki
|
||||
# `kaba_*` adlı işlevler, normal LLVM yolunda C++ çalışma zamanının verdiği
|
||||
# C ABI işlevlerinin karşılığıdır; üreteç onları aynı adla dışa açar
|
||||
# (işaretçiler burada 64 bit sayı olarak görünür). Böylece metin işlemleri
|
||||
# (birleştirme, karşılaştırma, uzunluk, parça…) çekirdekte de normal
|
||||
# KabaLang yazımıyla kullanılabilir.
|
||||
#
|
||||
# Yığın: `yigin_kur(adres, boyut)` ile çekirdeğin verdiği bölge. İlk uyan
|
||||
# boş blok kullanılır, büyük blok bölünür; boş blok yoksa bölgenin
|
||||
# sonundan ilerlenir. Bellek biterse işlemci durdurulur.
|
||||
#
|
||||
# Metin düzeni: [sayaç: 8][uzunluk (bayt): 8][baytlar][0]
|
||||
# sayaç < 0 → ölümsüz (derleme zamanında gömülen sabit metin).
|
||||
# Uzunluk ve indeks KOD NOKTASI üzerinden çalışır (UTF-8).
|
||||
|
||||
BASLIK = 16 # blok başlığı: [boyut][sonraki]
|
||||
METIN_BASLIK = 16 # metin başlığı: [sayaç][uzunluk]
|
||||
|
||||
# Yığın durumu `yigin_durumu()` adresindedir (önyükleme parçasında 64 bayt).
|
||||
BOS_LISTE = 0
|
||||
KULLANILAN = 8
|
||||
SINIR = 16
|
||||
SON = 24
|
||||
|
||||
# ── yığın ────────────────────────────────────────────────────────────────
|
||||
fonksiyon yigin_kur(adres, boyut):
|
||||
d = yigin_durumu()
|
||||
bellek_yaz64(d + BOS_LISTE, 0)
|
||||
bellek_yaz64(d + KULLANILAN, 0)
|
||||
bellek_yaz64(d + SINIR, adres)
|
||||
bellek_yaz64(d + SON, adres + boyut)
|
||||
|
||||
fonksiyon yigin_kullanilan():
|
||||
don bellek_oku64(yigin_durumu() + KULLANILAN)
|
||||
|
||||
fonksiyon kaba_ayir(n):
|
||||
d = yigin_durumu()
|
||||
boyut = bit_ve(n + 15, bit_degil(15)) + BASLIK
|
||||
onceki = 0
|
||||
blok = bellek_oku64(d + BOS_LISTE)
|
||||
iken blok != 0:
|
||||
bb = bellek_oku64(blok)
|
||||
eger bb >= boyut:
|
||||
eger bb - boyut >= 64:
|
||||
# Bloğun SONUNDAN kes; kalan parça listede kalır.
|
||||
bellek_yaz64(blok, bb - boyut)
|
||||
yeni = blok + bb - boyut
|
||||
bellek_yaz64(yeni, boyut)
|
||||
bellek_yaz64(d + KULLANILAN, bellek_oku64(d + KULLANILAN) + boyut)
|
||||
don yeni + BASLIK
|
||||
sonraki = bellek_oku64(blok + 8)
|
||||
eger onceki == 0:
|
||||
bellek_yaz64(d + BOS_LISTE, sonraki)
|
||||
degilse:
|
||||
bellek_yaz64(onceki + 8, sonraki)
|
||||
bellek_yaz64(d + KULLANILAN, bellek_oku64(d + KULLANILAN) + bb)
|
||||
don blok + BASLIK
|
||||
onceki = blok
|
||||
blok = bellek_oku64(blok + 8)
|
||||
sinir = bellek_oku64(d + SINIR)
|
||||
eger sinir == 0 veya sinir + boyut > bellek_oku64(d + SON):
|
||||
dur()
|
||||
bellek_yaz64(d + SINIR, sinir + boyut)
|
||||
bellek_yaz64(sinir, boyut)
|
||||
bellek_yaz64(d + KULLANILAN, bellek_oku64(d + KULLANILAN) + boyut)
|
||||
don sinir + BASLIK
|
||||
|
||||
fonksiyon kaba_serbest(p):
|
||||
eger p == 0:
|
||||
don 0
|
||||
d = yigin_durumu()
|
||||
blok = p - BASLIK
|
||||
bellek_yaz64(d + KULLANILAN, bellek_oku64(d + KULLANILAN) - bellek_oku64(blok))
|
||||
bellek_yaz64(blok + 8, bellek_oku64(d + BOS_LISTE))
|
||||
bellek_yaz64(d + BOS_LISTE, blok)
|
||||
don 0
|
||||
|
||||
# ── metin yardımcıları ───────────────────────────────────────────────────
|
||||
fonksiyon bayt_uzunluk(m):
|
||||
don bellek_oku64(m + 8)
|
||||
|
||||
fonksiyon veri(m):
|
||||
don m + METIN_BASLIK
|
||||
|
||||
fonksiyon yeni_metin(n):
|
||||
m = kaba_ayir(METIN_BASLIK + n + 1)
|
||||
bellek_yaz64(m, 1)
|
||||
bellek_yaz64(m + 8, n)
|
||||
bellek_yaz8(m + METIN_BASLIK + n, 0)
|
||||
don m
|
||||
|
||||
fonksiyon kopyala(hedef, kaynak, n):
|
||||
dongu i icinde 0..n - 1:
|
||||
bellek_yaz8(hedef + i, bellek_oku8(kaynak + i))
|
||||
|
||||
fonksiyon devam_bayti_mi(b):
|
||||
don bit_ve(b, 0xC0) == 0x80
|
||||
|
||||
fonksiyon kod_noktasi_ofseti(m, k):
|
||||
# k. kod noktasının bayt ofseti; k uzunluğa eşitse bayt uzunluğu.
|
||||
n = bayt_uzunluk(m)
|
||||
i = 0
|
||||
sayac = 0
|
||||
iken i < n:
|
||||
eger degil devam_bayti_mi(bellek_oku8(veri(m) + i)):
|
||||
eger sayac == k:
|
||||
don i
|
||||
sayac = sayac + 1
|
||||
i = i + 1
|
||||
don n
|
||||
|
||||
fonksiyon alt_metin(m, bas, son):
|
||||
# [bas, son) bayt aralığından yeni metin.
|
||||
r = yeni_metin(son - bas)
|
||||
kopyala(veri(r), veri(m) + bas, son - bas)
|
||||
don r
|
||||
|
||||
# ── C ABI karşılıkları (normal yolda kaba_rt.cpp) ────────────────────────
|
||||
fonksiyon kaba_m_tut(m):
|
||||
eger m != 0 ve bellek_oku64(m) >= 0:
|
||||
bellek_yaz64(m, bellek_oku64(m) + 1)
|
||||
|
||||
fonksiyon kaba_m_birak(m):
|
||||
eger m == 0:
|
||||
don 0
|
||||
s = bellek_oku64(m)
|
||||
eger s > 0:
|
||||
eger s == 1:
|
||||
kaba_serbest(m)
|
||||
degilse:
|
||||
bellek_yaz64(m, s - 1)
|
||||
don 0
|
||||
|
||||
fonksiyon kaba_m_sabit(p, n):
|
||||
r = yeni_metin(n)
|
||||
kopyala(veri(r), p, n)
|
||||
don r
|
||||
|
||||
fonksiyon kaba_m_cden(p):
|
||||
n = 0
|
||||
iken bellek_oku8(p + n) != 0:
|
||||
n = n + 1
|
||||
don kaba_m_sabit(p, n)
|
||||
|
||||
fonksiyon kaba_m_birlestir(a, b):
|
||||
la = bayt_uzunluk(a)
|
||||
lb = bayt_uzunluk(b)
|
||||
r = yeni_metin(la + lb)
|
||||
kopyala(veri(r), veri(a), la)
|
||||
kopyala(veri(r) + la, veri(b), lb)
|
||||
don r
|
||||
|
||||
fonksiyon kaba_m_birlestir_tasi(a, b):
|
||||
# Sol taraf geçicidir: sonuç üretilir, sol bırakılır.
|
||||
r = kaba_m_birlestir(a, b)
|
||||
kaba_m_birak(a)
|
||||
don r
|
||||
|
||||
fonksiyon kaba_m_karsilastir(a, b):
|
||||
la = bayt_uzunluk(a)
|
||||
lb = bayt_uzunluk(b)
|
||||
n = la
|
||||
eger lb < n:
|
||||
n = lb
|
||||
dongu i icinde 0..n - 1:
|
||||
x = bellek_oku8(veri(a) + i)
|
||||
y = bellek_oku8(veri(b) + i)
|
||||
eger x < y:
|
||||
don 0 - 1
|
||||
eger x > y:
|
||||
don 1
|
||||
eger la < lb:
|
||||
don 0 - 1
|
||||
eger la > lb:
|
||||
don 1
|
||||
don 0
|
||||
|
||||
fonksiyon kaba_m_esit(a, b):
|
||||
eger bayt_uzunluk(a) != bayt_uzunluk(b):
|
||||
don 0
|
||||
eger kaba_m_karsilastir(a, b) == 0:
|
||||
don 1
|
||||
don 0
|
||||
|
||||
fonksiyon kaba_m_uzunluk(m):
|
||||
n = bayt_uzunluk(m)
|
||||
sayac = 0
|
||||
dongu i icinde 0..n - 1:
|
||||
eger degil devam_bayti_mi(bellek_oku8(veri(m) + i)):
|
||||
sayac = sayac + 1
|
||||
don sayac
|
||||
|
||||
fonksiyon kaba_m_bos_mu(m):
|
||||
eger bayt_uzunluk(m) == 0:
|
||||
don 1
|
||||
don 0
|
||||
|
||||
fonksiyon kaba_m_sayidan(n):
|
||||
eksi = n < 0
|
||||
eger eksi:
|
||||
n = 0 - n
|
||||
basamak = 1
|
||||
b = n
|
||||
iken b >= 10:
|
||||
b = b // 10
|
||||
basamak = basamak + 1
|
||||
uzun = basamak
|
||||
eger eksi:
|
||||
uzun = uzun + 1
|
||||
r = yeni_metin(uzun)
|
||||
eger eksi:
|
||||
bellek_yaz8(veri(r), 0x2D)
|
||||
k = uzun - 1
|
||||
dongu j icinde 1..basamak:
|
||||
bellek_yaz8(veri(r) + k, 0x30 + n % 10)
|
||||
n = n // 10
|
||||
k = k - 1
|
||||
don r
|
||||
|
||||
fonksiyon kaba_m_sayiya(m):
|
||||
n = bayt_uzunluk(m)
|
||||
i = 0
|
||||
eksi = yanlis
|
||||
eger n > 0 ve bellek_oku8(veri(m)) == 0x2D:
|
||||
eksi = dogru
|
||||
i = 1
|
||||
sonuc = 0
|
||||
iken i < n:
|
||||
c = bellek_oku8(veri(m) + i)
|
||||
eger c < 0x30 veya c > 0x39:
|
||||
don 0
|
||||
sonuc = sonuc * 10 + (c - 0x30)
|
||||
i = i + 1
|
||||
eger eksi:
|
||||
don 0 - sonuc
|
||||
don sonuc
|
||||
|
||||
fonksiyon kaba_m_mantiktan(b):
|
||||
eger b != 0:
|
||||
don kaba_m_cden(veri_adresi("doğru"))
|
||||
don kaba_m_cden(veri_adresi("yanlış"))
|
||||
|
||||
fonksiyon kaba_m_oge(m, i, satir):
|
||||
n = kaba_m_uzunluk(m)
|
||||
eger i < 0:
|
||||
i = i + n
|
||||
eger i < 0 veya i >= n:
|
||||
dur()
|
||||
don alt_metin(m, kod_noktasi_ofseti(m, i), kod_noktasi_ofseti(m, i + 1))
|
||||
|
||||
fonksiyon kaba_m_parca(m, bas, uzunluk):
|
||||
n = kaba_m_uzunluk(m)
|
||||
eger bas < 0:
|
||||
bas = 0
|
||||
eger bas > n:
|
||||
bas = n
|
||||
son = n
|
||||
eger uzunluk >= 0 ve bas + uzunluk < n:
|
||||
son = bas + uzunluk
|
||||
don alt_metin(m, kod_noktasi_ofseti(m, bas), kod_noktasi_ofseti(m, son))
|
||||
|
||||
fonksiyon kaba_m_ile_baslar(m, onek):
|
||||
lo = bayt_uzunluk(onek)
|
||||
eger lo > bayt_uzunluk(m):
|
||||
don 0
|
||||
dongu i icinde 0..lo - 1:
|
||||
eger bellek_oku8(veri(m) + i) != bellek_oku8(veri(onek) + i):
|
||||
don 0
|
||||
don 1
|
||||
|
||||
fonksiyon bayt_bul(m, parca):
|
||||
lm = bayt_uzunluk(m)
|
||||
lp = bayt_uzunluk(parca)
|
||||
eger lp == 0:
|
||||
don 0
|
||||
i = 0
|
||||
iken i + lp <= lm:
|
||||
tutar = dogru
|
||||
j = 0
|
||||
iken tutar ve j < lp:
|
||||
eger bellek_oku8(veri(m) + i + j) != bellek_oku8(veri(parca) + j):
|
||||
tutar = yanlis
|
||||
j = j + 1
|
||||
eger tutar:
|
||||
don i
|
||||
i = i + 1
|
||||
don 0 - 1
|
||||
|
||||
fonksiyon kaba_m_icerir(m, parca):
|
||||
eger bayt_bul(m, parca) >= 0:
|
||||
don 1
|
||||
don 0
|
||||
|
||||
fonksiyon kaba_m_bul(m, parca):
|
||||
b = bayt_bul(m, parca)
|
||||
eger b < 0:
|
||||
don 0 - 1
|
||||
# bayt ofsetinden kod noktası dizinine
|
||||
sayac = 0
|
||||
dongu i icinde 0..b - 1:
|
||||
eger degil devam_bayti_mi(bellek_oku8(veri(m) + i)):
|
||||
sayac = sayac + 1
|
||||
don sayac
|
||||
|
||||
fonksiyon kaba_m_tekrarla(m, n):
|
||||
l = bayt_uzunluk(m)
|
||||
eger n < 0:
|
||||
n = 0
|
||||
r = yeni_metin(l * n)
|
||||
dongu k icinde 0..n - 1:
|
||||
kopyala(veri(r) + k * l, veri(m), l)
|
||||
don r
|
||||
@@ -0,0 +1,17 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
/* KabaLang yalın çekirdek bağlayıcı betiği — 1 MB'tan başlar (Multiboot1). */
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 1M;
|
||||
.text : ALIGN(4K) {
|
||||
KEEP(*(.multiboot))
|
||||
*(.text .text.*)
|
||||
}
|
||||
.rodata : ALIGN(4K) { *(.rodata .rodata.*) }
|
||||
.data : ALIGN(4K) { *(.data .data.*) }
|
||||
.bss : ALIGN(4K) { *(COMMON) *(.bss .bss.*) }
|
||||
/DISCARD/ : { *(.comment) *(.note*) *(.eh_frame*) }
|
||||
}
|
||||
Reference in New Issue
Block a user