[BOOTLIB]: Begin adding support for transferring to newly loaded i386 image.

svn path=/trunk/; revision=73687
This commit is contained in:
Alex Ionescu 2017-02-04 21:59:52 +00:00
parent 6ee138b21a
commit 28dad177a0
4 changed files with 192 additions and 4 deletions

View file

@ -45,7 +45,7 @@ list(APPEND BOOTLIB_SOURCE
if(ARCH STREQUAL "i386")
list(APPEND BOOTLIB_ASM_SOURCE
#lib/arch/i386/foo.asm
lib/arch/i386/transfer.s
)
list(APPEND BOOTLIB_SOURCE
lib/arch/i386/arch.c

View file

@ -283,6 +283,7 @@ typedef enum _BL_MEMORY_TYPE
BlLoaderPageDirectory = 0xD0000006,
BlLoaderReferencePage = 0xD0000007,
BlLoaderRamDisk = 0xD0000008,
BlLoaderArchData = 0xD0000009,
BlLoaderData = 0xD000000A,
BlLoaderRegistry = 0xD000000B,
BlLoaderBlockMemory = 0xD000000C,
@ -1180,6 +1181,13 @@ typedef struct _BL_IMAGE_APPLICATION_ENTRY
ULONG ImageSize;
} BL_IMAGE_APPLICATION_ENTRY, *PBL_IMAGE_APPLICATION_ENTRY;
typedef struct _BL_IMAGE_PARAMETERS
{
PVOID Buffer;
ULONG ActualSize;
ULONG BufferSize;
} BL_IMAGE_PARAMETERS, *PBL_IMAGE_PARAMETERS;
typedef struct _BL_DEFERRED_FONT_FILE
{
LIST_ENTRY ListEntry;
@ -1937,6 +1945,11 @@ BlpArchSwitchContext (
_In_ BL_ARCH_MODE NewMode
);
VOID
Archx86TransferTo32BitApplicationAsm (
VOID
);
/* MEMORY DESCRIPTOR ROUTINES ************************************************/
VOID

View file

@ -0,0 +1,81 @@
/*
* COPYRIGHT: See COPYING.ARM in the top level directory
* PROJECT: ReactOS UEFI Boot Library
* FILE: boot/environ/lib/arch/transfer.asm
* PURPOSE: Boot Library i386 Transfer Functions
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <asm.inc>
#include <ks386.inc>
EXTERN _GdtRegister:DWORD
EXTERN _IdtRegister:DWORD
EXTERN _BootAppGdtRegister:DWORD
EXTERN _BootAppIdtRegister:DWORD
EXTERN _BootApp32Stack:DWORD
EXTERN _BootApp32EntryRoutine:DWORD
EXTERN _BootApp32Parameters:DWORD
/* FUNCTIONS ****************************************************************/
.code
PUBLIC _Archx86TransferTo32BitApplicationAsm
_Archx86TransferTo32BitApplicationAsm:
/* Save non-volatile registers */
push ebp
push esi
push edi
push ebx
/* Save data segments */
push es
push ds
/* Save the old stack */
mov ebx, esp
/* Save current GDT/IDT, then load new one */
sgdt fword ptr _GdtRegister
sidt fword ptr _IdtRegister
lgdt fword ptr _BootAppGdtRegister
lidt fword ptr _BootAppIdtRegister
/* Load the new stack */
xor ebp, ebp
mov esp, _BootApp32Stack
/* Push old stack onto new stack */
push ebx
/* Call the entry routine, passing the parameters */
mov eax, _BootApp32Parameters
push eax
mov eax, _BootApp32EntryRoutine
call eax
/* Retore old stack */
pop ebx
mov esp, ebx
/* Restore old GDT/IDT */
lgdt fword ptr _GdtRegister
lidt fword ptr _IdtRegister
/* Retore old segments */
pop ds
pop es
/* Retore non-volatiles */
pop ebx
pop edi
pop esi
pop ebp
/* All done */
retn
END

View file

@ -17,6 +17,14 @@ ULONG IapAllocatedTableEntries;
ULONG IapTableEntries;
PVOID* IapImageTable;
KDESCRIPTOR GdtRegister;
KDESCRIPTOR IdtRegister;
KDESCRIPTOR BootAppGdtRegister;
KDESCRIPTOR BootAppIdtRegister;
PVOID BootApp32EntryRoutine;
PVOID BootApp32Parameters;
PVOID BootApp32Stack;
/* FUNCTIONS *****************************************************************/
NTSTATUS
@ -1596,6 +1604,17 @@ BlpPdParseReturnArguments (
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ImgpInitializeBootApplicationParameters (
_In_ PBL_IMAGE_PARAMETERS ImageParameters,
_In_ PBL_APPLICATION_ENTRY AppEntry,
_In_ PVOID ImageBase,
_In_ ULONG ImageSize
)
{
return STATUS_SUCCESS;
}
NTSTATUS
ImgArchEfiStartBootApplication (
_In_ PBL_APPLICATION_ENTRY AppEntry,
@ -1604,9 +1623,84 @@ ImgArchEfiStartBootApplication (
_In_ PBL_RETURN_ARGUMENTS ReturnArguments
)
{
/* Not yet implemented. This is the last step! */
EfiPrintf(L"EFI APPLICATION START!!!\r\n");
EfiStall(100000000);
KDESCRIPTOR Gdt, Idt;
ULONG BootSizeNeeded;
NTSTATUS Status;
PVOID BootData;
PIMAGE_NT_HEADERS NtHeaders;
PVOID NewStack, NewGdt, NewIdt;
BL_IMAGE_PARAMETERS Parameters;
/* Read the current IDT and GDT */
_sgdt(&Gdt.Limit);
__sidt(&Idt.Limit);
/* Allocate space for the IDT, GDT, and 24 pages of stack */
BootSizeNeeded = (ULONG)PAGE_ALIGN(Idt.Limit + Gdt.Limit + 1 + 25 * PAGE_SIZE);
Status = MmPapAllocatePagesInRange(&BootData,
BlLoaderArchData,
BootSizeNeeded >> PAGE_SHIFT,
0,
0,
NULL,
0);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
RtlZeroMemory(BootData, BootSizeNeeded);
NewStack = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE) - 8);
NewGdt = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE));
NewIdt = (PVOID)((ULONG_PTR)BootData + (24 * PAGE_SIZE) + Gdt.Limit + 1);
RtlCopyMemory(NewGdt, (PVOID)Gdt.Base, Gdt.Limit + 1);
RtlCopyMemory(NewIdt, (PVOID)Idt.Base, Idt.Limit + 1);
RtlImageNtHeaderEx(0, ImageBase, ImageSize, &NtHeaders);
RtlZeroMemory(&Parameters, sizeof(Parameters));
Status = ImgpInitializeBootApplicationParameters(&Parameters,
AppEntry,
ImageBase,
ImageSize);
if (NT_SUCCESS(Status))
{
BootAppGdtRegister = Gdt;
BootAppIdtRegister = Idt;
BootApp32EntryRoutine = (PVOID)((ULONG_PTR)ImageBase +
NtHeaders->OptionalHeader.
AddressOfEntryPoint);
BootApp32Parameters = Parameters.Buffer;
BootApp32Stack = NewStack;
#if BL_KD_SUPPORT
BlBdStop();
#endif
/* Not yet implemented. This is the last step! */
EfiPrintf(L"EFI APPLICATION START!!!\r\n");
EfiStall(100000000);
/* Make it so */
Archx86TransferTo32BitApplicationAsm();
/* Not yet implemented. This is the last step! */
EfiPrintf(L"EFI APPLICATION RETURNED!!!\r\n");
EfiStall(100000000);
#if BL_KD_SUPPORT
BlBdStart();
#endif
}
Quickie:
if (BootData)
{
//MmPapFreePages(bootData, TRUE);
}
return STATUS_NOT_IMPLEMENTED;
}