#elif defined (DEBUG_REACTOS)
ULONG DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY;
#elif defined (DEBUG_CUSTOM)
-ULONG DebugPrintMask = DPRINT_WARNING|DPRINT_FILESYSTEM|DPRINT_MEMORY|DPRINT_LINUX;
+ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY |
+ DPRINT_REACTOS | DPRINT_WINDOWS | DPRINT_HWDETECT;
#else //#elif defined (DEBUG_NONE)
ULONG DebugPrintMask = 0;
#endif
DebugPrintChar(':');
DebugPrintChar(' ');
break;
+ case DPRINT_WINDOWS:
+ DebugPrintChar('W');
+ DebugPrintChar('I');
+ DebugPrintChar('N');
+ DebugPrintChar('L');
+ DebugPrintChar('D');
+ DebugPrintChar('R');
+ DebugPrintChar(':');
+ DebugPrintChar(' ');
+ break;
case DPRINT_HWDETECT:
DebugPrintChar('H');
DebugPrintChar('W');
<define name="DEBUG" />
-->
<define name="_NTHAL_" />
+ <define name="_NTSYSTEM_" />
<compilerflag>-ffreestanding</compilerflag>
<compilerflag>-fno-builtin</compilerflag>
<compilerflag>-fno-inline</compilerflag>
<file>video.c</file>
</directory>
<directory name="windows">
+ <file>conversion.c</file>
+ <file>peloader.c</file>
<file>winldr.c</file>
+ <file>wlmemory.c</file>
</directory>
<file>freeldr.c</file>
<file>debug.c</file>
#define DPRINT_REACTOS 0x00000100 // OR this with DebugPrintMask to enable ReactOS messages
#define DPRINT_LINUX 0x00000200 // OR this with DebugPrintMask to enable Linux messages
#define DPRINT_HWDETECT 0x00000400 // OR this with DebugPrintMask to enable hardware detection messages
+ #define DPRINT_WINDOWS 0x00000800 // OR this with DebugPrintMask to enable messages from Windows loader
VOID DebugInit(VOID);
VOID DebugPrint(ULONG Mask, char *format, ...);
///////////////////////////////////////////////////////////////////////////////////////\r
VOID LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion);\r
\r
+/* Entry-point to kernel */\r
+typedef\r
+VOID\r
+NTAPI\r
+(*KERNEL_ENTRY_POINT) (PLOADER_PARAMETER_BLOCK LoaderBlock);\r
+\r
+\r
+// Some definitions\r
+#define SECTOR_SIZE 512\r
+\r
+// Descriptors\r
+#define NUM_GDT 28 //15. The kernel wants 0xD8 as a last GDT entry offset\r
+#define NUM_IDT 0x100 // only 16 are used though\r
+\r
+// conversion.c\r
+PVOID VaToPa(PVOID Va);\r
+PVOID PaToVa(PVOID Pa);\r
+VOID List_PaToVa(LIST_ENTRY *ListEntry);\r
+VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start);\r
+\r
+// peloader.c\r
+BOOLEAN\r
+WinLdrLoadImage(IN PCHAR FileName,\r
+ OUT PVOID *ImageBasePA);\r
+\r
+\r
+BOOLEAN\r
+WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,\r
+ IN PCCH BaseDllName,\r
+ IN PCCH FullDllName,\r
+ IN PVOID BasePA,\r
+ OUT PLDR_DATA_TABLE_ENTRY *NewEntry);\r
+\r
+BOOLEAN\r
+WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,\r
+ IN PCCH DirectoryPath,\r
+ IN PLDR_DATA_TABLE_ENTRY ScanDTE);\r
+\r
+// wlmemory.c\r
+BOOLEAN\r
+WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,\r
+ ULONG PcrBasePage,\r
+ ULONG TssBasePage,\r
+ PVOID GdtIdt);\r
\r
#endif // defined __WINLDR_H\r
--- /dev/null
+/*\r
+ * PROJECT: EFI Windows Loader\r
+ * LICENSE: GPL - See COPYING in the top level directory\r
+ * FILE: freeldr/winldr/conversion.c\r
+ * PURPOSE: Physical <-> Virtual addressing mode conversions\r
+ * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ***************************************************************/\r
+\r
+#include <freeldr.h>\r
+\r
+//#include <ndk/ldrtypes.h>\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* FUNCTIONS **************************************************************/\r
+\r
+/* Arch-specific addresses translation implementation */\r
+PVOID\r
+VaToPa(PVOID Va)\r
+{\r
+ return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE);\r
+}\r
+\r
+PVOID\r
+PaToVa(PVOID Pa)\r
+{\r
+ return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE);\r
+}\r
+\r
+VOID\r
+List_PaToVa(LIST_ENTRY *ListEntry)\r
+{\r
+ LIST_ENTRY *ListHead = ListEntry;\r
+ LIST_ENTRY *Next = ListEntry->Flink;\r
+ LIST_ENTRY *NextPA;\r
+\r
+ //Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next);\r
+ //\r
+ // Walk through the whole list\r
+ //\r
+ if (Next != NULL)\r
+ {\r
+ while (Next != PaToVa(ListHead))\r
+ {\r
+ NextPA = VaToPa(Next);\r
+ //Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink);\r
+\r
+ NextPA->Flink = PaToVa((PVOID)NextPA->Flink);\r
+ NextPA->Blink = PaToVa((PVOID)NextPA->Blink);\r
+\r
+ //Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink);\r
+\r
+ Next = NextPA->Flink;\r
+ }\r
+\r
+ //\r
+ // Finally convert first Flink/Blink\r
+ //\r
+ ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink);\r
+ if (ListEntry->Blink)\r
+ ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink);\r
+ }\r
+}\r
+\r
+// This function converts only Child->Child, and calls itself for each Sibling\r
+VOID\r
+ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)\r
+{\r
+ PCONFIGURATION_COMPONENT_DATA Child;\r
+ PCONFIGURATION_COMPONENT_DATA Sibling;\r
+\r
+ DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start));\r
+ Child = Start;\r
+\r
+ while (Child != NULL)\r
+ {\r
+ if (Child->ConfigurationData)\r
+ Child->ConfigurationData = PaToVa(Child->ConfigurationData);\r
+\r
+ if (Child->Child)\r
+ Child->Child = PaToVa(Child->Child);\r
+\r
+ if (Child->Parent)\r
+ Child->Parent = PaToVa(Child->Parent);\r
+\r
+ if (Child->Sibling)\r
+ Child->Sibling = PaToVa(Child->Sibling);\r
+\r
+ DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class));\r
+\r
+ // If the child has a sibling list, then search the sibling list\r
+ // for an entry that matches the specified class, type, and key.\r
+ Sibling = Child->Sibling;\r
+ while (Sibling != NULL)\r
+ {\r
+ if (Sibling->ConfigurationData)\r
+ Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData);\r
+\r
+ if (Sibling->Child)\r
+ Sibling->Child = PaToVa(Sibling->Child);\r
+\r
+ if (Sibling->Parent)\r
+ Sibling->Parent = PaToVa(Sibling->Parent);\r
+\r
+ if (Sibling->Sibling)\r
+ Sibling->Sibling = PaToVa(Sibling->Sibling);\r
+\r
+ DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class));\r
+\r
+ // If the sibling has a child tree, then search the child tree\r
+ // for an entry that matches the specified class, type, and key.\r
+ if (VaToPa(Sibling->Child) != NULL)\r
+ ConvertConfigToVA(VaToPa(Sibling->Child));\r
+\r
+ Sibling = VaToPa(Sibling->Sibling);\r
+ }\r
+\r
+ Child = VaToPa(Child->Child);\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * PROJECT: WinLoader\r
+ * LICENSE: GPL - See COPYING in the top level directory\r
+ * FILE: freeldr/winldr/peloader.c\r
+ * PURPOSE: Provides routines for loading PE files. To be merged with\r
+ * arch/i386/loader.c in future\r
+ * This article was very handy during development:\r
+ * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/\r
+ * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)\r
+ * The source code in this file is based on the work of respective\r
+ * authors of PE loading code in ReactOS and Brian Palmer and\r
+ * Alex Ionescu's arch/i386/loader.c, and my research project\r
+ * (creating a native EFI loader for Windows)\r
+ */\r
+\r
+/* INCLUDES ***************************************************************/\r
+#include <freeldr.h>\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/* FUNCTIONS **************************************************************/\r
+\r
+BOOLEAN\r
+WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,\r
+ IN PCCH DirectoryPath,\r
+ IN PLDR_DATA_TABLE_ENTRY ScanDTE)\r
+{\r
+ return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,\r
+ IN PCCH BaseDllName,\r
+ IN PCCH FullDllName,\r
+ IN PVOID BasePA,\r
+ OUT PLDR_DATA_TABLE_ENTRY *NewEntry)\r
+{\r
+ return FALSE;\r
+}\r
+\r
+/* WinLdrLoadImage loads the specified image from the file (it doesn't\r
+ perform any additional operations on the filename, just directly\r
+ calls the file I/O routines), and relocates it so that it's ready\r
+ to be used when paging is enabled.\r
+ Addressing mode: physical\r
+ */\r
+BOOLEAN\r
+WinLdrLoadImage(IN PCHAR FileName,\r
+ OUT PVOID *ImageBasePA)\r
+{\r
+ return FALSE;\r
+}\r
+\r
+/* PRIVATE FUNCTIONS *******************************************************/\r
#define NDEBUG\r
#include <debug.h>\r
\r
+VOID DumpMemoryAllocMap(VOID);\r
+VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);\r
+\r
VOID\r
LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)\r
{\r
CHAR MsgBuffer[256];\r
+ CHAR SystemPath[1024], SearchPath[1024];\r
+ CHAR FileName[1024];\r
+ CHAR BootPath[256];\r
+ PVOID NtosBase = NULL, HalBase = NULL;\r
+ BOOLEAN Status;\r
+ ULONG SectionId;\r
+ ULONG BootDevice;\r
+ PLOADER_PARAMETER_BLOCK LoaderBlock=NULL, LoaderBlockVA;\r
+ PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE;\r
+ KERNEL_ENTRY_POINT KiSystemStartup;\r
+ // Mm-related things\r
+ PVOID GdtIdt=NULL;\r
+ ULONG PcrBasePage=0;\r
+ ULONG TssBasePage=0;\r
+\r
+ //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);\r
+ //UiMessageBox(MsgBuffer);\r
+\r
+ //\r
+ // Open the operating system section\r
+ // specified in the .ini file\r
+ //\r
+ if (!IniOpenSection(OperatingSystemName, &SectionId))\r
+ {\r
+ sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);\r
+ UiMessageBox(MsgBuffer);\r
+ return;\r
+ }\r
+\r
+ /*\r
+ * Make sure the system path is set in the .ini file\r
+ */\r
+ if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))\r
+ {\r
+ UiMessageBox("System path not specified for selected operating system.");\r
+ return;\r
+ }\r
+\r
+ if (!MachDiskNormalizeSystemPath(SystemPath,\r
+ sizeof(SystemPath)))\r
+ {\r
+ UiMessageBox("Invalid system path");\r
+ return;\r
+ }\r
+\r
+ UiDrawStatusText("Loading...");\r
+\r
+ /*\r
+ * Try to open system drive\r
+ */\r
+ BootDevice = 0xffffffff;\r
+ if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice))\r
+ {\r
+ UiMessageBox("Failed to open boot drive.");\r
+ return;\r
+ }\r
+\r
+ /* append a backslash */\r
+ if ((strlen(BootPath)==0) ||\r
+ BootPath[strlen(BootPath)] != '\\')\r
+ strcat(BootPath, "\\");\r
+\r
+ DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));\r
+\r
+ /* Allocate and minimalistic-initialize LPB */\r
+ //AllocateAndInitLPB(&LoaderBlock);\r
+\r
+ // Load kernel\r
+ strcpy(FileName, BootPath);\r
+ strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");\r
+ Status = WinLdrLoadImage(FileName, &NtosBase);\r
+ DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d\n", Status));\r
+\r
+ // Load HAL\r
+ strcpy(FileName, BootPath);\r
+ strcat(FileName, "SYSTEM32\\HAL.DLL");\r
+ Status = WinLdrLoadImage(FileName, &HalBase);\r
+ DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d\n", Status));\r
+\r
+ WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",\r
+ "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);\r
+ WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",\r
+ "WINNT\\SYSTEM32\\HAL.EXE", HalBase, &HalDTE);\r
+\r
+ /* Load all referenced DLLs for kernel and HAL */\r
+ strcpy(SearchPath, BootPath);\r
+ strcat(SearchPath, "SYSTEM32\\");\r
+ WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE);\r
+ WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE);\r
+\r
+ /* Initialize Phase 1 - before NLS */\r
+ //WinLdrInitializePhase1(LoaderBlock);\r
+\r
+ /* Load SYSTEM hive and its LOG file */\r
+ strcpy(SearchPath, BootPath);\r
+ strcat(SearchPath, "SYSTEM32\\CONFIG\\");\r
+ //Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");\r
+ DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status));\r
+\r
+ /* Load NLS data */\r
+ strcpy(SearchPath, BootPath);\r
+ strcat(SearchPath, "SYSTEM32\\");\r
+ //Status = WinLdrLoadNLSData(LoaderBlock, SearchPath,\r
+ // "c_1252.nls", "c_437.nls", "l_intl.nls");\r
+ DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status));\r
+\r
+ /* Load OEM HAL font */\r
+\r
+ /* Load boot drivers */\r
\r
- sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);\r
- UiMessageBox(MsgBuffer);\r
+ /* Alloc PCR, TSS, do magic things with the GDT/IDT */\r
+ //WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);\r
+\r
+ /* Save entry-point pointer (VA) */\r
+ KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;\r
+ LoaderBlockVA = PaToVa(LoaderBlock);\r
+\r
+ /* Debugging... */\r
+ //DumpMemoryAllocMap();\r
+\r
+ /* Turn on paging mode of CPU*/\r
+ WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);\r
+\r
+ DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",\r
+ KiSystemStartup, LoaderBlockVA));\r
+\r
+ WinLdrpDumpMemoryDescriptors(LoaderBlockVA);\r
+\r
+ /*__asm\r
+ {\r
+ or esp, KSEG0_BASE;\r
+ or ebp, KSEG0_BASE;\r
+ }*/\r
+\r
+ /*\r
+ {\r
+ ULONG *trrr = (ULONG *)(512*1024*1024);\r
+\r
+ *trrr = 0x13131414;\r
+ }\r
+\r
+ //FIXME!\r
+ while (1) {};*/\r
+\r
+ (KiSystemStartup)(LoaderBlockVA);\r
\r
return;\r
}\r
+\r
+VOID\r
+WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)\r
+{\r
+ PLIST_ENTRY NextMd;\r
+ PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;\r
+\r
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;\r
+\r
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead)\r
+ {\r
+ MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);\r
+\r
+\r
+ DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,\r
+ MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType));\r
+\r
+ NextMd = MemoryDescriptor->ListEntry.Flink;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * PROJECT: EFI Windows Loader\r
+ * LICENSE: GPL - See COPYING in the top level directory\r
+ * FILE: freeldr/winldr/wlmemory.c\r
+ * PURPOSE: Memory related routines\r
+ * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ***************************************************************/\r
+\r
+#include <freeldr.h>\r
+\r
+#include <ndk/asm.h>\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+// This is needed because headers define wrong one for ReactOS\r
+#undef KIP0PCRADDRESS\r
+#define KIP0PCRADDRESS 0xffdff000\r
+\r
+#define HYPER_SPACE_ENTRY 0x300\r
+\r
+/* GLOBALS ***************************************************************/\r
+\r
+/* FUNCTIONS **************************************************************/\r
+\r
+BOOLEAN\r
+WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,\r
+ ULONG PcrBasePage,\r
+ ULONG TssBasePage,\r
+ PVOID GdtIdt)\r
+{\r
+ return FALSE;\r
+}\r