VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bootsector2-vbinstst-kernel.asm@ 76690

Last change on this file since 76690 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 KB
Line 
1; $Id: bootsector2-vbinstst-kernel.asm 76553 2019-01-01 01:45:53Z vboxsync $
2;; @file
3; bootsector #2 kernel for big instruction testcases.
4; VBoxManage setextradata bs-vbinstst-64-1 VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled 1
5;
6
7;
8; Copyright (C) 2007-2019 Oracle Corporation
9;
10; This file is part of VirtualBox Open Source Edition (OSE), as
11; available from http://www.virtualbox.org. This file is free software;
12; you can redistribute it and/or modify it under the terms of the GNU
13; General Public License (GPL) as published by the Free Software
14; Foundation, in version 2 as it comes in the "COPYING" file of the
15; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17;
18; The contents of this file may alternatively be used under the terms
19; of the Common Development and Distribution License Version 1.0
20; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
21; VirtualBox OSE distribution, in which case the provisions of the
22; CDDL are applicable instead of those of the GPL.
23;
24; You may elect to license modified versions of this file under the
25; terms and conditions of either the GPL or the CDDL or both.
26;
27
28
29;
30; This is always the first include file.
31;
32%include "bootsector2-first.mac"
33
34;
35; Include and execute the init code.
36;
37 %define BS2_INIT_RM
38 %define BS2_WITH_TRAPS
39 %define BS2_WITHOUT_RAW_MODE ; causes troubles with PIC/floppy.
40
41 %define BS2_INC_RM
42 %define BS2_INC_PE16
43 %define BS2_INC_PE32
44 %define BS2_INC_PP16
45 %define BS2_INC_PP32
46 %define BS2_INC_PAE16
47 %define BS2_INC_PAE32
48 %define BS2_INC_LM16
49 %define BS2_INC_LM32
50 %define BS2_INC_LM64
51 %include "bootsector2-common-init-code.mac"
52 %include "bootsector2-api.mac"
53 %include "iprt/formats/pe.mac"
54 %include "iprt/formats/mz.mac"
55
56
57BEGINCODE
58BEGINPROC main
59;
60; Set up the runtime environment.
61;
62 call Bs2EnableA20_r86
63
64 ; 16-bit real mode.
65%undef BS2_API_TEMPLATE_ACTION
66%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _r86)], dword NAME(a_Name %+ _r86)
67 BS2_API_TEMPLATE
68
69 ; 16-bit protected mode.
70%undef BS2_API_TEMPLATE_ACTION
71%define BS2_API_TEMPLATE_ACTION(a_Name) mov word [NAME(g_pfn %+ a_Name %+ _p16)], word NAME(a_Name %+ _p16)
72 BS2_API_TEMPLATE
73 mov eax, BS2_SEL_CS16
74%undef BS2_API_TEMPLATE_ACTION
75%define BS2_API_TEMPLATE_ACTION(a_Name) mov [NAME(g_pfn %+ a_Name %+ _p16) + 2], ax
76 BS2_API_TEMPLATE
77
78 ; 32-bit
79%undef BS2_API_TEMPLATE_ACTION
80%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _p32)], dword NAME(a_Name %+ _p32)
81 BS2_API_TEMPLATE
82
83 ; 64-bit
84%undef BS2_API_TEMPLATE_ACTION
85%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _p64)], dword NAME(a_Name %+ _p64)
86 BS2_API_TEMPLATE
87 xor eax, eax
88%undef BS2_API_TEMPLATE_ACTION
89%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _p64) + 4], eax
90 BS2_API_TEMPLATE
91
92 ; The magic markers and version number.
93 mov dword [g_u32Bs2ApiMagic], BS2_API_MAGIC
94 mov dword [g_u32Bs2ApiEndMagic], BS2_API_MAGIC
95 mov dword [g_u32Bs2ApiVersion], BS2_API_VERSION
96
97;
98; Load the extended image into high memory.
99;
100 mov dl, [g_bBootDrv]
101 call NAME(bs2LoadBigImage)
102
103;
104; Hand control over to the extended image.
105;
106%ifdef BS2_BIG_IMAGE_LM64
107 call Bs2EnterMode_rm_lm64
108BITS 64
109 mov eax, BS2_BIG_LOAD_ADDR
110 call rax
111 call Bs2ExitMode_lm64
112BITS 16
113
114%elifdef BS2_BIG_IMAGE_PP32
115 call Bs2EnterMode_rm_pp32
116BITS 32
117 mov eax, BS2_BIG_LOAD_ADDR
118 call eax
119 call Bs2ExitMode_pp32
120BITS 16
121
122%elifdef BS2_BIG_IMAGE_PAE32
123 call Bs2EnterMode_rm_pae32
124BITS 32
125 mov eax, BS2_BIG_LOAD_ADDR
126 call eax
127 call Bs2ExitMode_pae32
128BITS 16
129
130%else
131 ;
132 ; Probe the image, looking for an executable format we can deal with.
133 ; Not doing a lot of checking here, but who cares right now...
134 ;
135 call Bs2EnterMode_rm_pp32
136BITS 32
137 mov eax, BS2_BIG_LOAD_ADDR
138 cmp word [eax], IMAGE_DOS_SIGNATURE
139 jne .not_dos
140 add eax, [eax + IMAGE_DOS_HEADER.e_lfanew]
141.not_dos:
142 cmp dword [eax], IMAGE_NT_SIGNATURE
143 je .is_pe
144 mov eax, BS2_BIG_LOAD_ADDR
145 jmp .start_32
146
147.is_pe:
148 lea edx, [eax + IMAGE_NT_HEADERS32.FileHeader]
149 cmp word [edx + IMAGE_FILE_HEADER.Machine], IMAGE_FILE_MACHINE_I386
150 je .is_pe32
151 cmp word [edx + IMAGE_FILE_HEADER.Machine], IMAGE_FILE_MACHINE_AMD64
152 je .is_pe64
153 jmp .panic_32
154
155.is_pe32:
156 add edx, IMAGE_FILE_HEADER_size
157 mov eax, [edx + IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint]
158 add eax, BS2_BIG_LOAD_ADDR
159 jmp .start_32
160
161.is_pe64:
162 add edx, IMAGE_FILE_HEADER_size
163 mov eax, [edx + IMAGE_OPTIONAL_HEADER64.AddressOfEntryPoint]
164 add eax, BS2_BIG_LOAD_ADDR
165 jmp .start_64
166
167 ; Start executing at eax in 32-bit mode (current).
168.start_32:
169 call eax
170.panic_32:
171 call Bs2ExitMode_pp32
172BITS 16
173 jmp .panic
174
175 ; Start executing at eax in 64-bit mode.
176BITS 32
177.start_64:
178 call Bs2ExitMode_pp32
179BITS 16
180 call Bs2EnterMode_rm_lm64
181BITS 64
182 mov eax, eax
183 call rax
184 call Bs2ExitMode_lm64
185BITS 16
186 jmp .panic
187
188.panic:
189%endif
190 call Bs2Panic
191ENDPROC main
192
193
194
195
196;;
197; Loads the big image off the floppy.
198;
199; This uses the the_end label to figure out the starting offset.
200; The length is assumed to be the whole floppy.
201;
202; Clobbers nothing, except for 68KB of memory beyond the_end.
203;
204; @param dl The boot drive number (from BIOS).
205;
206BITS 16
207BEGINPROC bs2LoadBigImage
208 push ebp
209 movzx ebp, sp
210
211%define bSavedDiskNo byte [bp - 02h]
212 push dx
213%define bMaxSector byte [bp - 04h]
214 push 0
215%define bMaxHead byte [bp - 06h]
216 push 0
217%define bMaxCylinder byte [bp - 08h]
218 push 0
219%define pbHighDst dword [bp - 0ch]
220 push dword BS2_BIG_LOAD_ADDR
221%define SegTemp word [bp - 0eh]
222 push 0
223%define fStatus byte [bp - 10h]
224 push 0
225
226 push es
227 push ds
228 push eax
229 push edx
230 push ecx
231 push ebx
232 push edi
233 push esi
234 push ebp
235
236 ; Display message.
237 push cs
238 push .s_szLoadingBigImage
239 call PrintF_r86
240 add sp, 4
241
242
243 ;
244 ; Try figure the geometry. This defines how much we'll read.
245 ;
246 mov ah, 08h
247 xor di, di ; (es:di = 0000:0000 works around some buggy bioses, says wikipedia.)
248 mov es, di
249 int 13h
250 jc .param_error
251 mov bMaxSector, cl ; Do the cl[7:6]+ch stuff so we can address 255 sectors on the fake 63MB floppy.
252 mov bMaxHead, dh
253 mov bMaxCylinder, ch ; See above.
254 mov dl, bSavedDiskNo
255%if 0
256 movzx ax, bMaxCylinder
257 push ax
258 movzx cx, bMaxHead
259 push cx
260 movzx ax, bMaxSector
261 push ax
262 push ds
263 push .s_szDbgParam
264 call PrintF_r86
265 jmp .dprintf_param_done
266.s_szDbgParam:
267 db 13, 10, 'Floppy params max: sectors=%RX16 heads=%RX16 cylinders=%RX16', 13, 10, 0
268.dprintf_param_done:
269%endif
270
271 ;
272 ; Skip the kernel image (this could be done more efficiently, but this
273 ; also does the trick).
274 ;
275 lea eax, [dword the_end]
276 sub eax, start
277 shr eax, 9 ; sectors to skip
278 mov cx, 0001h ; sector (1-based), cylinder (0-based).
279 xor dh, dh ; head (0-based).
280.skip_one_more:
281 inc cl
282 cmp cl, bMaxSector
283 jbe .decrement_sector_count
284
285 mov cl, 1
286 inc dh
287 cmp dh, bMaxHead ; ASSUMES bMaxHead < 255.
288 jbe .decrement_sector_count
289
290 mov dh, 0
291 inc ch
292
293.decrement_sector_count:
294 dec ax
295 jnz .skip_one_more
296
297
298
299 ;
300 ; Load loop. We load and copy 64 KB at the time into the high location.
301 ; Fixed registers (above): dl=drive, cl[7:6]:ch=cylinder, dh=head, cl[5:0]=sector.
302 ;
303 lea eax, [dword the_end + 0ffffh]
304 and eax, 0ffff0000h
305 shr eax, 4
306 mov SegTemp, ax ; the 64KB segment we use for temporary storage.
307
308.the_load_loop:
309 mov al, '.'
310 call PrintChr_r86
311
312 ; Fill the segment with int3s (in case we don't read a full 64KB).
313 mov eax, 0cccccccch
314 mov di, SegTemp
315 mov es, di
316 xor edi, edi
317 push ecx
318 cld
319 mov cx, 4000h
320 rep stosd
321 pop ecx
322
323 ;
324 ; Load a bunch of sectors into the temp segment.
325 ;
326 xor ebx, ebx
327.the_sector_load_loop:
328 ; Figure how many sectors we can read without switching track or side.
329 movzx ax, bMaxSector
330 sub al, cl
331 inc al ; al = sectors left to read in the current track on the current side.
332 mov di, bx
333 shr di, 9 ; bx/512 = current sector offset.
334 neg di
335 add di, 10000h / 512 ; di = sectors left to read in the 64KB buffer.
336 cmp ax, di ; ax = min(ax, di)
337 jbe .use_ax_sector_count1
338 mov ax, di
339.use_ax_sector_count1:
340 cmp ax, 64 ; ax = min(ax,64) - Our BIOS limitation is 72, play safe.
341 jbe .use_ax_sector_count2
342 mov ax, 64
343.use_ax_sector_count2:
344 mov di, ax ; save the number of sectors we read
345
346 ; Do the reading.
347%if 0
348 push bx
349 push ax
350 push dx
351 push cx
352 push cs
353 push .s_szDbgRead
354 call PrintF_r86
355 jmp .after_read_dprintf
356.s_szDbgRead: db 'Reading CX=%RX16 DX=%RX16 AX=%RX16 BX=%RX16', 13, 10, 0
357.after_read_dprintf:
358%endif
359 push bx
360 mov ah, 02h ; ah=read function
361 int 13h
362 pop bx
363 jc .read_error
364
365 ; advance to the next sector/head/cylinder and address (lazy impl).
366.advance_another_sector:
367 cmp cl, bMaxSector
368 je .next_head
369 inc cl
370 jmp .adv_addr
371
372.next_head:
373 mov cl, 1
374 cmp dh, bMaxHead
375 je .next_cylinder
376 inc dh
377 jmp .adv_addr
378
379.next_cylinder:
380 mov dh, 0
381 cmp ch, bMaxCylinder ; No the cl[7:6]+ch stuff so we can address 255 sectors on the fake 63MB floppy.
382 jb .update_ch
383 mov fStatus, 1
384 jmp .move_block
385.update_ch:
386 inc ch
387
388.adv_addr:
389 add bx, 512
390 dec di
391 jnz .advance_another_sector
392
393 test bx, bx
394 jnz .the_sector_load_loop
395
396.move_block:
397 ;
398 ; Copy the memory into high mem.
399 ;
400%if 0
401 mov edi, pbHighDst
402 push edi
403 push cs
404 push .s_szDbgMove
405 call PrintF_r86
406 jmp .after_move_dprintf
407.s_szDbgMove: db 'Moving memory to EDI=%RX32', 13, 10, 0
408.after_move_dprintf:
409%endif
410
411 push ecx
412 push edx
413 push ds
414 push es
415 call Bs2EnterMode_rm_pp32
416BITS 32
417 ; Copy
418 mov edi, pbHighDst
419 movzx esi, SegTemp
420 shl esi, 4
421 mov ecx, 10000h / 4
422 cld
423 rep movsd
424
425 ; Verify
426 mov edi, pbHighDst
427 movzx esi, SegTemp
428 shl esi, 4
429 mov ecx, 10000h / 4
430 cld
431 repe cmpsd
432 je .mem_verified_ok
433 mov fStatus, 2
434
435.mem_verified_ok:
436 mov pbHighDst, edi
437
438 call Bs2ExitMode_pp32
439BITS 16
440 pop es
441 pop ds
442 pop edx
443 pop ecx
444
445 ; Continue reading and copying?
446 cmp fStatus, 0
447 je .the_load_loop
448
449 ; Do we quit the loop on a failure?
450 cmp fStatus, 2
451 je .verify_failed_msg
452
453 ;
454 ; Done, so end the current message line.
455 ;
456 mov al, 13
457 call PrintChr_r86
458 mov al, 10
459 call PrintChr_r86
460
461
462 pop esi
463 pop edi
464 pop ebx
465 pop ecx
466 pop edx
467 pop eax
468 pop ds
469 pop es
470 mov sp, bp
471 pop ebp
472 ret
473
474
475 ;
476 ; Something went wrong, display a message.
477 ;
478.verify_failed_msg:
479 mov edi, pbHighDst
480 push edi
481 push cs
482 push .s_szVerifyFailed
483 jmp .print_message_and_panic
484
485.param_error:
486 push ax
487 push cs
488 push .s_szParamError
489 jmp .print_message_and_panic
490
491.read_error:
492 push ax
493 push cs
494 push .s_szReadError
495 jmp .print_message_and_panic
496
497.print_message_and_panic:
498 call PrintF_r86
499 call Bs2Panic
500 jmp .print_message_and_panic
501
502.s_szReadError:
503 db 13, 10, 'Error reading: %RX8', 13, 10, 0
504.s_szParamError:
505 db 13, 10, 'Error getting params: %RX8', 13, 10, 0
506.s_szVerifyFailed:
507 db 13, 10, 'Failed to move block high... (%RX32) Got enough memory configured?', 13, 10, 0
508.s_szLoadingBigImage:
509 db 'Loading 2nd image.', 0
510ENDPROC bs2LoadBigImage
511
512
513;
514; End sections and image.
515;
516%include "bootsector2-common-end.mac"
517
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette