Syncboot/arch/i386/boot.s
Curle 022884e20d Fixes and improvements.
Including a new, rewritten and restructured boot.s file, plus automagical Protected Mode.
2019-06-25 22:31:26 +01:00

225 lines
3.7 KiB
ArmAsm
Executable File

[BITS 32] ;... somehow.
[GLOBAL start]
start:
mov esp, _sys_stack ; Stack pointer!
jmp stublet ; This has a purpse. I don't know what it is, but there is one.
ALIGN 4 ; 4KB alignment, required by GRUB.
mboot: ; This is all magic, and all of it required for GRUB to see our stuff.
MULTIBOOT_ALIGN equ 1<<0
MULTIBOOT_MEM equ 1<<1
MULTIBOOT_AOUT equ 1<<16
MULTIBOOT_MAGIC equ 0x1BADB002
MULTIBOOT_FLAGS equ MULTIBOOT_ALIGN | MULTIBOOT_MEM | MULTIBOOT_AOUT
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)
EXTERN code, bss, end
dd MULTIBOOT_MAGIC
dd MULTIBOOT_FLAGS
dd MULTIBOOT_CHECKSUM
dd mboot
dd code
dd bss
dd end
dd start
stublet: ; Where the kernel stuff goes.
;=====================================
;===Priority: 32 bit Protected Mode===
;=====================================
cli ; Interrupts be gone!
xor cx, cx ; CX - GP, useful here.
kbempty:
in al, 64h ; Read keyboard status
test al, 02h ; Check if the buffer is full
loopnz kbempty ; Wait until it is
mov al, 0d1h ; Prepare a message
out 64h, al ; And then send it to the keyboard (controller)
kbempty2:
in al, 64h ; Read the status again
test al, 02h ; Check if it's processed our message
loopnz kbempty2 ; And wait until it has
mov al, 0dfh ; Prepare a different message, telling it to enable A20
out 60h, al ; Send the message
mov cx, 14h ; Restore the value of CX
wait_kb: ; Insinuate a 25uS delay to allow the processor to catch up
out 0edh, ax
loop wait_kb
mov eax, cr0 ; Read the control register
or al, 1 ; Set bit 1: protected mode
mov cr0, eax ; Set the control register back
jmp $+2 ; Clear the queue
nop ; (jump straight to kernel)
nop
;==================================
;===32-bit Protected Mode active===
;==================================
; Call the kernel
EXTERN kernel_main
call kernel_main
jmp $
[GLOBAL load_gdt]
[EXTERN gp]
load_gdt:
lgdt [gp] ; Load the new GDT pointer
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:flush
flush:
ret
%macro ISR 1
global isr%1
isr%1:
cli
push byte 0
push byte %1
jmp isr_common
%endmacro
%macro ISR_ERR 1
global isr%1
isr%1:
cli
push byte %1
jmp isr_common
%endmacro
%macro IRQ 2
global irq%1
irq%1:
cli
push byte 0
push byte %2
jmp irq_common
%endmacro
ISR 0
ISR 1
ISR 2
ISR 3
ISR 4
ISR 5
ISR 6
ISR 7
ISR_ERR 8
ISR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR 15
ISR 16
ISR_ERR 17
ISR 18
ISR 19
ISR 20
ISR 21
ISR 22
ISR 23
ISR 24
ISR 25
ISR 26
ISR 27
ISR 28
ISR 29
ISR_ERR 30
ISR 31
IRQ 0, 32
IRQ 1, 33
IRQ 2, 34
IRQ 3, 35
IRQ 4, 36
IRQ 5, 37
IRQ 6, 38
IRQ 7, 39
IRQ 8, 40
IRQ 9, 41
IRQ 10, 42
IRQ 11, 43
IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47
[EXTERN fault_handler]
isr_common:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, fault_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
[EXTERN irq_handler]
irq_common:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
[GLOBAL idt_load]
[EXTERN idtp]
idt_load:
lidt [eax]
ret
SECTION .bss
resb 8192
_sys_stack: