summaryrefslogtreecommitdiffstats
path: root/src/VBox/ValidationKit/bootsectors/bootsector2-vbinstst-kernel.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/ValidationKit/bootsectors/bootsector2-vbinstst-kernel.asm')
-rw-r--r--src/VBox/ValidationKit/bootsectors/bootsector2-vbinstst-kernel.asm527
1 files changed, 527 insertions, 0 deletions
diff --git a/src/VBox/ValidationKit/bootsectors/bootsector2-vbinstst-kernel.asm b/src/VBox/ValidationKit/bootsectors/bootsector2-vbinstst-kernel.asm
new file mode 100644
index 00000000..b1a53f7f
--- /dev/null
+++ b/src/VBox/ValidationKit/bootsectors/bootsector2-vbinstst-kernel.asm
@@ -0,0 +1,527 @@
+; $Id: bootsector2-vbinstst-kernel.asm $
+;; @file
+; bootsector #2 kernel for big instruction testcases.
+; VBoxManage setextradata bs-vbinstst-64-1 VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled 1
+;
+
+;
+; Copyright (C) 2007-2023 Oracle and/or its affiliates.
+;
+; This file is part of VirtualBox base platform packages, as
+; available from https://www.virtualbox.org.
+;
+; This program is free software; you can redistribute it and/or
+; modify it under the terms of the GNU General Public License
+; as published by the Free Software Foundation, in version 3 of the
+; License.
+;
+; This program is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+; General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program; if not, see <https://www.gnu.org/licenses>.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+; in the VirtualBox distribution, in which case the provisions of the
+; CDDL are applicable instead of those of the GPL.
+;
+; You may elect to license modified versions of this file under the
+; terms and conditions of either the GPL or the CDDL or both.
+;
+; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+;
+
+
+;
+; This is always the first include file.
+;
+%include "bootsector2-first.mac"
+
+;
+; Include and execute the init code.
+;
+ %define BS2_INIT_RM
+ %define BS2_WITH_TRAPS
+ %define BS2_WITHOUT_RAW_MODE ; causes troubles with PIC/floppy.
+
+ %define BS2_INC_RM
+ %define BS2_INC_PE16
+ %define BS2_INC_PE32
+ %define BS2_INC_PP16
+ %define BS2_INC_PP32
+ %define BS2_INC_PAE16
+ %define BS2_INC_PAE32
+ %define BS2_INC_LM16
+ %define BS2_INC_LM32
+ %define BS2_INC_LM64
+ %include "bootsector2-common-init-code.mac"
+ %include "bootsector2-api.mac"
+ %include "iprt/formats/pe.mac"
+ %include "iprt/formats/mz.mac"
+
+
+BEGINCODE
+BEGINPROC main
+;
+; Set up the runtime environment.
+;
+ call Bs2EnableA20_r86
+
+ ; 16-bit real mode.
+%undef BS2_API_TEMPLATE_ACTION
+%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _r86)], dword NAME(a_Name %+ _r86)
+ BS2_API_TEMPLATE
+
+ ; 16-bit protected mode.
+%undef BS2_API_TEMPLATE_ACTION
+%define BS2_API_TEMPLATE_ACTION(a_Name) mov word [NAME(g_pfn %+ a_Name %+ _p16)], word NAME(a_Name %+ _p16)
+ BS2_API_TEMPLATE
+ mov eax, BS2_SEL_CS16
+%undef BS2_API_TEMPLATE_ACTION
+%define BS2_API_TEMPLATE_ACTION(a_Name) mov [NAME(g_pfn %+ a_Name %+ _p16) + 2], ax
+ BS2_API_TEMPLATE
+
+ ; 32-bit
+%undef BS2_API_TEMPLATE_ACTION
+%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _p32)], dword NAME(a_Name %+ _p32)
+ BS2_API_TEMPLATE
+
+ ; 64-bit
+%undef BS2_API_TEMPLATE_ACTION
+%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _p64)], dword NAME(a_Name %+ _p64)
+ BS2_API_TEMPLATE
+ xor eax, eax
+%undef BS2_API_TEMPLATE_ACTION
+%define BS2_API_TEMPLATE_ACTION(a_Name) mov dword [NAME(g_pfn %+ a_Name %+ _p64) + 4], eax
+ BS2_API_TEMPLATE
+
+ ; The magic markers and version number.
+ mov dword [g_u32Bs2ApiMagic], BS2_API_MAGIC
+ mov dword [g_u32Bs2ApiEndMagic], BS2_API_MAGIC
+ mov dword [g_u32Bs2ApiVersion], BS2_API_VERSION
+
+;
+; Load the extended image into high memory.
+;
+ mov dl, [g_bBootDrv]
+ call NAME(bs2LoadBigImage)
+
+;
+; Hand control over to the extended image.
+;
+%ifdef BS2_BIG_IMAGE_LM64
+ call Bs2EnterMode_rm_lm64
+BITS 64
+ mov eax, BS2_BIG_LOAD_ADDR
+ call rax
+ call Bs2ExitMode_lm64
+BITS 16
+
+%elifdef BS2_BIG_IMAGE_PP32
+ call Bs2EnterMode_rm_pp32
+BITS 32
+ mov eax, BS2_BIG_LOAD_ADDR
+ call eax
+ call Bs2ExitMode_pp32
+BITS 16
+
+%elifdef BS2_BIG_IMAGE_PAE32
+ call Bs2EnterMode_rm_pae32
+BITS 32
+ mov eax, BS2_BIG_LOAD_ADDR
+ call eax
+ call Bs2ExitMode_pae32
+BITS 16
+
+%else
+ ;
+ ; Probe the image, looking for an executable format we can deal with.
+ ; Not doing a lot of checking here, but who cares right now...
+ ;
+ call Bs2EnterMode_rm_pp32
+BITS 32
+ mov eax, BS2_BIG_LOAD_ADDR
+ cmp word [eax], IMAGE_DOS_SIGNATURE
+ jne .not_dos
+ add eax, [eax + IMAGE_DOS_HEADER.e_lfanew]
+.not_dos:
+ cmp dword [eax], IMAGE_NT_SIGNATURE
+ je .is_pe
+ mov eax, BS2_BIG_LOAD_ADDR
+ jmp .start_32
+
+.is_pe:
+ lea edx, [eax + IMAGE_NT_HEADERS32.FileHeader]
+ cmp word [edx + IMAGE_FILE_HEADER.Machine], IMAGE_FILE_MACHINE_I386
+ je .is_pe32
+ cmp word [edx + IMAGE_FILE_HEADER.Machine], IMAGE_FILE_MACHINE_AMD64
+ je .is_pe64
+ jmp .panic_32
+
+.is_pe32:
+ add edx, IMAGE_FILE_HEADER_size
+ mov eax, [edx + IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint]
+ add eax, BS2_BIG_LOAD_ADDR
+ jmp .start_32
+
+.is_pe64:
+ add edx, IMAGE_FILE_HEADER_size
+ mov eax, [edx + IMAGE_OPTIONAL_HEADER64.AddressOfEntryPoint]
+ add eax, BS2_BIG_LOAD_ADDR
+ jmp .start_64
+
+ ; Start executing at eax in 32-bit mode (current).
+.start_32:
+ call eax
+.panic_32:
+ call Bs2ExitMode_pp32
+BITS 16
+ jmp .panic
+
+ ; Start executing at eax in 64-bit mode.
+BITS 32
+.start_64:
+ call Bs2ExitMode_pp32
+BITS 16
+ call Bs2EnterMode_rm_lm64
+BITS 64
+ mov eax, eax
+ call rax
+ call Bs2ExitMode_lm64
+BITS 16
+ jmp .panic
+
+.panic:
+%endif
+ call Bs2Panic
+ENDPROC main
+
+
+
+
+;;
+; Loads the big image off the floppy.
+;
+; This uses the the_end label to figure out the starting offset.
+; The length is assumed to be the whole floppy.
+;
+; Clobbers nothing, except for 68KB of memory beyond the_end.
+;
+; @param dl The boot drive number (from BIOS).
+;
+BITS 16
+BEGINPROC bs2LoadBigImage
+ push ebp
+ movzx ebp, sp
+
+%define bSavedDiskNo byte [bp - 02h]
+ push dx
+%define bMaxSector byte [bp - 04h]
+ push 0
+%define bMaxHead byte [bp - 06h]
+ push 0
+%define bMaxCylinder byte [bp - 08h]
+ push 0
+%define pbHighDst dword [bp - 0ch]
+ push dword BS2_BIG_LOAD_ADDR
+%define SegTemp word [bp - 0eh]
+ push 0
+%define fStatus byte [bp - 10h]
+ push 0
+
+ push es
+ push ds
+ push eax
+ push edx
+ push ecx
+ push ebx
+ push edi
+ push esi
+ push ebp
+
+ ; Display message.
+ push cs
+ push .s_szLoadingBigImage
+ call PrintF_r86
+ add sp, 4
+
+
+ ;
+ ; Try figure the geometry. This defines how much we'll read.
+ ;
+ mov ah, 08h
+ xor di, di ; (es:di = 0000:0000 works around some buggy bioses, says wikipedia.)
+ mov es, di
+ int 13h
+ jc .param_error
+ mov bMaxSector, cl ; Do the cl[7:6]+ch stuff so we can address 255 sectors on the fake 63MB floppy.
+ mov bMaxHead, dh
+ mov bMaxCylinder, ch ; See above.
+ mov dl, bSavedDiskNo
+%if 0
+ movzx ax, bMaxCylinder
+ push ax
+ movzx cx, bMaxHead
+ push cx
+ movzx ax, bMaxSector
+ push ax
+ push ds
+ push .s_szDbgParam
+ call PrintF_r86
+ jmp .dprintf_param_done
+.s_szDbgParam:
+ db 13, 10, 'Floppy params max: sectors=%RX16 heads=%RX16 cylinders=%RX16', 13, 10, 0
+.dprintf_param_done:
+%endif
+
+ ;
+ ; Skip the kernel image (this could be done more efficiently, but this
+ ; also does the trick).
+ ;
+ lea eax, [dword the_end]
+ sub eax, start
+ shr eax, 9 ; sectors to skip
+ mov cx, 0001h ; sector (1-based), cylinder (0-based).
+ xor dh, dh ; head (0-based).
+.skip_one_more:
+ inc cl
+ cmp cl, bMaxSector
+ jbe .decrement_sector_count
+
+ mov cl, 1
+ inc dh
+ cmp dh, bMaxHead ; ASSUMES bMaxHead < 255.
+ jbe .decrement_sector_count
+
+ mov dh, 0
+ inc ch
+
+.decrement_sector_count:
+ dec ax
+ jnz .skip_one_more
+
+
+
+ ;
+ ; Load loop. We load and copy 64 KB at the time into the high location.
+ ; Fixed registers (above): dl=drive, cl[7:6]:ch=cylinder, dh=head, cl[5:0]=sector.
+ ;
+ lea eax, [dword the_end + 0ffffh]
+ and eax, 0ffff0000h
+ shr eax, 4
+ mov SegTemp, ax ; the 64KB segment we use for temporary storage.
+
+.the_load_loop:
+ mov al, '.'
+ call PrintChr_r86
+
+ ; Fill the segment with int3s (in case we don't read a full 64KB).
+ mov eax, 0cccccccch
+ mov di, SegTemp
+ mov es, di
+ xor edi, edi
+ push ecx
+ cld
+ mov cx, 4000h
+ rep stosd
+ pop ecx
+
+ ;
+ ; Load a bunch of sectors into the temp segment.
+ ;
+ xor ebx, ebx
+.the_sector_load_loop:
+ ; Figure how many sectors we can read without switching track or side.
+ movzx ax, bMaxSector
+ sub al, cl
+ inc al ; al = sectors left to read in the current track on the current side.
+ mov di, bx
+ shr di, 9 ; bx/512 = current sector offset.
+ neg di
+ add di, 10000h / 512 ; di = sectors left to read in the 64KB buffer.
+ cmp ax, di ; ax = min(ax, di)
+ jbe .use_ax_sector_count1
+ mov ax, di
+.use_ax_sector_count1:
+ cmp ax, 64 ; ax = min(ax,64) - Our BIOS limitation is 72, play safe.
+ jbe .use_ax_sector_count2
+ mov ax, 64
+.use_ax_sector_count2:
+ mov di, ax ; save the number of sectors we read
+
+ ; Do the reading.
+%if 0
+ push bx
+ push ax
+ push dx
+ push cx
+ push cs
+ push .s_szDbgRead
+ call PrintF_r86
+ jmp .after_read_dprintf
+.s_szDbgRead: db 'Reading CX=%RX16 DX=%RX16 AX=%RX16 BX=%RX16', 13, 10, 0
+.after_read_dprintf:
+%endif
+ push bx
+ mov ah, 02h ; ah=read function
+ int 13h
+ pop bx
+ jc .read_error
+
+ ; advance to the next sector/head/cylinder and address (lazy impl).
+.advance_another_sector:
+ cmp cl, bMaxSector
+ je .next_head
+ inc cl
+ jmp .adv_addr
+
+.next_head:
+ mov cl, 1
+ cmp dh, bMaxHead
+ je .next_cylinder
+ inc dh
+ jmp .adv_addr
+
+.next_cylinder:
+ mov dh, 0
+ cmp ch, bMaxCylinder ; No the cl[7:6]+ch stuff so we can address 255 sectors on the fake 63MB floppy.
+ jb .update_ch
+ mov fStatus, 1
+ jmp .move_block
+.update_ch:
+ inc ch
+
+.adv_addr:
+ add bx, 512
+ dec di
+ jnz .advance_another_sector
+
+ test bx, bx
+ jnz .the_sector_load_loop
+
+.move_block:
+ ;
+ ; Copy the memory into high mem.
+ ;
+%if 0
+ mov edi, pbHighDst
+ push edi
+ push cs
+ push .s_szDbgMove
+ call PrintF_r86
+ jmp .after_move_dprintf
+.s_szDbgMove: db 'Moving memory to EDI=%RX32', 13, 10, 0
+.after_move_dprintf:
+%endif
+
+ push ecx
+ push edx
+ push ds
+ push es
+ call Bs2EnterMode_rm_pp32
+BITS 32
+ ; Copy
+ mov edi, pbHighDst
+ movzx esi, SegTemp
+ shl esi, 4
+ mov ecx, 10000h / 4
+ cld
+ rep movsd
+
+ ; Verify
+ mov edi, pbHighDst
+ movzx esi, SegTemp
+ shl esi, 4
+ mov ecx, 10000h / 4
+ cld
+ repe cmpsd
+ je .mem_verified_ok
+ mov fStatus, 2
+
+.mem_verified_ok:
+ mov pbHighDst, edi
+
+ call Bs2ExitMode_pp32
+BITS 16
+ pop es
+ pop ds
+ pop edx
+ pop ecx
+
+ ; Continue reading and copying?
+ cmp fStatus, 0
+ je .the_load_loop
+
+ ; Do we quit the loop on a failure?
+ cmp fStatus, 2
+ je .verify_failed_msg
+
+ ;
+ ; Done, so end the current message line.
+ ;
+ mov al, 13
+ call PrintChr_r86
+ mov al, 10
+ call PrintChr_r86
+
+
+ pop esi
+ pop edi
+ pop ebx
+ pop ecx
+ pop edx
+ pop eax
+ pop ds
+ pop es
+ mov sp, bp
+ pop ebp
+ ret
+
+
+ ;
+ ; Something went wrong, display a message.
+ ;
+.verify_failed_msg:
+ mov edi, pbHighDst
+ push edi
+ push cs
+ push .s_szVerifyFailed
+ jmp .print_message_and_panic
+
+.param_error:
+ push ax
+ push cs
+ push .s_szParamError
+ jmp .print_message_and_panic
+
+.read_error:
+ push ax
+ push cs
+ push .s_szReadError
+ jmp .print_message_and_panic
+
+.print_message_and_panic:
+ call PrintF_r86
+ call Bs2Panic
+ jmp .print_message_and_panic
+
+.s_szReadError:
+ db 13, 10, 'Error reading: %RX8', 13, 10, 0
+.s_szParamError:
+ db 13, 10, 'Error getting params: %RX8', 13, 10, 0
+.s_szVerifyFailed:
+ db 13, 10, 'Failed to move block high... (%RX32) Got enough memory configured?', 13, 10, 0
+.s_szLoadingBigImage:
+ db 'Loading 2nd image.', 0
+ENDPROC bs2LoadBigImage
+
+
+;
+; End sections and image.
+;
+%include "bootsector2-common-end.mac"
+