-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootsector.asm
More file actions
219 lines (149 loc) · 4.09 KB
/
Copy pathbootsector.asm
File metadata and controls
219 lines (149 loc) · 4.09 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
BITS 16
jmp start
; ---- Data ----
welcome_string: dw "Welcome to LukOS! Here are the numbers in the fibonacci sequence under 1 billion:", 0
space: db " ", 0
gdt: ; Global Description Table - each entry 8 bytes, our two segments define the same area
gdt_null EQU $-gdt ; first entry has to be null
dq 0
gdt_code EQU $-gdt ; Code
dw 0FFFFh ; Sets limit to 4G (max possible)
dw 0 ; Where it starts
db 0 ; Continuation of start
db 10011010b ; Type
db 11001111b
db 0
gdt_data EQU $-gdt ; Data and stack
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:
gdt_desc: ; Used by NASM to find address
gdt_size dw gdt_end-gdt-1
gdt_base dd gdt
; ---- Bootloader ----
start:
ORG 0x7C00 ; Set initial offset to where BIOS puts us
; Needed if we want to do stuff before entering protected mode, otherwise not nessesary
; mov ax, 07C0h ; Set stack segment
; add ax, 288
; mov ss, ax
; mov sp, 4096 ; Set stack pointer
; Preparing to enter Protected mode ------
cli ; disables interupts
xor ax, ax
mov ds, ax ; sets ds to null (ds can't be set directly)
lgdt [gdt_desc] ; loads GDT table
; Here we enter Protected mode -----
mov eax, cr0 ; Copies control register
or eax, 1 ; Sets lowest bit to 1, (which enables Protected mode)
mov cr0, eax ; Copies back
jmp 08h:clear_pipe ; Does a "long jump" to clear old 16-bit instructions
[BITS 32]
clear_pipe:
mov eax, gdt_data; Set stack segment
mov ds,eax
mov es,eax
mov fs,eax
mov gs,eax
mov ss,eax
mov esp, 0xffff ; Sets stack pointer
call vga_clear
mov esi, welcome_string
call vga_print_string
; Fibonacci
mov ecx, 0 ; prev
mov eax, 1 ; current
loop:
cmp ecx, 1000000000
jg loop_end
mov esi, space
call vga_print_string
mov esi, ecx
call vga_print_integer
mov edx, eax ; store current
add eax, ecx ; add prev to current
mov ecx, edx ; update prev to what was current
jmp loop
loop_end:
hang:
jmp hang ; infinite loop!
vga_print_integer: ; Recursive function to print the integer passed in ESI via the VGA buffer
push eax
push esi
push edx
push ecx
mov eax, esi ; Set dividend
mov ecx, 10 ; set to divide by 10
mov edx, 0 ; clear dividend
div ecx ; EAX has quotent, EDX has remainder
cmp eax, 0 ; If nothing left, skip
je .vga_print_integer_done
mov esi, eax ; otherwise, do remainder
call vga_print_integer
.vga_print_integer_done:
add edx, 0x30 ; adds 0x30 since the unicode for "0" is 0x30, unicode "1" is 0x31, unicode "2" is 0x32, etc..
mov esi, edx
call vga_print_byte
pop ecx
pop edx
pop esi
pop eax
ret
vga_clear: ; Clears the screen
push edi
push ecx
mov edi, 0xb8000 ; VGA buffer
mov ecx, 0xb8000
add ecx, 4000 ; 80*25*2 = End of VGA buffer
.vga_clear_start:
cmp edi, ecx
je .vga_clear_end ; Triggers when reaches end
mov byte [edi], 0 ; Blank
inc edi
mov byte [edi], 0 ; Black background
inc edi
jmp .vga_clear_start
.vga_clear_end:
pop ecx
pop edi
ret
vga_print_byte: ; Print byte in ESI to screen via VGA buffer
push edi
push ecx
push eax
mov edi, 0xb8000 ; VGA buffer
.vga_print_byte_find_end: ; Finds next blank space
mov ecx, [edi]
cmp ecx, 0
je .vga_print_byte_find_end_done
inc edi
jmp .vga_print_byte_find_end
.vga_print_byte_find_end_done: ; Prints byte to that space
mov eax, esi
mov byte [edi], al
inc edi
mov byte [edi], 0x1f ; White on blue
pop eax
pop ecx
pop edi
ret
vga_print_string: ; Print string in ESI to screen via VGA buffer
push eax
.vga_print_string_start:
lodsb ; Loads a single byte from ESI to AL
cmp al, 0 ; If 0, stop
je .vga_print_string_done
push esi
mov esi, eax
call vga_print_byte
pop esi
jmp .vga_print_string_start
.vga_print_string_done:
pop eax
ret
times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature