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
142
143
144
145
|
[bits 16]
[extern _kernel_size]
[extern _bootloader_stage1_size]
[extern _kernel_loc]
;TODO clean up unreal mode
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:
.debugmsg: db "debugeroni", 0
.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 ; starting sector TODO automate this
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
mov bx, boot_msg.debugmsg
mov cx, 0
call bios_print
pop cx
cmp cl, _kernel_size
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
|