-
Notifications
You must be signed in to change notification settings - Fork 0
/
ppboot.asm
286 lines (274 loc) · 7.07 KB
/
ppboot.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
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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
format pe64 efi
entry main
section '.text' executable readable
include 'uefi.inc'
main:
;Save EFI system table that is loaded into rdx
mov qword [efiSystemTable],rdx
mov qword [efiImageHandle],rcx
;Output welcome message
mov rsi,welcomeStr
call printString
;Begin to load the file system
call initEfiFileSystem
mov r8,ldrFN
call openFile
;Setup GOP
call setupGOP
;Exit boot services
mov rax,qword [efiSystemTable]
mov rax,[rax+EFI_SYSTEM_TABLE.BootServices]
sub rsp,32
call qword [rax+EFI_BOOT_SERVICES_TABLE.ExitBootServices]
add rsp,32
;Move file to proper memory address
mov rsi,[efiOSBufferHandle]
mov rdi,0x20000
mov rcx,[efiReadSize]
repe movsb
call elfLoad
;Jump to kernel
mov esi,[frameBufferPPS]
mov rdi,[uefiGOPHandle]
jmp 0x30000
ret
elfLoad:
;Check ELF signature
cmp dword [20001h],1179403647
je failElfLoad
;Get Program entry and program header pos
mov rax,qword [20018h]
mov rbx,qword [20020h]
mov r8w,word [20038h]
;Read and load program entries
add rbx,20008h
loopreadProgEntries:
mov rcx,qword [rbx]
mov rdx,qword [rbx+8]
test rcx,rcx
jz skipCopyDataElf
mov r9,qword [rbx+24]
mov rsi,rcx
add rsi,20000h
mov rdi,rdx
mov rcx,r9
repe movsb
skipCopyDataElf:
add rbx,56
dec r8
cmp r8,0
jne loopreadProgEntries
failElfLoad:
ret
setupGOP:
;Get GOP pointer
lea rcx,[gopguid]
mov rdx,0
lea r8,[efiGOPHandle]
mov r9,qword [efiSystemTable]
mov r9,[r9+EFI_SYSTEM_TABLE.BootServices]
sub rsp,32
call qword [r9+EFI_BOOT_SERVICES_TABLE.LocateProtocol]
add rsp,32
;Get current video mode
mov rcx,[efiGOPHandle]
mov edx,dword [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
mov edx,dword [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.CurrentMode]
and edx,edx
lea r8,[gopModeSize]
lea r9,[gopModeInfo]
sub rsp,32
call qword [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode]
add rsp,32
mov r9, qword [gopModeInfo]
mov eax,dword [r9+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
mov ebx,dword [r9+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
;Query number of video modes
mov rax,[efiGOPHandle]
mov rax,[rax+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
mov ecx,dword [rax+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode]
and ecx,ecx
dec rcx
loopgetgopmodes:
push rcx
mov rdx,rcx
mov rcx,[efiGOPHandle]
lea r8,[gopModeSize]
lea r9,[gopModeInfo]
sub rsp,32
call qword [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode]
add rsp,32
mov r9, qword [gopModeInfo]
mov eax,dword [r9+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
mov ebx,dword [r9+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
imul rax,rbx
cmp rax,qword [currentHighestRes]
jl skipsethighestres
mov byte [currentHighestIndex],dl
mov qword [currentHighestRes],rax
mov eax,dword [r9+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanline]
mov dword [frameBufferPPS],eax
skipsethighestres:
pop rcx
loop loopgetgopmodes
;Set the highest resolution as the video mode
mov dl,byte [currentHighestIndex]
mov rcx,[efiGOPHandle]
sub rsp,32
call qword [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode]
add rsp,32
ret
initEfiFileSystem:
;Get loaded image pointer
mov rcx,[efiImageHandle]
mov rdx,EFI_LOADED_IMAGE_PROTOCOL_GUID
lea r8,[efiLoadedImage]
mov r9,qword [efiSystemTable]
mov r9,[r9+EFI_SYSTEM_TABLE.BootServices]
sub rsp,32
call qword [r9+EFI_BOOT_SERVICES_TABLE.HandleProtocol]
add rsp,32
;Get volume handle
mov rcx,[efiLoadedImage]
mov rcx,[rcx+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle]
mov rdx,EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID
lea r8,[efiVolumeHandle]
mov r9,qword [efiSystemTable]
mov r9,[r9+EFI_SYSTEM_TABLE.BootServices]
sub rsp,32
call qword [r9+EFI_BOOT_SERVICES_TABLE.HandleProtocol]
add rsp,32
;Open Volume
mov rcx,[efiVolumeHandle]
lea rdx,[efiRootFSHandle]
sub rsp,32
call qword [rcx+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume]
add rsp,32
ret
openFile:
;Open file and check if file loaded successfully
mov rcx,[efiRootFSHandle]
lea rdx,[efiFileHandle]
mov r9,EFI_FILE_MODE_READ
sub rsp,32
call qword [rcx+EFI_FILE_PROTOCOL.Open]
add rsp,32
cmp rax,0
je skiperrorloadingkernel
sub rsp,8
mov rsi,errorStr
call printString
add rsp,8
call waitForAnyKey
call resetPC
skiperrorloadingkernel:
;Get file size
mov rcx,[efiFileHandle]
mov rdx,EFI_FILE_INFO_ID_GUID
lea r8,[efiFileInfoBufferSize]
mov r9,efiFileInfoBuffer
sub rsp,40
call qword [rcx+EFI_FILE_PROTOCOL.GetInfo]
add rsp,40
mov r9,[efiFileInfoBuffer+8]
mov qword [efiReadSize],r9
;Allocate memory pool
mov rcx,2
mov rdx,qword [efiReadSize]
lea r8,[efiOSBufferHandle]
mov r9,qword [efiSystemTable]
mov r9,[r9+EFI_SYSTEM_TABLE.BootServices]
sub rsp,32
call qword [r9+EFI_BOOT_SERVICES_TABLE.AllocatePool]
add rsp,32
;Read file
mov rcx,[efiFileHandle]
lea rdx,[efiReadSize]
mov r8,[efiOSBufferHandle]
sub rsp,32
call qword [rcx+EFI_FILE_PROTOCOL.Read]
add rsp,32
ret
waitForAnyKey:
mov rdx,1
mov rcx,[efiSystemTable]
mov rcx,[rcx+EFI_SYSTEM_TABLE.ConIn]
sub rsp,32
call qword [rcx+EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset]
add rsp,32
loopwaitforkeypress:
lea rdx,[efiKeyData]
mov rcx,[efiSystemTable]
mov rcx,[rcx+EFI_SYSTEM_TABLE.ConIn]
sub rsp,32
call qword [rcx+EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke]
add rsp,32
and rax,0xff
cmp rax,6 ;Check if its not ready
je loopwaitforkeypress
ret
resetPC:
;Reset using 8042 method (if possible)
mov al,0xfe
out 0x64,al
;Reset using UEFI runtime services
mov rax,qword [efiSystemTable]
mov rax,[rax+EFI_SYSTEM_TABLE.RuntimeServices]
mov rax,[rax+EFI_RUNTIME_SERVICES_TABLE.ResetSystem]
mov r9d,0
mov r8d,0
mov edx,0
mov ecx,0
call rax
ret
printString:
push rdx
push rcx
push rax
push rsi
;Get ConOut in rcx, then use that to get the pointer for the OutputString function in rax
mov rdx,qword [efiSystemTable]
mov rcx,[rdx+EFI_SYSTEM_TABLE.ConOut]
mov rax,[rcx+SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString]
xchg rdx,rsi
;Setup shadow space for GPRs
sub rsp,32
call rax
add rsp,32
pop rsi
pop rax
pop rcx
pop rdx
ret
section '.data' readable writable
welcomeStr du 'Doors++ UEFI bootloader', 0xD, 0xA, 0
errorStr du 'Error loading PPKRNL.SYS!', 0xd, 0xa, 'Press any key to reboot...',0
ldrFN du 'ppkrnl.sys',0
efiSystemTable dq 0
efiLoadedImage dq 0
efiImageHandle dq 0
efiDevicePathHandle dq 0
efiVolumeHandle dq 0
efiRootFSHandle dq 0
efiFileHandle dq 0
efiOSBufferHandle dq 0
efiGOPHandle dq 0
efiReadSize dq 1216
efiKeyData dq 0
efiFileInfo dq 0
currentHighestRes dq 0
currentHighestIndex db 0
frameBufferPPS dd 0
uefiGOPHandle dq 0
EFI_LOADED_IMAGE_PROTOCOL_GUID db 0xa1, 0x31, 0x1b, 0x5b, 0x62, 0x95, 0xd2, 0x11, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID db 0x22, 0x5b, 0x4e, 0x96, 0x59, 0x64, 0xd2, 0x11, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b
EFI_FILE_INFO_ID_GUID db 0x92, 0x6e, 0x57, 0x09, 0x3f, 0x6d, 0xd2, 0x11, 0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b
efiFileInfoBufferSize dq 128
efiFileInfoBuffer: times 128 db 0
blockiouuid db EFI_BLOCK_IO_PROTOCOL_UUID
gopguid db EFI_GRAPHICS_OUTPUT_PROTOCOL_UUID
gopMax dd 0
gopModeSize dq 0
gopModeInfo dd 0,0,0,0,0,0,0,0
EFI_FILE_MODE_READ = 0x0000000000000001
secondStageLoc = 0x030000