hazel/kernel/init.asm

294 lines
4.7 KiB
NASM

%define MAGIC 0x1BADB002
%define ALIGN 1<<0
%define MMAP 1<<1
%define VID 1<<2
%define FLAGS (ALIGN | MMAP | VID)
section .multiboot.data
dd MAGIC
dd FLAGS
dd -(MAGIC + FLAGS)
dd 0 ; header_addr
dd 0 ; load_addr
dd 0 ; load_end_addr
dd 0 ; bss_end_addr
dd 0 ; entry_addr
dd 1 ; mode_type
dd 80 ; width
dd 25 ; height
dd 0 ; depth
section .multiboot.text
global _start
_start:
cli
; Check if EAX contains this magic value that our bootloader should've set
cmp eax, 0x2BADB002
jne halt
; Setup table
; Identity page 0-4 mib
mov eax, 0
mov edx, 0
.fill_table:
mov ecx, edx
or ecx, 7
mov [boot_page_tab-0xC0000000+eax*4], ecx
add edx, 0x1000
inc eax
cmp eax, 1024
jne .fill_table
mov ecx, boot_page_tab
sub ecx, 0xC0000000
or ecx, 7
mov [boot_page_dir-0xC0000000], ecx
mov [boot_page_dir-0xC0000000+768*4], ecx
; Enable paging
mov eax, boot_page_dir
sub eax, 0xC0000000
mov cr3, eax
mov eax, cr0
or eax, (1<<31)
mov cr0, eax
jmp higher_half
section .text
higher_half:
; Un-identity-map kernel
mov dword [boot_page_dir], 2
; Add KERNEL_VMA to the address of the multiboot info struct
add ebx, 0xC0000000
; Load GDT
lgdt [gdtp]
; Offset to kernel data descriptor
mov ax, 0x10
mov es, ax
mov ds, ax
mov fs, ax
mov gs, ax
mov ss, ax
; Offset to kernel code descriptor
jmp 0x8:.use_code_seg
.use_code_seg:
mov esp, stack_bottom
mov ebp, esp
push ebx
extern kernel
call kernel
cli
halt:
hlt
jmp halt
global ps2_isr
ps2_isr:
extern ps2_handler
pushad
call ps2_handler
popad
iret
extern ctx
extern task_sort
global pit_isr
pit_isr:
pushad
extern pit_handler
call pit_handler
cmp eax, 1
; jne .ret
jmp .ret
mov edi, [ctx+28] ; EDI = current task
; mov esi, [edi+8] ; ESI = next task
; Save current ESP
mov dword [edi], esp
call task_sort
mov edi, [ctx+28] ; EDI = NEW current task
; Set current task to next task
; mov dword [ctx+28], esi
; Change to new ESP
mov esp, [edi]
.ret:
popad
iret
global jmp_user_mode
jmp_user_mode:
mov ax, (4*8) | 3
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax ; SS is handled by iret
mov eax, [esp+4] ; esp arg
mov edx, [esp+8] ; eip arg
push (4*8) | 3
push eax
sti
pushf
push (3*8) | 3
push edx
iret
global flush_tss
flush_tss:
ltr [esp+4]
ret
global syscall_isr
syscall_isr:
pushad
mov ecx, esp
sysenter
after_syscall:
popad
iret
global syscall
syscall:
imul eax, eax, 4
add eax, syscall_table
pushad
call [eax]
popad
mov edx, after_syscall
sti
sysexit
extern exception_handler
%macro isr_err_stub 1
isr_stub_%+%1:
cli
push %1
pusha
call exception_handler
popa
add esp, 8
iret
%endmacro
%macro isr_no_err_stub 1
isr_stub_%+%1:
cli
push 0
push %1
pusha
call exception_handler
popa
add esp, 12
iret
%endmacro
isr_no_err_stub 0
isr_no_err_stub 1
isr_no_err_stub 2
isr_no_err_stub 3
isr_no_err_stub 4
isr_no_err_stub 5
isr_no_err_stub 6
isr_no_err_stub 7
isr_err_stub 8
isr_no_err_stub 9
isr_err_stub 10
isr_err_stub 11
isr_err_stub 12
isr_err_stub 13
isr_err_stub 14
isr_no_err_stub 15
isr_no_err_stub 16
isr_err_stub 17
isr_no_err_stub 18
isr_no_err_stub 19
isr_no_err_stub 20
isr_no_err_stub 21
isr_no_err_stub 22
isr_no_err_stub 23
isr_no_err_stub 24
isr_no_err_stub 25
isr_no_err_stub 26
isr_no_err_stub 27
isr_no_err_stub 28
isr_no_err_stub 29
isr_err_stub 30
isr_no_err_stub 31
global isr_stub_table
isr_stub_table:
%assign i 0
%rep 32
dd isr_stub_%+i
%assign i i+1
%endrep
section .data
; GDT for a flat memory layout
; We get access to all memory and can utilize paging
global gdt
gdt:
gdt_null:
dq 0
gdt_kern_code:
dw 0xffff
dw 0x0000
db 0x00
db 0b10011010
db 0b11001111
db 0x00
gdt_kern_data:
dw 0xffff
dw 0x0000
db 0x00
db 0b10010010
db 0b11001111
db 0x00
gdt_user_code:
dw 0xffff
dw 0x0000
db 0x00
db 0b11111010
db 0b11001111
db 0x00
gdt_user_data:
dw 0xffff
dw 0x0000
db 0x00
db 0b11110010
db 0b11001111
db 0x00
tss:
dq 0
gdt_end:
gdtp:
dw gdt_end - gdt - 1
dd gdt
global boot_page_dir
align 0x1000
boot_page_dir: times 1024 dd 0
global boot_page_tab
align 0x1000
boot_page_tab: times 1024 dd 0
extern syscall_read
extern syscall_write
extern syscall_reboot
global syscall_table
syscall_table:
dd syscall_read
dd syscall_write
dd syscall_reboot
section .bss
align 16
stack_top:
resb 16384
stack_bottom: