150 lines
4.5 KiB
ArmAsm
150 lines
4.5 KiB
ArmAsm
/* 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
|