- Implement BIOS access routines in HAL.

- Implement HalResetDisplay using those routines.
- Uncomment a display reset in bootvid (as real Windows bootvid does).
- Remove 1 sec delay from the shutdown thread.
- As a result, no more red screen flashing at the end of the 1st stage, shutdown quotes are displayed again, and BSODs are shown correctly.

svn path=/trunk/; revision=31251
This commit is contained in:
Aleksey Bragin
2007-12-15 17:15:48 +00:00
parent 6d60d0c394
commit ffa5f05eca
9 changed files with 717 additions and 10 deletions

View File

@@ -420,10 +420,8 @@ TryAgain:
/* Now check if we have to set the mode */
if (SetMode)
{
//
// Reset the display
//
//HalResetDisplay();
/* Reset the display */
HalResetDisplay();
curr_x = 0;
curr_y = 0;
@@ -463,7 +461,7 @@ VidResetDisplay(IN BOOLEAN HalReset)
curr_y = 0;
/* Clear the screen with HAL if we were asked to */
//if (HalReset) HalResetDisplay();
if (HalReset) HalResetDisplay();
/* Re-initialize the VGA Display */
VgaInterpretCmdStream(AT_Initialization);

View File

@@ -0,0 +1,237 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL - See COPYING in the top level directory
* FILE: hal/halx86/generic/bios.c
* PURPOSE: BIOS Access Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES *******************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
UCHAR HalpIopmSaveBuffer[0x2000];
ULONG HalpSavedPfn;
HARDWARE_PTE HalpSavedPte;
ULONG HalpGpfHandler;
ULONG HalpBopHandler;
USHORT HalpSavedIopmBase;
PUCHAR HalpSavedIoMap;
ULONG HalpSavedEsp0;
#define GetPdeAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 22) << 2) + 0xC0300000)
#define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000)
/* FUNCTIONS ******************************************************************/
VOID
NTAPI
HalpStoreAndClearIopm(IN PUCHAR IoMap)
{
ULONG i;
/* Backup the old I/O Map */
RtlCopyMemory(HalpIopmSaveBuffer, IoMap, 0x2000);
/* Erase the current one */
for (i = 0; i < 0x2000; i++) IoMap[i] = 0;
for (i = 0x2000; i < 0x2004; i++) IoMap[i] = 0xFF;
}
VOID
NTAPI
HalpRestoreIopm(IN PUCHAR IoMap)
{
ULONG i;
/* Restore the backed up copy, and initialize it */
RtlCopyMemory(IoMap, HalpIopmSaveBuffer, 0x2000);
for (i = 0x2000; i < 0x2004; i++) IoMap[i] = 0xFF;
}
VOID
NTAPI
HalpMapRealModeMemory(VOID)
{
PHARDWARE_PTE Pte, V86Pte;
ULONG i;
/* Get the page table directory for the lowest meg of memory */
Pte = GetPdeAddress(0);
HalpSavedPfn = Pte->PageFrameNumber;
HalpSavedPte = *Pte;
/* Map it to the HAL reserved region and make it valid */
Pte->Valid = 1;
Pte->Write = 1;
Pte->Owner = 1;
Pte->PageFrameNumber = (GetPdeAddress(0xFFC00000))->PageFrameNumber;
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
/* Now loop the first meg of memory */
for (i = 0; i < 0x100000; i += PAGE_SIZE)
{
/* Identity map it */
Pte = GetPteAddress((PVOID)i);
Pte->PageFrameNumber = i >> PAGE_SHIFT;
Pte->Valid = 1;
Pte->Write = 1;
Pte->Owner = 1;
}
/* Now get the entry for our real mode V86 code and the target */
Pte = GetPteAddress(0x20000);
V86Pte = GetPteAddress(&HalpRealModeStart);
do
{
/* Map the physical address into our real-mode region */
Pte->PageFrameNumber = V86Pte->PageFrameNumber;
/* Keep going until we've reached the end of our region */
Pte++;
V86Pte++;
} while (V86Pte <= GetPteAddress(&HalpRealModeEnd));
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
}
VOID
NTAPI
HalpSwitchToRealModeTrapHandlers(VOID)
{
ULONG Handler;
/* Save the current Invalid Opcode and General Protection Fault Handlers */
HalpGpfHandler = ((((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset << 16) &
0xFFFF0000) |
(((PKIPCR)KeGetPcr())->IDT[13].Offset & 0xFFFF);
HalpBopHandler = ((((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset << 16) &
0xFFFF0000) |
(((PKIPCR)KeGetPcr())->IDT[6].Offset & 0xFFFF);
/* Now set our own GPF handler to handle exceptions while in real mode */
Handler = (ULONG_PTR)HalpTrap0D;
((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset =
(USHORT)((Handler >> 16) & 0xFFFF);
((PKIPCR)KeGetPcr())->IDT[13].Offset = (USHORT)Handler;
/* And our own invalid opcode handler to detect the BOP to get us out */
Handler = (ULONG_PTR)HalpTrap06;
((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset =
(USHORT)((Handler >> 16) & 0xFFFF);
((PKIPCR)KeGetPcr())->IDT[6].Offset = (USHORT)Handler;
}
VOID
NTAPI
HalpSetupRealModeIoPermissionsAndTask(VOID)
{
/* Save a copy of the I/O Map and delete it */
HalpSavedIoMap = (PUCHAR)&(KeGetPcr()->TSS->IoMaps[0]);
HalpStoreAndClearIopm(HalpSavedIoMap);
/* Save the IOPM and switch to the real-mode one */
HalpSavedIopmBase = KeGetPcr()->TSS->IoMapBase;
KeGetPcr()->TSS->IoMapBase = KiComputeIopmOffset(1);
/* Save our stack pointer */
HalpSavedEsp0 = KeGetPcr()->TSS->Esp0;
}
VOID
NTAPI
HalpRestoreTrapHandlers(VOID)
{
/* We're back, restore the handlers we over-wrote */
((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset =
(USHORT)((HalpGpfHandler >> 16) & 0xFFFF);
((PKIPCR)KeGetPcr())->IDT[13].Offset = (USHORT)HalpGpfHandler;
((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset =
(USHORT)((HalpBopHandler >> 16) & 0xFFFF);
((PKIPCR)KeGetPcr())->IDT[6].Offset = (USHORT)HalpBopHandler;
}
VOID
NTAPI
HalpRestoreIoPermissionsAndTask(VOID)
{
/* Restore the stack pointer */
KeGetPcr()->TSS->Esp0 = HalpSavedEsp0;
/* Restore the I/O Map */
HalpRestoreIopm(HalpSavedIoMap);
/* Restore the IOPM */
KeGetPcr()->TSS->IoMapBase = HalpSavedIopmBase;
}
VOID
NTAPI
HalpUnmapRealModeMemory(VOID)
{
ULONG i;
PHARDWARE_PTE Pte;
/* Loop the first meg of memory */
for (i = 0; i < 0x100000; i += PAGE_SIZE)
{
/* Invalidate each PTE */
Pte = GetPteAddress((PVOID)i);
Pte->Valid = 0;
Pte->Write = 0;
Pte->PageFrameNumber = 0;
}
/* Restore the PDE for the lowest megabyte of memory */
Pte = GetPdeAddress(0);
*Pte = HalpSavedPte;
Pte->PageFrameNumber = HalpSavedPfn;
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
}
BOOLEAN
NTAPI
HalpBiosDisplayReset(VOID)
{
ULONG Flags = 0;
/* Disable interrupts */
Ke386SaveFlags(Flags);
_disable();
/* Map memory available to the V8086 real-mode code */
HalpMapRealModeMemory();
/* Use special invalid opcode and GPF trap handlers */
HalpSwitchToRealModeTrapHandlers();
/* Configure the IOPM and TSS */
HalpSetupRealModeIoPermissionsAndTask();
/* Now jump to real mode */
HalpBiosCall();
/* Restore kernel trap handlers */
HalpRestoreTrapHandlers();
/* Restore TSS and IOPM */
HalpRestoreIoPermissionsAndTask();
/* Restore low memory mapping */
HalpUnmapRealModeMemory();
/* Restore interrupts if they were previously enabled */
Ke386RestoreFlags(Flags);
return TRUE;
}
/* EOF */

View File

@@ -7,6 +7,7 @@
<define name="_DISABLE_TIDENTS" />
<define name="_NTHAL_" />
<file>beep.c</file>
<file>bios.c</file>
<file>bus.c</file>
<file>cmos.c</file>
<file>dma.c</file>
@@ -20,6 +21,7 @@
<file>sysinfo.c</file>
<file>timer.c</file>
<file>systimer.S</file>
<file>v86.s</file>
<pch>../include/hal.h</pch>
</module>
<module name="hal_generic_up" type="objectlibrary">

View File

@@ -109,6 +109,7 @@ HalInitSystem(IN ULONG BootPhase,
HalInitPnpDriver = NULL; // FIXME: TODO
HalGetDmaAdapter = HalpGetDmaAdapter;
HalGetInterruptTranslator = NULL; // FIXME: TODO
HalResetDisplay = HalpBiosDisplayReset;
/* Initialize the hardware lock (CMOS) */
KeInitializeSpinLock(&HalpSystemHardwareLock);

View File

@@ -0,0 +1,417 @@
/*
* FILE: hal/halx86/generic/bios.S
* COPYRIGHT: See COPYING in the top level directory
* PURPOSE: V8086 Real-Mode BIOS Thunking
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include <asm.h>
#include <internal/i386/asmmacro.S>
.intel_syntax noprefix
//
// HAL BIOS Frame
//
#define HALP_BIOS_FRAME_SS 0x00
#define HALP_BIOS_FRAME_ESP 0x04
#define HALP_BIOS_FRAME_EFLAGS 0x08
#define HALP_BIOS_FRAME_CS 0x0C
#define HALP_BIOS_FRAME_EIP 0x10
#define HALP_BIOS_FRAME_TRAP_FRAME 0x14
#define HALP_BIOS_FRAME_CS_LIMIT 0x18
#define HALP_BIOS_FRAME_CS_BASE 0x1C
#define HALP_BIOS_FRAME_CS_FLAGS 0x20
#define HALP_BIOS_FRAME_SS_LIMIT 0x24
#define HALP_BIOS_FRAME_SS_BASE 0x28
#define HALP_BIOS_FRAME_SS_FLAGS 0x2C
#define HALP_BIOS_FRAME_PREFIX 0x30
#define HALP_BIOS_FRAME_LENGTH 0x34
/* GLOBALS *******************************************************************/
_HalpSavedEsp:
.long 0
_UnhandledMsg:
.asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
/* FUNCTIONS *****************************************************************/
.globl _HalpBiosCall@0
.func HalpBiosCall@0
_HalpBiosCall@0:
/* Set up stack pointer */
push ebp
mov ebp, esp
/* Build a trap frame */
pushfd
push edi
push esi
push ebx
push ds
push es
push fs
push gs
push offset _HalpRealModeEnd
/* Save the stack */
mov _HalpSavedEsp, esp
/* Turn off alignment faults */
mov eax, cr0
and eax, ~CR0_AM
mov cr0, eax
/* Setup a new stack */
mov esi, fs:KPCR_TSS
mov eax, esp
sub eax, NPX_FRAME_LENGTH
mov [esi+KTSS_ESP0], eax
/* Save V86 registers */
push 0
push 0
push 0
push 0
push 0x2000
/* Get linear delta between stack and code */
mov eax, offset _HalpRealModeEnd-4
sub eax, offset _HalpRealModeStart
/* Get offset of code */
mov edx, offset _HalpRealModeStart
and edx, 0xFFF
/* Add offset to linear address and save the new V86 SP */
add eax, edx
push eax
/* Start building interrupt frame. Setup V86 EFLAGS and IOPL 3 */
pushfd
or dword ptr [esp], EFLAGS_V86_MASK
or dword ptr [esp], 0x3000
/* Push the CS and IP */
push 0x2000
push edx
/* Do the interrupt return (jump to V86 mode) */
iretd
.globl _HalpRealModeStart
_HalpRealModeStart:
/* Set mode 13 */
mov ax, 0x12
.byte 0
.byte 0
/* Do the interrupt */
int 0x10
/* BOP to exit V86 mode */
.byte 0xC4
.byte 0xC4
/* The stack lives here */
.align 4
.space 2048
.globl _HalpRealModeEnd
_HalpRealModeEnd:
/* We're back, clean up the trap frame */
pop gs
pop fs
pop es
pop ds
pop ebx
pop esi
pop edi
popfd
/* Return to caller */
pop ebp
ret 0
.endfunc
.globl _HalpOpcodeInvalid@0
.func HalpOpcodeInvalid@0
_HalpOpcodeInvalid@0:
/* Unhandled */
UNHANDLED_PATH
/* Nothing to return */
xor eax, eax
ret 0
.endfunc
.globl _HalpPushInt@0
.func HalpPushInt@0
_HalpPushInt@0:
/* Save EBX */
push ebx
/* Get SS offset and base */
mov edx, [esi+HALP_BIOS_FRAME_ESP]
mov ebx, [esi+HALP_BIOS_FRAME_SS_BASE]
/* Convert to 16-bits */
and edx, 0xFFFF
sub dx, 2
/* Get EFLAGS and write them into the linear address of SP */
mov ax, word ptr [esi+HALP_BIOS_FRAME_EFLAGS]
mov [ebx+edx], ax
sub dx, 2
/* Get CS segment and write it into SP */
mov ax, word ptr [esi+HALP_BIOS_FRAME_CS]
mov [ebx+edx], ax
sub dx, 2
/* Get IP and write it into SP */
mov ax, word ptr [esi+HALP_BIOS_FRAME_EIP]
mov [ebx+edx], ax
/* Get new IP value (the interrupt ID is in ECX, so this is in the IVT) */
mov eax, [ecx*4]
push eax
/* Now save the new IP */
movzx eax, ax
mov [esi+HALP_BIOS_FRAME_EIP], eax
/* Save the new CS of this IP */
pop eax
shr eax, 16
mov [esi+HALP_BIOS_FRAME_CS], eax
/* Update the stack pointer after our manual interrupt frame construction */
mov word ptr [esi+HALP_BIOS_FRAME_ESP], dx
/* Get CS and convert it to linear format */
mov eax, [esi+HALP_BIOS_FRAME_CS]
shl eax, 4
mov [esi+HALP_BIOS_FRAME_CS_BASE], eax
mov dword ptr [esi+HALP_BIOS_FRAME_CS_LIMIT], 0xFFFF
mov dword ptr [esi+HALP_BIOS_FRAME_CS_FLAGS], 0
/* Return success and restore EBX */
mov eax, 1
pop ebx
ret 0
.endfunc
.globl _HalpOpcodeINTnn@0
.func HalpOpcodeINTnn@0
_HalpOpcodeINTnn@0:
/* Save non-volatiles and stack */
push ebp
push esi
push ebx
/* Get SS and convert it to linear format */
mov eax, [esi+HALP_BIOS_FRAME_SS]
shl eax, 4
mov [esi+HALP_BIOS_FRAME_SS_BASE], eax
mov dword ptr [esi+HALP_BIOS_FRAME_SS_LIMIT], 0xFFFF
mov dword ptr [esi+HALP_BIOS_FRAME_SS_FLAGS], 0
/* Increase IP and check if we're past the CS limit */
inc dword ptr [esi+HALP_BIOS_FRAME_EIP]
mov edi, [esi+HALP_BIOS_FRAME_EIP]
cmp edi, [esi+HALP_BIOS_FRAME_CS_LIMIT]
ja EipLimitReached
/* Convert IP to linear address and read the interrupt number */
add edi, [esi+HALP_BIOS_FRAME_CS_BASE]
movzx ecx, byte ptr [edi]
/* Increase EIP and do the interrupt, check for status */
inc dword ptr [esi+HALP_BIOS_FRAME_EIP]
call _HalpPushInt@0
test eax, 0xFFFF
jz Done
/* Update the trap frame */
mov ebp, [esi+HALP_BIOS_FRAME_TRAP_FRAME]
mov eax, [esi+HALP_BIOS_FRAME_SS]
mov [ebp+KTRAP_FRAME_SS], eax
mov eax, [esi+HALP_BIOS_FRAME_ESP]
mov [ebp+KTRAP_FRAME_ESP], eax
mov eax, [esi+HALP_BIOS_FRAME_CS]
mov [ebp+KTRAP_FRAME_CS], eax
mov eax, [esi+HALP_BIOS_FRAME_EFLAGS]
mov [ebp+KTRAP_FRAME_EFLAGS], eax
/* Set success code */
mov eax, 1
Done:
/* Restore volatiles */
pop ebx
pop edi
pop ebp
ret 0
EipLimitReached:
/* Set failure code */
xor eax, eax
jmp Done
.endfunc
.globl _HalpDispatchV86Opcode@0
.func HalpDispatchV86Opcode@0
_HalpDispatchV86Opcode@0:
/* Make space for the HAL BIOS Frame on the stack */
push ebp
mov ebp, esp
sub esp, HALP_BIOS_FRAME_LENGTH
/* Save non-volatiles */
push esi
push edi
/* Save pointer to the trap frame */
mov esi, [ebp]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_TRAP_FRAME], esi
/* Save SS */
movzx eax, word ptr [esi+KTRAP_FRAME_SS]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_SS], eax
/* Save ESP */
mov eax, [esi+KTRAP_FRAME_ESP]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_ESP], eax
/* Save EFLAGS */
mov eax, [esi+KTRAP_FRAME_EFLAGS]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_EFLAGS], eax
/* Save CS */
movzx eax, word ptr [esi+KTRAP_FRAME_CS]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_CS], eax
/* Save EIP */
mov eax, [esi+KTRAP_FRAME_EIP]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_EIP], eax
/* No prefix */
xor eax, eax
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_PREFIX], eax
/* Set pointer to HAL BIOS Frame */
lea esi, [ebp-HALP_BIOS_FRAME_LENGTH]
/* Convert CS to linear format */
mov eax, [esi+HALP_BIOS_FRAME_CS]
shl eax, 4
mov [esi+HALP_BIOS_FRAME_CS_BASE], eax
mov dword ptr [esi+HALP_BIOS_FRAME_CS_LIMIT], 0xFFFF
mov dword ptr [esi+HALP_BIOS_FRAME_CS_FLAGS], 0
/* Make sure IP is within the CS Limit */
mov edi, [esi+HALP_BIOS_FRAME_EIP]
cmp edi, [esi+HALP_BIOS_FRAME_CS_LIMIT]
ja DispatchError
/* Convert IP to linear address and read the opcode */
add edi, [esi+HALP_BIOS_FRAME_CS_BASE]
mov dl, [edi]
/* We only deal with interrupts */
cmp dl, 0xCD
je DispatchInt
/* Anything else is invalid */
call _HalpOpcodeInvalid@0
jmp DispatchError
DispatchInt:
/* Handle dispatching the interrupt */
call _HalpOpcodeINTnn@0
test eax, 0xFFFF
jz DispatchReturn
/* Update the trap frame EIP */
mov edi, [ebp-0x20]
mov eax, [ebp-0x24]
mov [edi+KTRAP_FRAME_EIP], eax
/* Set success code */
mov eax, 1
DispatchReturn:
/* Restore registers and return */
pop edi
pop esi
mov esp, ebp
pop ebp
ret 0
DispatchError:
/* Set failure code and return */
xor eax, eax
jmp DispatchReturn
.endfunc
.func Ki16BitStackException
_Ki16BitStackException:
/* Save stack */
push ss
push esp
/* Go to kernel mode thread stack */
mov eax, PCR[KPCR_CURRENT_THREAD]
add esp, [eax+KTHREAD_INITIAL_STACK]
/* Switch to good stack segment */
UNHANDLED_PATH
.endfunc
.globl _HalpTrap0D@0
.func HalpTrap0D@0
TRAP_FIXUPS htd_a, htd_t, DoFixupV86, DoFixupAbios
_HalpTrap0D@0:
/* Enter trap */
TRAP_PROLOG htd_a, htd_t
/* Check if this is a V86 trap */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz DoDispatch
/* Unhandled */
UNHANDLED_PATH
DoDispatch:
/* Handle the opcode */
call _HalpDispatchV86Opcode@0
/* Exit the interrupt */
jmp _Kei386EoiHelper@0
.endfunc
.globl _HalpTrap06@0
.func HalpTrap06@0
_HalpTrap06@0:
/* Restore DS/ES segments */
mov eax, KGDT_R3_DATA | RPL_MASK
mov ds, ax
mov es, ax
/* Restore ESP and return */
mov esp, _HalpSavedEsp
ret 0
.endfunc

View File

@@ -115,6 +115,48 @@ HaliSetSystemInformation(
IN OUT PVOID Buffer
);
//
// BIOS Routines
//
BOOLEAN
NTAPI
HalpBiosDisplayReset(
VOID
);
ULONG
NTAPI
HalpBorrowTss(
VOID
);
ULONG
NTAPI
HalpReturnTss(
ULONG SavedTss
);
VOID
NTAPI
HalpBiosCall(
VOID
);
VOID
NTAPI
HalpTrap0D(
VOID
);
VOID
NTAPI
HalpTrap06(
VOID
);
extern PVOID HalpRealModeStart;
extern PVOID HalpRealModeEnd;
extern KSPIN_LOCK HalpSystemHardwareLock;
#endif /* __INTERNAL_HAL_HAL_H */

View File

@@ -108,6 +108,16 @@ Author:
//
#define INITIAL_STALL_COUNT 0x64
//
// IOPM Definitions
//
#define IO_ACCESS_MAP_NONE 0
#define IOPM_OFFSET FIELD_OFFSET(KTSS, IoMaps[0].IoMap)
#define KiComputeIopmOffset(MapNumber) \
(MapNumber == IO_ACCESS_MAP_NONE) ? \
(USHORT)(sizeof(KTSS)) : \
(USHORT)(FIELD_OFFSET(KTSS, IoMaps[MapNumber-1].IoMap))
//
// Static Kernel-Mode Address start (use MM_KSEG0_BASE for actual)
//

View File

@@ -48,7 +48,6 @@ VOID STDCALL
ShutdownThreadMain(PVOID Context)
{
SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context;
LARGE_INTEGER Waittime;
static PCH FamousLastWords[] =
{
@@ -167,16 +166,13 @@ ShutdownThreadMain(PVOID Context)
}
PspShutdownProcessManager();
Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */
KeDelayExecutionThread(KernelMode, FALSE, &Waittime);
CmShutdownSystem();
IoShutdownRegisteredFileSystems();
IoShutdownRegisteredDevices();
MiShutdownMemoryManager();
if (Action == ShutdownNoReboot)
{
HalDisplayString("\nYou can switch off your computer now\n");

View File

@@ -111,6 +111,7 @@ InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
PCHAR CommandLine;
BOOLEAN CustomLogo = FALSE;
ULONG i;
extern BOOLEAN ExpInTextModeSetup;
/* Quit if we're already installed */
if (InbvBootDriverInstalled) return TRUE;
@@ -124,6 +125,9 @@ InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
CustomLogo = strstr(CommandLine, "BOOTLOGO") ? TRUE: FALSE;
}
/* For SetupLDR, don't reset the BIOS Display -- FIXME! */
if (ExpInTextModeSetup) CustomLogo = TRUE;
/* Initialize the video */
InbvBootDriverInstalled = VidInitialize(!CustomLogo);
if (InbvBootDriverInstalled)