- Fix some bugs in intrin.h (missing __inline__ statments in some locations, which were causing warnings due to "static").

- Remove intrinsics in winddk.h since they're now properly done in intrin.h (thanks KJK!!!)
- Make freeldr.c setup the boot KTSS like NTLDR does, so that the GDT entry for it is valid (and remove the code that was doing this from Ki386InitializeTss)
- Refactor KiSystemStartup to use 100% dynamic pointers and machine data queried from the Loader Block or actual GDT/IDT/Selectors in memory, isntead of hard-coded ntoskrnl offsets. This makes it possible to be loaded by NTLDR, which sets these system structures up by itself. (we do it in freeldr.c, as hacks).

svn path=/trunk/; revision=24306
This commit is contained in:
Alex Ionescu 2006-09-30 05:42:22 +00:00
parent 8b1ba6c11a
commit eb0f964be3
7 changed files with 126 additions and 64 deletions

View file

@ -10568,30 +10568,6 @@ extern BOOLEAN KdDebuggerEnabled;
#endif #endif
#ifdef __GNUC__
/* Available as intrinsics on MSVC */
static __inline void _disable(void) {__asm__ __volatile__("cli\n");}
static __inline void _enable(void) {__asm__ __volatile__("sti\n");}
static __inline ULONG64 __readcr3(void)
{
ULONG_PTR Ret;
__asm__ __volatile__("movl %%cr3, %0;\n"
:"=r"(Ret));
return (ULONG64)Ret;
}
static __inline ULONG64 __readcr4(void)
{
ULONG_PTR Ret;
__asm__ __volatile__("movl %%cr4, %0; \n"
:"=r"(Ret));
return (ULONG64)Ret;
}
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -609,20 +609,20 @@ static __inline__ __attribute__((always_inline)) void __addfsdword(const unsigne
/*** Bit manipulation ***/ /*** Bit manipulation ***/
static __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask) static __inline__ __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)
{ {
__asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); __asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
return Mask ? 1 : 0; return Mask ? 1 : 0;
} }
static __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask) static __inline__ __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)
{ {
__asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); __asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
return Mask ? 1 : 0; return Mask ? 1 : 0;
} }
/* NOTE: again, the bizarre implementation follows Visual C++ */ /* NOTE: again, the bizarre implementation follows Visual C++ */
static __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b) static __inline__ __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b)
{ {
unsigned char retval; unsigned char retval;

View file

@ -56,9 +56,14 @@ VOID
KiInitializeGdt(struct _KPCR* Pcr); KiInitializeGdt(struct _KPCR* Pcr);
VOID VOID
Ki386ApplicationProcessorInitializeTSS(VOID); Ki386ApplicationProcessorInitializeTSS(VOID);
VOID VOID
NTAPI FASTCALL
Ki386InitializeTss(VOID); Ki386InitializeTss(
IN PKTSS Tss,
IN PKIDTENTRY Idt
);
VOID VOID
KiGdtPrepareForApplicationProcessorInit(ULONG Id); KiGdtPrepareForApplicationProcessorInit(ULONG Id);
VOID VOID
@ -203,6 +208,7 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
#define Ke386GetCr4() _Ke386GetCr(4) #define Ke386GetCr4() _Ke386GetCr(4)
#define Ke386SetCr4(X) _Ke386SetCr(4,X) #define Ke386SetCr4(X) _Ke386SetCr(4,X)
#define Ke386GetSs() _Ke386GetSeg(ss) #define Ke386GetSs() _Ke386GetSeg(ss)
#define Ke386GetFs() _Ke386GetSeg(fs)
#define Ke386SetFs(X) _Ke386SetSeg(fs, X) #define Ke386SetFs(X) _Ke386SetSeg(fs, X)
#define Ke386SetDs(X) _Ke386SetSeg(ds, X) #define Ke386SetDs(X) _Ke386SetSeg(ds, X)
#define Ke386SetEs(X) _Ke386SetSeg(es, X) #define Ke386SetEs(X) _Ke386SetSeg(es, X)

View file

@ -807,6 +807,13 @@ KeI386VdmInitialize(
VOID VOID
); );
VOID
NTAPI
KiInitializeMachineType(
VOID
);
VOID VOID
NTAPI NTAPI
KiFlushNPXState( KiFlushNPXState(

View file

@ -87,11 +87,23 @@ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
PIMAGE_OPTIONAL_HEADER OptHead; PIMAGE_OPTIONAL_HEADER OptHead;
PLOADER_PARAMETER_BLOCK NtLoaderBlock; PLOADER_PARAMETER_BLOCK NtLoaderBlock;
CHAR* s; CHAR* s;
PKTSS Tss;
PKGDTENTRY TssEntry;
/* Load the GDT and IDT */ /* Load the GDT and IDT */
Ke386SetGlobalDescriptorTable(KiGdtDescriptor); Ke386SetGlobalDescriptorTable(KiGdtDescriptor);
Ke386SetInterruptDescriptorTable(KiIdtDescriptor); Ke386SetInterruptDescriptorTable(KiIdtDescriptor);
/* Initialize the boot TSS */
Tss = &KiBootTss;
TssEntry = &KiBootGdt[KGDT_TSS / sizeof(KGDTENTRY)];
TssEntry->HighWord.Bits.Type = I386_TSS;
TssEntry->HighWord.Bits.Pres = 1;
TssEntry->HighWord.Bits.Dpl = 0;
TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
/* Copy the Loader Block Data locally since Low-Memory will be wiped */ /* Copy the Loader Block Data locally since Low-Memory will be wiped */
memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK)); memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK));
memcpy(&KeLoaderModules[1], memcpy(&KeLoaderModules[1],

View file

@ -61,6 +61,7 @@ ULONG KeI386NpxPresent = 0;
ULONG MxcsrFeatureMask = 0; ULONG MxcsrFeatureMask = 0;
ULONG KeI386XMMIPresent = 0; ULONG KeI386XMMIPresent = 0;
ULONG KeI386FxsrPresent = 0; ULONG KeI386FxsrPresent = 0;
ULONG KeI386MachineType;
ULONG Ke386Pae = FALSE; ULONG Ke386Pae = FALSE;
ULONG Ke386GlobalPagesEnabled = FALSE; ULONG Ke386GlobalPagesEnabled = FALSE;
ULONG Ke386NoExecute = FALSE; ULONG Ke386NoExecute = FALSE;
@ -549,33 +550,24 @@ KiInitializeTSS(IN PKTSS Tss)
} }
VOID VOID
NTAPI FASTCALL
Ki386InitializeTss(VOID) Ki386InitializeTss(IN PKTSS Tss,
IN PKIDTENTRY Idt)
{ {
PKTSS Tss;
PKGDTENTRY TssEntry; PKGDTENTRY TssEntry;
PKIDTENTRY TaskGateEntry; PKIDTENTRY TaskGateEntry;
PKIDT_ACCESS TaskGateAccess; PKIDT_ACCESS TaskGateAccess;
/* Initialize the boot TSS. */ /* Initialize the boot TSS. */
Tss = &KiBootTss;
TssEntry = &KiBootGdt[KGDT_TSS / sizeof(KGDTENTRY)]; TssEntry = &KiBootGdt[KGDT_TSS / sizeof(KGDTENTRY)];
KiInitializeTSS2(Tss, TssEntry); KiInitializeTSS2(Tss, TssEntry);
KiInitializeTSS(Tss); KiInitializeTSS(Tss);
/* Initialize a descriptor for the TSS */
TssEntry->HighWord.Bits.Type = I386_TSS;
TssEntry->HighWord.Bits.Pres = 1;
TssEntry->HighWord.Bits.Dpl = 0;
TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
/* Load the task register */ /* Load the task register */
Ke386SetTr(KGDT_TSS); Ke386SetTr(KGDT_TSS);
/* Setup the Task Gate for Double Fault Traps */ /* Setup the Task Gate for Double Fault Traps */
TaskGateEntry = &KiIdt[8]; TaskGateEntry = &Idt[8];
TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access; TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access;
#if 0 #if 0
TaskGateAccess->SegmentType = I386_TASK_GATE; TaskGateAccess->SegmentType = I386_TASK_GATE;
@ -607,7 +599,7 @@ Ki386InitializeTss(VOID)
TssEntry->LimitLow = KTSS_IO_MAPS; TssEntry->LimitLow = KTSS_IO_MAPS;
/* Now setup the NMI Task Gate */ /* Now setup the NMI Task Gate */
TaskGateEntry = &KiIdt[2]; TaskGateEntry = &Idt[2];
TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access; TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access;
#if 0 #if 0
TaskGateAccess->SegmentType = I386_TASK_GATE; TaskGateAccess->SegmentType = I386_TASK_GATE;
@ -763,6 +755,14 @@ KiSaveProcessorControlState(IN PKPROCESSOR_STATE ProcessorState)
Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr); Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
} }
VOID
NTAPI
KiInitializeMachineType(VOID)
{
/* Set the Machine Type we got from NTLDR */
KeI386MachineType = KeLoaderBlock->u.I386.MachineType & 0x000FF;
}
/* PUBLIC FUNCTIONS **********************************************************/ /* PUBLIC FUNCTIONS **********************************************************/
/* /*

View file

@ -11,6 +11,7 @@
#include <ntoskrnl.h> #include <ntoskrnl.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include <intrin.h>
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
@ -227,13 +228,58 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
KeSetPriorityThread(InitThread, 0); KeSetPriorityThread(InitThread, 0);
} }
VOID
NTAPI
KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
IN PKIDTENTRY *Idt,
IN PKIPCR *Pcr,
IN PKTSS *Tss)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
KGDTENTRY TssSelector, PcrSelector;
ULONG Tr, Fs;
/* Get GDT and IDT descriptors */
Ke386GetGlobalDescriptorTable(GdtDescriptor);
Ke386GetInterruptDescriptorTable(IdtDescriptor);
/* Save IDT and GDT */
*Gdt = (PKGDTENTRY)GdtDescriptor.Base;
*Idt = (PKIDTENTRY)IdtDescriptor.Base;
/* Get TSS and FS Selectors */
Ke386GetTr(&Tr);
if (Tr != KGDT_TSS) Tr = KGDT_TSS; // FIXME: HACKHACK
Fs = Ke386GetFs();
/* Get PCR Selector, mask it and get its GDT Entry */
PcrSelector = *(PKGDTENTRY)((ULONG_PTR)*Gdt + (Fs & ~RPL_MASK));
/* Get the KPCR itself */
*Pcr = (PKIPCR)(ULONG_PTR)(PcrSelector.BaseLow |
PcrSelector.HighWord.Bytes.BaseMid << 16 |
PcrSelector.HighWord.Bytes.BaseHi << 24);
/* Get TSS Selector, mask it and get its GDT Entry */
TssSelector = *(PKGDTENTRY)((ULONG_PTR)*Gdt + (Tr & ~RPL_MASK));
/* Get the KTSS itself */
*Tss = (PKTSS)(ULONG_PTR)(TssSelector.BaseLow |
TssSelector.HighWord.Bytes.BaseMid << 16 |
TssSelector.HighWord.Bytes.BaseHi << 24);
}
VOID VOID
NTAPI NTAPI
KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
ULONG Cpu; ULONG Cpu;
PKIPCR Pcr = (PKIPCR)KPCR_BASE; PKTHREAD InitialThread;
PKPRCB Prcb; PVOID InitialStack;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
PKIPCR Pcr;
/* Save the loader block and get the current CPU */ /* Save the loader block and get the current CPU */
KeLoaderBlock = LoaderBlock; KeLoaderBlock = LoaderBlock;
@ -243,30 +289,47 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
/* If this is the boot CPU, set FS and the CPU Number*/ /* If this is the boot CPU, set FS and the CPU Number*/
Ke386SetFs(KGDT_R0_PCR); Ke386SetFs(KGDT_R0_PCR);
KeGetPcr()->Number = Cpu; KeGetPcr()->Number = Cpu;
/* Set the initial stack and idle thread as well */
LoaderBlock->KernelStack = (ULONG_PTR)P0BootStack;
LoaderBlock->Thread = (ULONG_PTR)&KiInitialThread;
} }
/* Save the initial thread and stack */
InitialStack = (PVOID)LoaderBlock->KernelStack;
InitialThread = (PKTHREAD)LoaderBlock->Thread;
/* Clean the APC List Head */
InitializeListHead(&InitialThread->ApcState.ApcListHead[KernelMode]);
/* Initialize the machine type */
KiInitializeMachineType();
/* Skip initial setup if this isn't the Boot CPU */ /* Skip initial setup if this isn't the Boot CPU */
if (Cpu) goto AppCpuInit; if (Cpu) goto AppCpuInit;
/* Setup the boot (Freeldr should've done), double fault and NMI TSS */ /* Get GDT, IDT, PCR and TSS pointers */
Ki386InitializeTss(); KiGetMachineBootPointers(&Gdt, &Idt, &Pcr, &Tss);
/* Setup the TSS descriptors and entries */
Ki386InitializeTss(Tss, Idt);
/* Initialize the PCR */ /* Initialize the PCR */
RtlZeroMemory(Pcr, PAGE_SIZE); RtlZeroMemory(Pcr, PAGE_SIZE);
KiInitializePcr(Cpu, KiInitializePcr(Cpu,
Pcr, Pcr,
KiIdt, Idt,
KiBootGdt, Gdt,
&KiBootTss, Tss,
&KiInitialThread.Tcb, InitialThread,
KiDoubleFaultStack); KiDoubleFaultStack);
/* Set us as the current process */ /* Set us as the current process */
KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb; InitialThread->ApcState.Process = &KiInitialProcess.Pcb;
/* Clear DR6/7 to cleanup bootloader debugging */ /* Clear DR6/7 to cleanup bootloader debugging */
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0; __writefsdword(KPCR_DR6, 0);
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0; __writefsdword(KPCR_DR7, 0);
/* Load Ring 3 selectors for DS/ES */ /* Load Ring 3 selectors for DS/ES */
Ke386SetDs(KGDT_R3_DATA | RPL_MASK); Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
@ -274,11 +337,10 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
/* Setup CPU-related fields */ /* Setup CPU-related fields */
AppCpuInit: AppCpuInit:
Prcb = Pcr->Prcb; __writefsdword(KPCR_NUMBER, Cpu);
Pcr->Number = Cpu; __writefsdword(KPCR_SET_MEMBER, 1 << Cpu);
Pcr->SetMember = 1 << Cpu; __writefsdword(KPCR_SET_MEMBER_COPY, 1 << Cpu);
Pcr->SetMemberCopy = 1 << Cpu; __writefsdword(KPCR_PRCB_SET_MEMBER, 1 << Cpu);
Prcb->SetMember = 1 << Cpu;
/* Initialize the Processor with HAL */ /* Initialize the Processor with HAL */
HalInitializeProcessor(Cpu, KeLoaderBlock); HalInitializeProcessor(Cpu, KeLoaderBlock);
@ -296,11 +358,11 @@ AppCpuInit:
/* Raise to HIGH_LEVEL */ /* Raise to HIGH_LEVEL */
KfRaiseIrql(HIGH_LEVEL); KfRaiseIrql(HIGH_LEVEL);
/* Call main kernel intialization */ /* Call main kernel initialization */
KiInitializeKernel(&KiInitialProcess.Pcb, KiInitializeKernel(&KiInitialProcess.Pcb,
&KiInitialThread.Tcb, InitialThread,
P0BootStack, InitialStack,
Prcb, &Pcr->PrcbData, //(PKPRCB)__readfsdword(KPCR_PRCB),
Cpu, Cpu,
LoaderBlock); LoaderBlock);
@ -314,4 +376,3 @@ AppCpuInit:
KiIdleLoop(); KiIdleLoop();
} }