diff --git a/reactos/ntoskrnl/ke/i386/init.S b/reactos/ntoskrnl/ke/i386/init.S new file mode 100644 index 00000000000..2d84d07f050 --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/init.S @@ -0,0 +1,39 @@ +/* + * FILE: ntoskrnl/ke/i386/init.S + * COPYRIGHT: See COPYING in the top level directory + * PURPOSE: Kernel Initialization + * PROGRAMMER: Thomas Weidenmueller + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +.intel_syntax noprefix + +/* FUNCTIONS ******************************************************************/ + +.text +.globl _KiSetupStackAndInitializeKernel@24 +.func KiSetupStackAndInitializeKernel@24 +_KiSetupStackAndInitializeKernel@24: + + mov esi, esp + + /* Setup the new stack */ + mov esp, [esp + 12] + sub esp, NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH + push CR0_EM + CR0_TS + CR0_MP + + /* Copy all parameters to the new stack */ + push [esi + 24] + push [esi + 20] + push [esi + 16] + push [esi + 12] + push [esi + 8] + push [esi + 4] + xor ebp, ebp + call _KiInitializeKernel@24 + + jmp _KiSystemStartupFinal@0 +.endfunc diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index bff40a36a88..ef1b1b409e7 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -12,6 +12,16 @@ #define NDEBUG #include + +VOID +NTAPI +KiSetupStackAndInitializeKernel(IN PKPROCESS InitProcess, + IN PKTHREAD InitThread, + IN PVOID IdleStack, + IN PKPRCB Prcb, + IN CCHAR Number, + IN PLOADER_PARAMETER_BLOCK LoaderBlock); + /* GLOBALS *******************************************************************/ /* Spinlocks used only on X86 */ @@ -752,28 +762,32 @@ AppCpuInit: KfRaiseIrql(HIGH_LEVEL); /* Align stack and make space for the trap frame and NPX frame */ - InitialStack &= -KTRAP_FRAME_ALIGN; -#ifdef __GNUC__ - __asm__ __volatile__("xorl %ebp, %ebp"); - __asm__ __volatile__("movl %0,%%esp" : :"r" (InitialStack)); - __asm__ __volatile__("subl %0,%%esp" : :"r" (NPX_FRAME_LENGTH + - KTRAP_FRAME_LENGTH + - KTRAP_FRAME_ALIGN)); - __asm__ __volatile__("push %0" : :"r" (CR0_EM + CR0_TS + CR0_MP)); -#else - __asm xor ebp, ebp; - __asm mov esp, InitialStack; - __asm sub esp, NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH; - __asm push CR0_EM + CR0_TS + CR0_MP; -#endif + InitialStack &= ~(KTRAP_FRAME_ALIGN - 1); - /* Call main kernel initialization */ - KiInitializeKernel(&KiInitialProcess.Pcb, - InitialThread, - (PVOID)InitialStack, - (PKPRCB)__readfsdword(KPCR_PRCB), - (CCHAR)Cpu, - KeLoaderBlock); + /* NOTE: We cannot setup the stack using inline assembly and then later assume + that the compiler is smart enough to figure out how the stack layout + changed! This is to avoid generating wrong code. We cannot directly + call KiInitializeKernel from here! */ + + KiSetupStackAndInitializeKernel(&KiInitialProcess.Pcb, + InitialThread, + (PVOID)InitialStack, + (PKPRCB)__readfsdword(KPCR_PRCB), + (CCHAR)Cpu, + KeLoaderBlock); + + /* NOTE: KiSetupStackAndInitializeKernel never returns! Do NOT add any code here! */ + ASSERT(FALSE); +} + +VOID +NTAPI +KiSystemStartupFinal(VOID) +{ + /* NOTE: This routine is called after setting up the stack in KiSystemStartup! + This code cannot be moved to KiSystemStartup because it cannot be assumed + that the compiler can generate working code after modifying ESP/EBP + using inline assembly! */ /* Set the priority of this thread to 0 */ KeGetCurrentThread()->Priority = 0; diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index d31e7bf3932..90acbe823a8 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -36,6 +36,7 @@ cpu.c ctxswitch.S exp.c + init.S irqobj.c kiinit.c ldt.c