Fix a couple of problems with FreeLDR portability.
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / reactos.c
index eafd96d..87e6414 100644 (file)
  */
 
 #include <freeldr.h>
-
-#define NDEBUG
 #include <debug.h>
 
+extern ULONG PageDirectoryStart;
+extern ULONG PageDirectoryEnd;
+
 ROS_LOADER_PARAMETER_BLOCK LoaderBlock;
 char                                   reactos_kernel_cmdline[255];    // Command line passed to kernel
 LOADER_MODULE                  reactos_modules[64];            // Array to hold boot module info loaded for the kernel
 char                                   reactos_module_strings[64][256];        // Array to hold module names
-unsigned long                  reactos_memory_map_descriptor_size;
-memory_map_t                   reactos_memory_map[32];         // Memory map
+// Make this a single struct to guarantee that these elements are nearby in
+// memory.  
+reactos_mem_data_t reactos_mem_data;
 ARC_DISK_SIGNATURE      reactos_arc_disk_info[32]; // ARC Disk Information
 char                    reactos_arc_strings[32][256];
 unsigned long           reactos_disk_count = 0;
+char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0};
+
 CHAR szHalName[255];
 CHAR szBootPath[255];
+CHAR SystemRoot[255];
 static CHAR szLoadingMsg[] = "Loading ReactOS...";
 BOOLEAN FrLdrBootType;
+ULONG_PTR KernelBase;
+ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
 
-static BOOLEAN
-NTAPI
-FrLdrLoadKernel(PCHAR szFileName,
+BOOLEAN
+FrLdrLoadDriver(PCHAR szFileName,
                 INT nPos)
 {
     PFILE FilePointer;
-    PCHAR szShortName;
-    CHAR szBuffer[256];
+    CHAR value[256], *FinalSlash;
+    LPSTR p;
 
-    /* Extract Kernel filename without path */
-    szShortName = strrchr(szFileName, '\\');
-    if (szShortName == NULL) {
+    if (!_stricmp(szFileName, "hal.dll"))
+    {
+        /* Use the boot.ini name instead */
+        szFileName = szHalName;
+    }
 
-        /* No path, leave it alone */
-        szShortName = szFileName;
+    FinalSlash = strrchr(szFileName, '\\');
+    if(FinalSlash)
+       szFileName = FinalSlash + 1;
 
-    } else {
+    /* Open the Driver */
+    FilePointer = FsOpenFile(szFileName);
 
-        /* Skip the path */
-        szShortName = szShortName + 1;
+    /* Try under the system root in the main dir and drivers */
+    if (FilePointer == NULL)
+    {
+       strcpy(value, SystemRoot);
+       if(value[strlen(value)-1] != '\\')
+           strcat(value, "\\");
+       strcat(value, szFileName);
+       FilePointer = FsOpenFile(value);
     }
 
-    /* Open the Kernel */
-    FilePointer = FsOpenFile(szFileName);
+    if (FilePointer == NULL)
+    {
+       strcpy(value, SystemRoot);
+       if(value[strlen(value)-1] != '\\')
+           strcat(value, "\\");
+       strcat(value, "SYSTEM32\\");
+       strcat(value, szFileName);
+       FilePointer = FsOpenFile(value);
+    }
 
-    /* Make sure it worked */
+    if (FilePointer == NULL)
+    {
+       strcpy(value, SystemRoot);
+       if(value[strlen(value)-1] != '\\')
+           strcat(value, "\\");
+       strcat(value, "SYSTEM32\\DRIVERS\\");
+       strcat(value, szFileName);
+       FilePointer = FsOpenFile(value);
+    }
+
+    /* Make sure we did */
     if (FilePointer == NULL) {
 
-        /* Return failure on the short name */
-        strcpy(szBuffer, szShortName);
-        strcat(szBuffer, " not found.");
-        UiMessageBox(szBuffer);
+        /* Fail if file wasn't opened */
+        strcpy(value, szFileName);
+        strcat(value, " not found.");
         return(FALSE);
     }
 
     /* Update the status bar with the current file */
-    strcpy(szBuffer, "Reading ");
-    strcat(szBuffer, szShortName);
-    UiDrawStatusText(szBuffer);
+    strcpy(value, "Reading ");
+    p = strrchr(szFileName, '\\');
+    if (p == NULL) {
 
-    /* Do the actual loading */
-    FrLdrMapKernel(FilePointer);
+        strcat(value, szFileName);
 
-    /* Update Processbar and return success */
+    } else {
+
+        strcat(value, p + 1);
+
+    }
+    UiDrawStatusText(value);
+
+    /* Load the driver */
+    FrLdrMapImage(FilePointer, szFileName, 0);
+
+    /* Update status and return */
     UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
     return(TRUE);
 }
 
-BOOLEAN
-NTAPI
-FrLdrMapImage(
-    IN FILE *Image,
-    IN PCHAR ShortName
-);
-
-BOOLEAN
+PVOID
 NTAPI
 FrLdrLoadImage(IN PCHAR szFileName,
-               IN INT nPos)
+               IN INT nPos,
+               IN ULONG ImageType)
 {
     PFILE FilePointer;
     PCHAR szShortName;
     CHAR szBuffer[256], szFullPath[256];
-
-    /* Check if this the HAL being loaded */
-    if (!_stricmp(szFileName, "hal.dll"))
-    {
-        /* Use the boot.ini name instead */
-        szFileName = szHalName;
-    }
+    PVOID LoadBase;
 
     /* Extract filename without path */
     szShortName = strrchr(szFileName, '\\');
@@ -153,74 +182,11 @@ FrLdrLoadImage(IN PCHAR szFileName,
     UiDrawStatusText(szBuffer);
 
     /* Do the actual loading */
-    FrLdrMapImage(FilePointer, szShortName);
+    LoadBase = FrLdrMapImage(FilePointer, szShortName, ImageType);
 
     /* Update Processbar and return success */
     if (!FrLdrBootType) UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
-    return TRUE;
-}
-
-static VOID
-FreeldrFreeMem(PVOID Area)
-{
-  MmFreeMemory(Area);
-}
-
-static PVOID
-FreeldrAllocMem(ULONG_PTR Size)
-{
-  return MmAllocateMemory((ULONG) Size);
-}
-
-static BOOLEAN
-FreeldrReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
-{
-  ULONG BytesRead;
-
-  return FsReadFile((PFILE) FileContext, (ULONG) Size, &BytesRead, Buffer)
-         && Size == BytesRead;
-}
-
-static BOOLEAN
-FreeldrSeekFile(PVOID FileContext, ULONG_PTR Position)
-{
-  FsSetFilePointer((PFILE) FileContext, (ULONG) Position);
-    return TRUE;
-}
-
-static BOOLEAN
-LoadKernelSymbols(PCHAR szKernelName, int nPos)
-{
-  static ROSSYM_CALLBACKS FreeldrCallbacks =
-    {
-      FreeldrAllocMem,
-      FreeldrFreeMem,
-      FreeldrReadFile,
-      FreeldrSeekFile
-    };
-  PFILE FilePointer;
-  PROSSYM_INFO RosSymInfo;
-  ULONG Size;
-  ULONG_PTR Base;
-  //return TRUE;
-
-  RosSymInit(&FreeldrCallbacks);
-
-  FilePointer = FsOpenFile(szKernelName);
-  if (FilePointer == NULL)
-    {
-      return FALSE;
-    }
-  if (! RosSymCreateFromFile(FilePointer, &RosSymInfo))
-    {
-      return FALSE;
-    }
-  Base = FrLdrCreateModule("NTOSKRNL.SYM");
-  Size = RosSymGetRawDataLength(RosSymInfo);
-  RosSymGetRawData(RosSymInfo, (PVOID)Base);
-  FrLdrCloseModule(Base, Size);
-  RosSymDelete(RosSymInfo);
-  return TRUE;
+    return LoadBase;
 }
 
 static BOOLEAN
@@ -374,49 +340,6 @@ FrLdrLoadNlsFiles(PCHAR szSystemRoot,
     return(TRUE);
 }
 
-static BOOLEAN
-FrLdrLoadDriver(PCHAR szFileName,
-                INT nPos)
-{
-    PFILE FilePointer;
-    CHAR value[256];
-    LPSTR p;
-
-    /* Open the Driver */
-    FilePointer = FsOpenFile(szFileName);
-
-    /* Make sure we did */
-    if (FilePointer == NULL) {
-
-        /* Fail if file wasn't opened */
-        strcpy(value, szFileName);
-        strcat(value, " not found.");
-        UiMessageBox(value);
-        return(FALSE);
-    }
-
-    /* Update the status bar with the current file */
-    strcpy(value, "Reading ");
-    p = strrchr(szFileName, '\\');
-    if (p == NULL) {
-
-        strcat(value, szFileName);
-
-    } else {
-
-        strcat(value, p + 1);
-
-    }
-    UiDrawStatusText(value);
-
-    /* Load the driver */
-    FrLdrLoadModule(FilePointer, szFileName, NULL);
-
-    /* Update status and return */
-    UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
-    return(TRUE);
-}
-
 static VOID
 FrLdrLoadBootDrivers(PCHAR szSystemRoot,
                      INT nPos)
@@ -490,7 +413,7 @@ FrLdrLoadBootDrivers(PCHAR szSystemRoot,
         if (rc != ERROR_SUCCESS) OrderList[0] = 0;
 
         /* enumerate all drivers */
-        for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
+        for (TagIndex = 1; TagIndex <= SWAPD(OrderList[0]); TagIndex++) {
 
             Index = 0;
 
@@ -552,7 +475,7 @@ FrLdrLoadBootDrivers(PCHAR szSystemRoot,
                         /* Update the position if needed */
                         if (nPos < 100) nPos += 5;
 
-                        FrLdrLoadDriver(ImagePath, nPos);
+                        FrLdrLoadImage(ImagePath, nPos, 2);
 
                     } else {
 
@@ -621,7 +544,7 @@ FrLdrLoadBootDrivers(PCHAR szSystemRoot,
 
                     if (nPos < 100) nPos += 5;
 
-                    FrLdrLoadDriver(ImagePath, nPos);
+                    FrLdrLoadImage(ImagePath, nPos, 2);
 
                 } else {
 
@@ -647,17 +570,13 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
        CHAR SystemPath[255];
        CHAR szKernelName[255];
        CHAR szFileName[255];
-       UINT i;
        CHAR  MsgBuffer[256];
        ULONG SectionId;
-
+    PIMAGE_NT_HEADERS NtHeader;
+    PVOID LoadBase;
        ULONG_PTR Base;
        ULONG Size;
 
-       extern ULONG PageDirectoryStart;
-       extern ULONG PageDirectoryEnd;
-       extern BOOLEAN AcpiPresent;
-
        //
        // Open the operating system section
        // specified in the .ini file
@@ -676,47 +595,57 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
        /*
         * Setup multiboot information structure
         */
-       LoaderBlock.Flags = MB_FLAGS_BOOT_DEVICE | MB_FLAGS_COMMAND_LINE | MB_FLAGS_MODULE_INFO;
+       LoaderBlock.CommandLine = reactos_kernel_cmdline;
        LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
        LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
-       LoaderBlock.BootDevice = 0xffffffff;
-       LoaderBlock.CommandLine = reactos_kernel_cmdline;
        LoaderBlock.ModsCount = 0;
        LoaderBlock.ModsAddr = reactos_modules;
     LoaderBlock.DrivesAddr = reactos_arc_disk_info;
-       LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&reactos_memory_map, 32) * sizeof(memory_map_t);
-       if (LoaderBlock.MmapLength)
-       {
-               LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
-               LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
-               reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
-               DbgPrint((DPRINT_REACTOS, "memory map length: %d\n", LoaderBlock.MmapLength));
-               DbgPrint((DPRINT_REACTOS, "dumping memory map:\n"));
-               for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
-               {
-                       if (BiosMemoryUsable == reactos_memory_map[i].type &&
-                           0 == reactos_memory_map[i].base_addr_low)
-                       {
-                               LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
-                               if (640 < LoaderBlock.MemLower)
-                               {
-                                       LoaderBlock.MemLower = 640;
-                               }
-                       }
-                       if (BiosMemoryUsable == reactos_memory_map[i].type &&
-                           reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
-                           1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
-                       {
-                               LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
-                       }
-                       DbgPrint((DPRINT_REACTOS, "start: %x\t size: %x\t type %d\n",
-                                 reactos_memory_map[i].base_addr_low,
-                                 reactos_memory_map[i].length_low,
-                                 reactos_memory_map[i].type));
-               }
-       }
-       DbgPrint((DPRINT_REACTOS, "low_mem = %d\n", LoaderBlock.MemLower));
-       DbgPrint((DPRINT_REACTOS, "high_mem = %d\n", LoaderBlock.MemHigher));
+    LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
+    if (LoaderBlock.MmapLength)
+    {
+        ULONG i;
+        LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
+        LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
+        reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
+        for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
+        {
+#ifdef _M_PPC
+            ULONG tmp;
+            /* Also swap from long long to high/low
+             * We also have unusable memory that will be available to kernel
+             * land.  Mark it here.
+             */
+            if (BiosMemoryAcpiReclaim == reactos_memory_map[i].type)
+            {
+                reactos_memory_map[i].type = BiosMemoryUsable;
+            }
+
+            tmp = reactos_memory_map[i].base_addr_low;
+            reactos_memory_map[i].base_addr_low = reactos_memory_map[i].base_addr_high;
+            reactos_memory_map[i].base_addr_high = tmp;
+            tmp = reactos_memory_map[i].length_low;
+            reactos_memory_map[i].length_low = reactos_memory_map[i].length_high;
+            reactos_memory_map[i].length_high = tmp;
+#endif
+
+            if (BiosMemoryUsable == reactos_memory_map[i].type &&
+                0 == reactos_memory_map[i].base_addr_low)
+            {
+                LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
+                if (640 < LoaderBlock.MemLower)
+                {
+                    LoaderBlock.MemLower = 640;
+                }
+            }
+            if (BiosMemoryUsable == reactos_memory_map[i].type &&
+                reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
+                1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
+            {
+                LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
+            }
+        }
+    }
 
        /*
         * Initialize the registry
@@ -767,14 +696,22 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
        /*
         * Detect hardware
         */
-       MachHwDetect();
+       LoaderBlock.ArchExtra = (ULONG)MachHwDetect();
     UiDrawProgressBarCenter(5, 100, szLoadingMsg);
 
-       if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
     LoaderBlock.DrivesCount = reactos_disk_count;
 
        UiDrawStatusText("Loading...");
 
+       //
+       // If we have a ramdisk, this will switch to the ramdisk disk routines
+       // which read from memory instead of using the firmware. This has to be done
+       // after hardware detection, since hardware detection will require using the
+       // real routines in order to perform disk-detection (just because we're on a
+       // ram-boot doesn't mean the user doesn't have actual disks installed too!)
+       //
+       RamDiskSwitchFromBios();
+
        /*
         * Try to open system drive
         */
@@ -790,6 +727,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
                strcat(szBootPath, "\\");
 
        DbgPrint((DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath));
+       strcpy(SystemRoot, szBootPath);
 
        /*
         * Find the kernel image name
@@ -847,8 +785,15 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
                strcat(szHalName, value);
        }
 
-    /* Load the kernel */
-    if (!FrLdrLoadKernel(szKernelName, 5)) return;
+       /* Load the kernel */
+       LoadBase = FrLdrLoadImage(szKernelName, 5, 1);
+       if (!LoadBase) return;
+
+       /* Get the NT header, kernel base and kernel entry */
+       NtHeader = RtlImageNtHeader(LoadBase);
+       KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase);
+       KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint));
+       LoaderBlock.KernelBase = KernelBase;
 
        /*
         * Load the System hive from disk
@@ -897,13 +842,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
 
        UiDrawProgressBarCenter(15, 100, szLoadingMsg);
 
-       /*
-        * Export the hardware hive
-        */
-       Base = FrLdrCreateModule ("HARDWARE");
-       RegExportBinaryHive (L"\\Registry\\Machine\\HARDWARE", (PCHAR)Base, &Size);
-       FrLdrCloseModule (Base, Size);
-
        UiDrawProgressBarCenter(20, 100, szLoadingMsg);
 
        /*
@@ -911,29 +849,26 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
         */
        if (!FrLdrLoadNlsFiles(szBootPath, MsgBuffer))
        {
-               UiMessageBox(MsgBuffer);
+               UiMessageBox(MsgBuffer);
                return;
        }
        UiDrawProgressBarCenter(30, 100, szLoadingMsg);
 
-       /*
-        * Load kernel symbols
-        */
-       LoadKernelSymbols(szKernelName, 30);
-       UiDrawProgressBarCenter(40, 100, szLoadingMsg);
-
        /*
         * Load boot drivers
         */
        FrLdrLoadBootDrivers(szBootPath, 40);
        //UiUnInitialize("Booting ReactOS...");
 
-       /*
-        * Now boot the kernel
-        */
-       DiskStopFloppyMotor();
-    //MachVideoPrepareForReactOS();
-    FrLdrStartup(0x2badb002);
+    //
+    // Perform architecture-specific pre-boot configuration
+    //
+    MachPrepareForReactOS(FALSE);
+
+    //
+    // Setup paging and jump to kernel
+    //
+       FrLdrStartup(0x2badb002);
 }
 
 #undef DbgPrint