From ae22dab753e6a5f18fe3848929ce48fcbb96482e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Wed, 26 Feb 2014 01:16:56 +0000 Subject: [PATCH] [NTVDM] - BIOS32: As a demonstration, load a BIOS expansion ROM (the one I've tested is the "OS in PCI expansion ROM" from: https://sites.google.com/site/pinczakko/building-a-kernel-in-pci-expansion-rom ; we don't support PCI thingies at all, but the bootstrap code works correctly). - Initialize the BIOS32 stack for the callbacks. - In the common BIOS functions, if we try to load the Windows NTVDM (SoftPC) BIOS (file: bios4.rom), we immediately hit a BOP 0x00 followed by INT 0x19 (bootstrap to run an OS). The BOP 0x00 is the function used by the BIOS to ask NTVDM to initialize the hardware, the IVT with data and so on. Also we finish to load the low part of the NTVDM BIOS in it (file: bios1.rom). It's work-in-progress, nothing is done, there are lots of debugging code... Have fun! (to load a custom bios you need to put its filename as the first parameter of the BiosInitialize call, in the main() function in ntvdm.c). svn path=/branches/ntvdm/; revision=62333 --- subsystems/ntvdm/bios/bios.c | 146 +++++++++++++------------- subsystems/ntvdm/bios/bios.h | 7 +- subsystems/ntvdm/bios/bios32/bios32.c | 24 +++++ subsystems/ntvdm/bios/bios32/bios32.h | 5 +- 4 files changed, 102 insertions(+), 80 deletions(-) diff --git a/subsystems/ntvdm/bios/bios.c b/subsystems/ntvdm/bios/bios.c index 2c698d5dd7b..46d7c6055a1 100644 --- a/subsystems/ntvdm/bios/bios.c +++ b/subsystems/ntvdm/bios/bios.c @@ -11,92 +11,96 @@ #define NDEBUG #include "emulator.h" +#include "callback.h" + #include "bios.h" +#include "bop.h" +#include "rom.h" + /* PRIVATE VARIABLES **********************************************************/ static BOOLEAN Bios32Loaded = FALSE; +static CALLBACK16 __BiosContext; + +/* BOP Identifiers */ +#define BOP_BIOSINIT 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00 + // to let the virtual machine initialize itself + // the IVT and its hardware. + /* PRIVATE FUNCTIONS **********************************************************/ +static VOID WINAPI BiosInitBop(LPWORD Stack) +{ + /* Load the second part of the Windows NTVDM BIOS image */ + LPCWSTR BiosFileName = L"bios1.rom"; + PVOID BiosLocation = (PVOID)TO_LINEAR(BIOS_SEGMENT, 0x0000); + DWORD BiosSize = 0; + BOOLEAN Success; + + DPRINT1("You are loading Windows NTVDM BIOS!"); + + /* Initialize a private callback context */ + InitializeContext(&__BiosContext, BIOS_SEGMENT, 0x0000); + + Success = LoadRom(BiosFileName, BiosLocation, &BiosSize); + DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + if (Success == FALSE) return; + + // DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n" + // L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x", + // BiosLocation, + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9), + + // (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1), + // *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0)); + + /* Initialize IVT and hardware */ + + /* Load VGA BIOS */ + // Success = LoadRom(L"v7vga.rom", (PVOID)0xC0000, &BiosSize); + // DPRINT1("VGA BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! ///////////////////// + + /* Load some ROMs */ + Success = LoadRom(L"boot.bin", (PVOID)0xE0000, &BiosSize); + DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + SearchAndInitRoms(&__BiosContext); +} + /* PUBLIC FUNCTIONS ***********************************************************/ BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName, IN HANDLE ConsoleInput, IN HANDLE ConsoleOutput) { + /* Register the BIOS support BOPs */ + RegisterBop(BOP_BIOSINIT, BiosInitBop); + if (BiosFileName) { - BOOL Success; - HANDLE hBiosFile; - DWORD BiosSize; - PVOID BiosLocation; - - /* Open the BIOS file */ - SetLastError(0); // For debugging purposes - hBiosFile = CreateFileW(BiosFileName, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - DPRINT1("BIOS opening %s ; GetLastError() = %u\n", hBiosFile != INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError()); - - /* If we failed, bail out */ - if (hBiosFile == INVALID_HANDLE_VALUE) return FALSE; - - /* OK, we have a handle to the BIOS file */ - - /* - * Retrieve the size of the file. Since the size of the BIOS file - * should be at most 64kB, we just use GetFileSize. - */ - BiosSize = GetFileSize(hBiosFile, NULL); - if (BiosSize == INVALID_FILE_SIZE && GetLastError() != ERROR_SUCCESS) - { - /* We failed, return failure */ - - /* Close the BIOS file */ - CloseHandle(hBiosFile); - - return FALSE; - } - - /* BIOS location needs to be aligned on 32-bit boundary */ - /* (PVOID)((ULONG_PTR)BaseAddress + ROM_AREA_END + 1 - BiosSize) */ - BiosLocation = (PVOID)MEM_ALIGN_DOWN((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) + 1 - BiosSize, sizeof(ULONG)); - - DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n" - L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x", - BiosLocation, - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 0), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 1), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 2), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 3), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 4), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 5), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 6), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 7), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8), - *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9), + PVOID BiosLocation = NULL; + DWORD BiosSize = 0; + BOOLEAN Success = LoadBios(BiosFileName, &BiosLocation, &BiosSize); - (PVOID)((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) - 2), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 2), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 1), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 0)); - - /* Attempt to load the BIOS file into memory */ - SetLastError(0); // For debugging purposes - Success = ReadFile(hBiosFile, - REAL_TO_PHYS(BiosLocation), - BiosSize, - &BiosSize, - NULL); DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); - /* Close the BIOS file */ - CloseHandle(hBiosFile); + if (Success == FALSE) return FALSE; DisplayMessage(L"First bytes at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n" L"3 last bytes at 0x%p: 0x%02x 0x%02x 0x%02x", @@ -112,10 +116,10 @@ BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName, *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 8), *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + 9), - (PVOID)((ULONG_PTR)TO_LINEAR(0xF000, 0xFFFF) - 2), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 2), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 1), - *(PCHAR)((ULONG_PTR)SEG_OFF_TO_PTR(0xF000, 0xFFFF) - 0)); + (PVOID)((ULONG_PTR)BiosLocation + BiosSize - 2), + *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 2), + *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 1), + *(PCHAR)((ULONG_PTR)REAL_TO_PHYS(BiosLocation) + BiosSize - 0)); DisplayMessage(L"POST at 0x%p: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", TO_LINEAR(getCS(), getIP()), diff --git a/subsystems/ntvdm/bios/bios.h b/subsystems/ntvdm/bios/bios.h index 93e8660c7fb..e71d899ecff 100644 --- a/subsystems/ntvdm/bios/bios.h +++ b/subsystems/ntvdm/bios/bios.h @@ -16,14 +16,11 @@ /* DEFINES ********************************************************************/ -#define ROM_AREA_START 0xE0000 -#define ROM_AREA_END 0xFFFFF +// #define BDA_SEGMENT 0x40 +#define BIOS_SEGMENT 0xF000 #if 0 -#define BDA_SEGMENT 0x40 -#define BIOS_SEGMENT 0xF000 - /* * BIOS Data Area at 0040:XXXX * diff --git a/subsystems/ntvdm/bios/bios32/bios32.c b/subsystems/ntvdm/bios/bios32/bios32.c index a71ec25427a..d5a84c89d3c 100644 --- a/subsystems/ntvdm/bios/bios32/bios32.c +++ b/subsystems/ntvdm/bios/bios32/bios32.c @@ -13,6 +13,8 @@ #include "emulator.h" #include "callback.h" +#include "../rom.h" +#include "../bios.h" #include "bios32.h" #include "io.h" @@ -355,8 +357,22 @@ static VOID InitializeBiosInt32(VOID) BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput, IN HANDLE ConsoleOutput) { + BOOLEAN Success; UCHAR Low, High; + /* Disable interrupts */ + setIF(0); + + /* Initialize the stack */ + // That's what says IBM... (stack at 30:00FF going downwards) + // setSS(0x0000); + // setSP(0x0400); + setSS(0x0050); // Stack at 50:0400, going downwards + setSP(0x0400); + + /* Set data segment */ + setDS(BDA_SEGMENT); + /* Initialize the BDA */ Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0); Bda->EquipmentList = BIOS_EQUIPMENT_LIST; @@ -389,6 +405,14 @@ BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput, /* Enable interrupts */ setIF(1); + ///////////// MUST BE DONE AFTER IVT INITIALIZATION !! ///////////////////// + + /* Load some ROMs */ + Success = LoadRom(L"boot.bin", (PVOID)0xE0000, NULL); + DPRINT1("Test ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError()); + + SearchAndInitRoms(&BiosContext); + /* We are done */ return TRUE; } diff --git a/subsystems/ntvdm/bios/bios32/bios32.h b/subsystems/ntvdm/bios/bios32/bios32.h index 8f153818203..4f9f120485c 100644 --- a/subsystems/ntvdm/bios/bios32/bios32.h +++ b/subsystems/ntvdm/bios/bios32/bios32.h @@ -31,11 +31,8 @@ #define BIOS_EQUIPMENT_LIST 0x2C // HACK: Disable FPU for now -#define ROM_AREA_START 0xE0000 -#define ROM_AREA_END 0xFFFFF - #define BDA_SEGMENT 0x40 -#define BIOS_SEGMENT 0xF000 +// #define BIOS_SEGMENT 0xF000 /* * BIOS Data Area at 0040:XXXX -- 2.17.1