This repository has been archived by the owner on Mar 15, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboot.s
143 lines (126 loc) · 2.65 KB
/
boot.s
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
[bits 16]
main:
mov ax, 0x0000
mov ds, ax
mov ax, 0x0500
mov es, ax
cli
clc
int 0x12
mov [lower_mem], ax
; memory scan
mov di, 0x0
call do_e820
jc hang
; a20
in al, 0x92
or al, 2
out 0x92, al
; basic flat GDT
xor eax, eax
mov ax, ds
shl eax, 4
add eax, gdt_base
mov [gdtr+2], eax
mov eax, gdt_end
sub eax, gdt_base
mov [gdtr], ax
lgdt [gdtr]
; protected mode enable flag
mov eax, cr0
or eax, 1
mov cr0, eax
; set segments
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; jump to protected mode entry
extern kmain
jmp far 0x08:(kmain)
hang:
jmp hang
do_e820:
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 0x15
jc short .failed ; carry set on first call means "unsupported function"
mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"
jne short .failed
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je short .failed
jmp short .jmpin
.e820lp:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc short .e820f ; carry set means "end of list already reached"
mov edx, 0x0534D4150 ; repair potentially trashed register
.jmpin:
jcxz .skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe short .notext
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
je short .skipent
.notext:
mov ecx, [es:di + 8] ; get lower uint32_t of memory region length
or ecx, [es:di + 12] ; "or" it with upper uint32_t to test for zero
jz .skipent ; if length uint64_t is 0, skip entry
inc bp ; got a good entry: ++count, move to next storage spot
add di, 24
.skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne short .e820lp
.e820f:
mov [mmap_ent], bp ; store the entry count
clc ; there is "jc" on end of list to this point, so the carry must be cleared
ret
.failed:
stc ; "function unsupported" error exit
ret
align 8
; GDT pointer
gdtr
dw 0
dd 0
; GDT (null, code, data)
gdt_base
; null
dq 0
; code
dw 0xFFFF
dw 0
db 0
db 0x9a
db 0xcf
db 0
; data
dw 0xffff
dw 0
db 0
db 0x92
db 0xcf
db 0
gdt_end
; memory map entry count
global mmap_ent
mmap_ent db 0, 0
global lower_mem
lower_mem db 0, 0
[bits 32]
global jump_to_main
jump_to_main:
extern _eax
extern _ebx
extern _xmain
mov eax, [_eax]
mov ebx, [_ebx]
jmp [_xmain]