VirtualBox

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

Last change on this file since 107044 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

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