summaryrefslogtreecommitdiff
path: root/Source/Kernel/Core/loader.wtf.asm
blob: 5a925d54f368f7631fcf335f25415234e2f8c65a (plain) (blame)
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
[GLOBAL loader]           ; making entry point visible to linker
[EXTERN kmain]            ; kmain is defined in kmain.wtf.cpp
 
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ  1<<0                   ; align loaded modules on page boundaries
MEMINFO     equ  1<<1                   ; provide memory map
FLAGS       equ  MODULEALIGN | MEMINFO  ; this is the Multiboot 'flag' field
MAGIC       equ    0x1BADB002           ; 'magic number' lets bootloader find the header
CHECKSUM    equ -(MAGIC + FLAGS)        ; checksum required
 
section .text
align 4
MultiBootHeader:
   dd MAGIC
   dd FLAGS
   dd CHECKSUM
 
; reserve initial kernel stack space
STACKSIZE equ 0x4000                  ; that's 16k.

extern start_ctors, end_ctors, start_dtors, end_dtors	; these are required for global objects
 
loader:		;here, we load our false GDT, used for having the kernel in higher half
	lgdt [trickgdt]
	mov cx, 0x10;
	mov ds, cx;
	mov es, cx;
	mov fs, cx;
	mov gs, cx;
	mov ss, cx;

	jmp 0x08:higherhalf


higherhalf:		; now we're running in higher half

   mov esp, stack+STACKSIZE           ; set up the stack
   push eax                           ; pass Multiboot magic number
   add ebx, 0xC0000000				  ; update the MB info structure so that it is in the new seg.
   push ebx                           ; pass Multiboot info structure

static_ctors_loop:			; construct global objects
   mov ebx, start_ctors
   jmp .test
.body:
   call [ebx]
   add ebx,4
.test:
   cmp ebx, end_ctors
   jb .body
 
   call  kmain                       ; call kernel proper

   cli		; disable interupts

static_dtors_loop:					 ; useless, kernel should never return
   mov ebx, start_dtors				; destruct global objects
   jmp .test
.body:
   call [ebx]
   add ebx,4
.test:
   cmp ebx, end_dtors
   jb .body
 
hang:
   hlt                                ; halt machine should kernel return
   jmp   hang

[section .setup]	; this is included in the .setup section, so that it thinks it is at 0x00100000

trickgdt:		; our false GDT (this is equivalent to the gdt_ptr_t structure defined in GDT.ns.h)
   dw gdt_end - gdt - 1		; gdt limit
   dd gdt					; gdt base

gdt:			; each of these is equivalent to one gdt_entry_t structure, defined in GDT.ns.h
   dd 0, 0					; null GDT entry
   db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40	; kernel code segment
   db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40	; kernel data segment

gdt_end:
 
[section .bss]
align 32
stack:
   resb STACKSIZE                     ; reserve 16k stack on a quadword boundary