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
|
; legacy BIOS PC-boot code, starts in 16-bit real mode
; BIOS always loads us to this location
[org 0x7c00]
; 16-bit real-mode
[bits 16]
; initialize segment registers
mov ax, 0
mov ds, ax
mov es, ax
mov ss, ax
; dl contains the boot drive, primarily because that's the last function
; called by the BIOS MBR loader, we remember that for loading additional
; blocks from the boot medium
mov [BOOT_DRIVE], dl
; make sure we know the location of the stack by setting it on our own
mov bp, 0xFFFF
mov sp, bp
; print out some information about CPU mode and BIOS boot drive
mov si, MESSAGE_REAL_MODE
call print_string
mov si, MESSAGE_BOOT_DRIVE
call print_string
mov ax, dx
call print_hex
call print_newline
; print we are going to load stage 2 of the boot blocks
mov si, MESSAGE_LOADING_STAGE_2
call print_string
mov dl, [BOOT_DRIVE]
call read_from_disk
jmp stage2
%include "stage1_functions.asm"
DISK_ERROR:
db "DISK ERROR ", 0
SHORT_READ:
db "DISK SHORT READ", 0
MESSAGE_REAL_MODE:
db "Started in 16-bit Real Mode", 13, 10, 0
MESSAGE_BOOT_DRIVE:
db "Booting from drive ", 0
MESSAGE_LOADING_STAGE_2:
db "Loading stage 2 boot loader", 13, 10, 0
BOOT_DRIVE:
db 0
; pad rest of sector with zeroes so we get 512 bytes in the end
times 510-($-$$) db 0
; magic number of a boot sector
dw 0xaa55
stage2:
mov si, MESSAGE_STAGE_2_LOADED
call print_string
; remember current position on screen
call current_row
mov [CURSOR_Y], dh
call switch_to_protected_mode
; we should never get here, but just in case
jmp $
MESSAGE_STAGE_2_LOADED:
db "Stage 2 boot sectors loaded", 13, 10, 0
%include "switch_mode.asm"
[bits 32]
BEGIN_PROTECTED_MODE:
mov edx, 1
_loop_test:
mov si, MESSAGE_INITIALIZING
call pm_print_string
call pm_print_newline
dec edx
cmp edx, 0
jnz _loop_test
_end_of_test:
mov si, MESSAGE_PROTECTED_MODE
call pm_print_string
call pm_print_newline
mov si, MESSAGE_CALL_C_ENTRY
call pm_print_string
call pm_print_newline
; call our kernel
call c_entry
mov si, MESSAGE_HALTED
call pm_print_string
call pm_print_newline
; end of C, disable interupts again, NMIs can still happen
cli
_halt_loop:
hlt
jmp _halt_loop
MESSAGE_PROTECTED_MODE:
db "Switched to 32-bit Protected Mode", 0
MESSAGE_INITIALIZING:
db "Initializing the Foo machine..", 0
MESSAGE_CALL_C_ENTRY:
db "Calling C entry function", 0
MESSAGE_HALTED:
db "Operating system halted", 0
%include "stage2_functions.asm"
; make sure we have full sectors
times 2048-($-$$) db 0
c_entry:
|