-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathos.asm
159 lines (127 loc) · 3.05 KB
/
os.asm
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
; vim: :set ft=nasm:
;--------------------
; This is a program to be booted by an x86 computer.
;
; References:
;
; - http://www.cs.cmu.edu/~410-s07/p4/p4-boot.pdf
;
; == x86 boot sequence
;
; BIOS begins like so:
;
; - run a system check
; - discover peripherials
; - discover drives and bootloaders
; - relocate one bootloader to 0x7c00 and execute it
;
; That bootloader is stage0, below.
;
;--------------------
;-------------------- Stage 0 --------------------
;
; The bootloader is constrained (along with the partition table), to
; the first sector of the disk (512 bytes). As such, the first thing
; a bootloader does is usually to load a second stage of the
; bootloader.
;
; Stage0 will:
;
; - [ ] disable interrupts
; - [ ] canonicalize %CS:%EIP
; - [ ] load segment registers (%DS, %ES, %FS, %GS, %SS)
; - [ ] set the stack pointer
; - [ ] enable interrupts
; - [ ] reset the floppy disk controller
; - [ ] read stage1 sectors from the floppy
; - [ ] jump to stage1 code
;
;-------------------------------------------------
; x86 boots up into 16-bit real mode.
;
[bits 16]
%include "asm/macros.asm"
; Add a global offset, so we don't have to add 0x7c00 to all
; the addresses.
;
[org 0x7c00]
test: db 42, 42
; Entry-point
;
data.stage0:
; BIOS stores our boot drive in dl; take note of this.
;
mov [data.boot_drive], dl
; Setup stack.
;
; The stack grows from high addresses to low addresses.
;
mov bp, 0x7c00
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, bp
mov bx, data.stage0_msg
call io.puts
mov bx, data.stage1_msg
call io.print
call load_stage1
call data.stage1
mov bx, data.stage0_end_msg
call io.print
jmp $ ; halt
; Helpers
;
%include "asm/io.asm"
%include "asm/disk_load.asm"
%include "asm/atoi.asm"
; Load up more space from disk, then jump to stage 1.
;
; We load 512 bytes * 5 = 2560 bytes = 2.56Kb
;
load_stage1:
mov bx, data.stage1
mov dh, 15
mov dl, [data.boot_drive]
call disk_load
ret
; Data
;
data.stage0_msg: db "stage0| BIOS has loaded stage0.", 0
data.stage1_msg: db "stage0| Loading stage1...", 0
data.stage0_end_msg: db 10, 13, "stage0| Error - returned from stage1."
data.ok_msg: db " ok", 0
data.boot_drive: db 0
; Required ending of stage0.
;
; The bootloader must by 512 bytes, with 0x55aa as the last 2 bytes.
;
times 510-($-$$) db 0 ; Pad to the 510th byte with zeros
dw 0xaa55 ; Tack the magic 2-byte constant at the end
;-------------------- Stage 1 --------------------
;
; Begin executing at address 0x7ee, the second boot sector
;
; Stage 1 will:
;
; - ...
;
;-------------------------------------------------
data.stage1:
mov bx, data.ok_msg
call io.puts
call monitor_repl
; mov bx, data.monitor_example
; call monitor_exec
; mov bx, dtest
; call monitor_print
mov bx, data.stage1_end_msg
call io.print
jmp $
%include "asm/lex.asm"
%include "asm/monitor.asm"
dtest: db "43828", 0 ; ab34
; dtest: db "2", 13, 0
data.stage1_end_msg: db "stage1| Error - returned from monitor", 0
data.monitor_example: incbin "stage2.monitor"