summaryrefslogtreecommitdiff
path: root/src/bootloader/bootloader.asm
blob: 3ac10f3f5de6a5444ec2420f097037db3510a5d7 (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
[bits 16]
[extern _kernel_size]
[extern _bootloader_stage1_size]
[extern _kernel_loc]

jmp stage0 
times 3-($-$$) db 0x90 ; a temporary dirty fix to emulate a floppy disk insted of a hard risk 
times 59 db 0          ; (TODO support hard disks) 

stage0:

jmp 0:.entry
.entry:

mov ax, 0
mov ds, ax
mov bp, ax 

mov ds, ax
mov es, ax

mov ax, 0x8fc0
mov ss, ax
mov ax, 0xfffe 
mov sp, ax

mov al, 0x92
or al, 2
out 0x92, al

mov [.boot_device], dl

mov bx, .loadstage2_msg
mov cx, 0 
call bios_print

; TODO put in an error message and a maximum fail count
.load_stage1:
mov al, _bootloader_stage1_size
mov cl, 0x2       ; read sector 2 
mov dx, 0x0       ; dest segment 0
mov bx, 0x7e00    ; dest offst 0 
call bios_disk.load_sectors 


jmp mbr_end.entry

.boot_device: db 0

.loadstage2_msg: db "Loading (stage 2) bootloader...", 0

%include "bootloader/bios_functions/bios_disk.asm"
%include "bootloader/bios_functions/print.asm"

times 510 - ($-$$) db 0  
dw 0xaa55

%include "bootloader/gdt.asm"

boot_msg:
.kernel_loaded: db `Kernel loaded!\r\nBooting to protected, then long mode...`, 0
.stage2_loaded: db `Done loading bootloader!\r\nLoading kernel...`, 0




mbr_end:
.entry:
; entering unreal mode
mov bx, boot_msg.stage2_loaded
mov cx, 0
call bios_print


cli
push ds

lgdt [protected_gdt.descriptor]

mov eax, cr0
or al, 1
mov cr0, eax

jmp $+2

mov bx, 0x10 ; descriptor 2, the data descriptor
mov ds, bx   ; put it into the segment register
mov es, bx   ; 

and al, 0xfe
mov cr0, eax

pop ds
sti

;we are now in unreal mode

mov cl, 5   
mov edi, _kernel_loc
.loop:
mov al, 0x1   ; sector count
mov dx, 0x0   ; dest addr segment
mov bx, 0x500 ; dest addr offset
call bios_disk.load_sectors


inc cl

push cx

mov esi, 0x500
mov ecx, 512
a32 rep movsb
nop

pop cx

cmp cl, _kernel_size+2
je .loop_end

jmp .loop

.loop_end:

mov bx, boot_msg.kernel_loaded
mov cx, 0
call bios_print


call detect_arch
call vbe_init
done:

call enter_longmode
jmp $

%include "bootloader/cpu_check.asm"
%include "bootloader/video.asm"
%include "bootloader/enter_kernel.asm"

times 2048 - ($ - $$) db 0