Fix a couple of problems with FreeLDR portability.
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / setupldr.c
index 369d9b8..fda0289 100644 (file)
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define _NTSYSTEM_
 #include <freeldr.h>
+#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
-
-#define USE_UI
-
-static BOOLEAN
-FreeldrReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
-{
-  ULONG BytesRead;
+reactos_mem_data_t reactos_mem_data;
+extern char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE];
+char szBootPath[256];
+char szHalName[256];
+CHAR SystemRoot[255];
+extern ULONG_PTR KernelBase;
+extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
 
-  return FsReadFile((PFILE) FileContext, (ULONG) Size, &BytesRead, Buffer)
-         && Size == BytesRead;
-}
+extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
 
-static BOOLEAN
-FreeldrSeekFile(PVOID FileContext, ULONG_PTR Position)
-{
-  FsSetFilePointer((PFILE) FileContext, (ULONG) Position);
-    return TRUE;
-}
+#define USE_UI
 
-static BOOLEAN
-LoadKernel(PCSTR szSourcePath, PCSTR szFileName)
+BOOLEAN
+NTAPI
+static FrLdrLoadKernel(IN PCHAR szFileName,
+                       IN INT nPos)
 {
-  CHAR szFullName[256];
-#ifdef USE_UI
-  CHAR szBuffer[80];
-#endif
-  PFILE FilePointer;
-  PCSTR szShortName;
-
-  if (szSourcePath[0] != '\\')
-    {
-      strcpy(szFullName, "\\");
-      strcat(szFullName, szSourcePath);
-    }
-  else
-    {
-      strcpy(szFullName, szSourcePath);
-    }
-
-  if (szFullName[strlen(szFullName)] != '\\')
-    {
-      strcat(szFullName, "\\");
-    }
+    PFILE FilePointer;
+    PCHAR szShortName;
+    CHAR szBuffer[256];
+    PVOID LoadBase;
+    PIMAGE_NT_HEADERS NtHeader;
 
-  if (szFileName[0] != '\\')
+    /* Extract Kernel filename without path */
+    szShortName = strrchr(szFileName, '\\');
+    if (!szShortName)
     {
-      strcat(szFullName, szFileName);
+        /* No path, leave it alone */
+        szShortName = szFileName;
     }
-  else
+    else
     {
-      strcat(szFullName, szFileName + 1);
+        /* Skip the path */
+        szShortName = szShortName + 1;
     }
 
-  szShortName = strrchr(szFileName, '\\');
-  if (szShortName == NULL)
-    szShortName = szFileName;
-  else
-    szShortName = szShortName + 1;
-
-  FilePointer = FsOpenFile(szFullName);
-  if (FilePointer == NULL)
+    /* Open the Kernel */
+    FilePointer = FsOpenFile(szFileName);
+    if (!FilePointer)
     {
-      printf("Could not find %s\n", szShortName);
-      return(FALSE);
+        /* Return failure on the short name */
+        strcpy(szBuffer, szShortName);
+        strcat(szBuffer, " not found.");
+        UiMessageBox(szBuffer);
+        return FALSE;
     }
 
-  /*
-   * Update the status bar with the current file
-   */
-#ifdef USE_UI
-  sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
-  UiDrawStatusText(szBuffer);
-#else
-  printf("Reading %s\n", szShortName);
-#endif
+    /* Update the status bar with the current file */
+    strcpy(szBuffer, "Reading ");
+    strcat(szBuffer, szShortName);
+    UiDrawStatusText(szBuffer);
 
-  /*
-   * Load the kernel
-   */
-  FrLdrMapKernel(FilePointer);
+    /* Do the actual loading */
+    LoadBase = FrLdrMapImage(FilePointer, szShortName, 1);
 
-  return(TRUE);
-}
+    /* Get the NT header, kernel base and kernel entry */
+    NtHeader = RtlImageNtHeader(LoadBase);
+    KernelBase = NtHeader->OptionalHeader.ImageBase;
+    KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + NtHeader->OptionalHeader.AddressOfEntryPoint);
+    LoaderBlock.KernelBase = KernelBase;
 
-static BOOLEAN
-LoadKernelSymbols(PCSTR szSourcePath, PCSTR szFileName)
-{
-  static ROSSYM_CALLBACKS FreeldrCallbacks =
-    {
-      MmAllocateMemory,
-      MmFreeMemory,
-      FreeldrReadFile,
-      FreeldrSeekFile
-    };
-  CHAR szFullName[256];
-  PFILE FilePointer;
-  PROSSYM_INFO RosSymInfo;
-  ULONG Size;
-  ULONG_PTR Base;
-
-  if (szSourcePath[0] != '\\')
-    {
-      strcpy(szFullName, "\\");
-      strcat(szFullName, szSourcePath);
-    }
-  else
-    {
-      strcpy(szFullName, szSourcePath);
-    }
-
-  if (szFullName[strlen(szFullName)] != '\\')
-    {
-      strcat(szFullName, "\\");
-    }
-
-  if (szFileName[0] != '\\')
-    {
-      strcat(szFullName, szFileName);
-    }
-  else
-    {
-      strcat(szFullName, szFileName + 1);
-    }
-
-  RosSymInit(&FreeldrCallbacks);
-
-  FilePointer = FsOpenFile(szFullName);
-  if (FilePointer  && RosSymCreateFromFile(FilePointer, &RosSymInfo))
-    {
-      Base = FrLdrCreateModule("NTOSKRNL.SYM");
-      Size = RosSymGetRawDataLength(RosSymInfo);
-      RosSymGetRawData(RosSymInfo, (PVOID)Base);
-      FrLdrCloseModule(Base, Size);
-      RosSymDelete(RosSymInfo);
-      return TRUE;
-    }
-  return FALSE;
+    /* Update Processbar and return success */
+    return TRUE;
 }
 
 static BOOLEAN
 LoadDriver(PCSTR szSourcePath, PCSTR szFileName)
 {
-  CHAR szFullName[256];
-#ifdef USE_UI
-  CHAR szBuffer[80];
-#endif
-  PFILE FilePointer;
-  PCSTR szShortName;
-
-  if (szSourcePath[0] != '\\')
-    {
-      strcpy(szFullName, "\\");
-      strcat(szFullName, szSourcePath);
-    }
-  else
-    {
-      strcpy(szFullName, szSourcePath);
-    }
-
-  if (szFullName[strlen(szFullName)] != '\\')
-    {
-      strcat(szFullName, "\\");
-    }
-
-  if (szFileName[0] != '\\')
-    {
-      strcat(szFullName, szFileName);
-    }
-  else
-    {
-      strcat(szFullName, szFileName + 1);
-    }
-
-  szShortName = strrchr(szFileName, '\\');
-  if (szShortName == NULL)
-    szShortName = szFileName;
-  else
-    szShortName = szShortName + 1;
-
-
-  FilePointer = FsOpenFile(szFullName);
-  if (FilePointer == NULL)
-    {
-      printf("Could not find %s\n", szFileName);
-      return(FALSE);
-    }
-
-  /*
-   * Update the status bar with the current file
-   */
-#ifdef USE_UI
-  sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
-  UiDrawStatusText(szBuffer);
-#else
-  printf("Reading %s\n", szShortName);
-#endif
-
-  /* Load the driver */
-  FrLdrLoadModule(FilePointer, szFileName, NULL);
-
-  return(TRUE);
+    return FrLdrLoadDriver((PCHAR)szFileName, 0);
 }
 
 
@@ -234,9 +105,7 @@ static BOOLEAN
 LoadNlsFile(PCSTR szSourcePath, PCSTR szFileName, PCSTR szModuleName)
 {
   CHAR szFullName[256];
-#ifdef USE_UI
   CHAR szBuffer[80];
-#endif
   PFILE FilePointer;
   PCSTR szShortName;
 
@@ -281,12 +150,8 @@ LoadNlsFile(PCSTR szSourcePath, PCSTR szFileName, PCSTR szModuleName)
   /*
    * Update the status bar with the current file
    */
-#ifdef USE_UI
   sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
   UiDrawStatusText(szBuffer);
-#else
-  printf("Reading %s\n", szShortName);
-#endif
 
   /* Load the driver */
   FrLdrLoadModule(FilePointer, szModuleName, NULL);
@@ -296,82 +161,78 @@ LoadNlsFile(PCSTR szSourcePath, PCSTR szFileName, PCSTR szModuleName)
 
 VOID RunLoader(VOID)
 {
-  ULONG_PTR Base;
-  ULONG Size;
+  ULONG i;
   const char *SourcePath;
-  const char *LoadOptions;
-  UINT i;
+  const char *LoadOptions = "", *DbgLoadOptions = "";
+  const char *sourcePaths[] = {
+      "", /* Only for floppy boot */
+#if defined(_M_IX86)
+      "\\I386",
+#elif defined(_M_MPPC)
+      "\\PPC",
+#elif defined(_M_MRX000)
+      "\\MIPS",
+#endif
+      "\\reactos",
+      NULL };
+  char szKernelName[256];
 
   HINF InfHandle;
   ULONG ErrorLine;
   INFCONTEXT InfContext;
 
-  extern ULONG PageDirectoryStart;
-  extern ULONG PageDirectoryEnd;
-
   /* 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 = (unsigned long)reactos_kernel_cmdline;
   LoaderBlock.ModsCount = 0;
-  LoaderBlock.ModsAddr = (unsigned long)reactos_modules;
-  LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&reactos_memory_map, 32) * sizeof(memory_map_t);
+  LoaderBlock.ModsAddr = reactos_modules;
+  LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
   if (LoaderBlock.MmapLength)
-    {
-      LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
+  {
+#ifdef _M_IX86
+      ULONG i;
+#endif
       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++)
-        {
-          if (MEMTYPE_USABLE == reactos_memory_map[i].type &&
+#ifdef _M_IX86
+      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 (MEMTYPE_USABLE == reactos_memory_map[i].type &&
+              }
+          }
+          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;
-            }
-#if 0
-           printf("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);
-#endif
-        }
-    }
-#if 0
-  printf("low_mem = %d\n", LoaderBlock.MemLower);
-  printf("high_mem = %d\n", LoaderBlock.MemHigher);
-  MachConsGetCh();
+          }
+      }
 #endif
+  }
 
 #ifdef USE_UI
   SetupUiInitialize();
-  UiDrawStatusText("");
 #endif
+  UiDrawStatusText("");
+
+    extern BOOLEAN FrLdrBootType;
+    FrLdrBootType = TRUE;
 
   /* Initialize registry */
   RegInitializeRegistry();
 
   /* Detect hardware */
-#ifdef USE_UI
   UiDrawStatusText("Detecting hardware...");
-#else
-  printf("Detecting hardware...\n\n");
-#endif
-  MachHwDetect();
-#ifdef USE_UI
+  LoaderBlock.ArchExtra = (ULONG)MachHwDetect();
   UiDrawStatusText("");
-#endif
 
   /* set boot device */
   MachDiskGetBootDevice(&LoaderBlock.BootDevice);
@@ -379,25 +240,39 @@ VOID RunLoader(VOID)
   /* Open boot drive */
   if (!FsOpenBootVolume())
     {
-#ifdef USE_UI
       UiMessageBox("Failed to open boot drive.");
-#else
-      printf("Failed to open boot drive.");
-#endif
       return;
     }
 
   /* Open 'txtsetup.sif' */
-  if (!InfOpenFile (&InfHandle,
-                   MachDiskBootingFromFloppy() ? "\\txtsetup.sif" : "\\reactos\\txtsetup.sif",
-                   &ErrorLine))
+  for (i = MachDiskBootingFromFloppy() ? 0 : 1; ; i++)
+  {
+    SourcePath = sourcePaths[i];
+    if (!SourcePath)
     {
       printf("Failed to open 'txtsetup.sif'\n");
       return;
     }
+    strcpy(szKernelName, SourcePath);
+    strcat(szKernelName, "\\txtsetup.sif");
+    if (InfOpenFile (&InfHandle, szKernelName, &ErrorLine))
+      break;
+  }
+  if (!*SourcePath)
+    SourcePath = "\\";
 
+#ifdef DBG
   /* Get load options */
-  if (!InfFindFirstLine (InfHandle,
+  if (InfFindFirstLine (InfHandle,
+                       "SetupData",
+                       "DbgOsLoadOptions",
+                       &InfContext))
+    {
+       if (!InfGetDataField (&InfContext, 1, &DbgLoadOptions))
+           DbgLoadOptions = "";
+    }
+#endif
+  if (!strlen(DbgLoadOptions) && !InfFindFirstLine (InfHandle,
                         "SetupData",
                         "OsLoadOptions",
                         &InfContext))
@@ -413,68 +288,36 @@ VOID RunLoader(VOID)
       printf("Failed to get load options\n");
       return;
     }
-#if 0
-  printf("LoadOptions: '%s'\n", LoadOptions);
-#endif
-
-  if (MachDiskBootingFromFloppy())
-    {
-      /* Boot from floppy disk */
-      SourcePath = "\\";
-    }
-  else
-    {
-      /* Boot from cdrom */
-      SourcePath = "\\reactos";
-    }
 
   /* Set kernel command line */
   MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
-  strcat(strcat(strcat(reactos_kernel_cmdline, SourcePath), " "),
-         LoadOptions);
-
-  /* Load ntoskrnl.exe */
-  if (!LoadKernel(SourcePath, "ntoskrnl.exe"))
-    return;
-
+  strcat(strcat(strcat(strcat(reactos_kernel_cmdline, SourcePath), " "),
+               LoadOptions), DbgLoadOptions);
 
-  /* Load hal.dll */
-  if (!LoadDriver(SourcePath, "hal.dll"))
-    return;
+  strcpy(SystemRoot, SourcePath);
+  strcat(SystemRoot, "\\");
 
-  /* Create ntoskrnl.sym */
-  LoadKernelSymbols(SourcePath, "ntoskrnl.exe");
+    /* Setup the boot path and kernel path */
+    strcpy(szBootPath, SourcePath);
+    strcpy(szKernelName, szBootPath);
+    strcat(szKernelName, "\\ntoskrnl.exe");
 
-  /* Export the hardware hive */
-  Base = FrLdrCreateModule ("HARDWARE");
-  RegExportBinaryHive (L"\\Registry\\Machine\\HARDWARE", (PVOID)Base, &Size);
-  FrLdrCloseModule (Base, Size);
+    /* Setup the HAL path */
+    strcpy(szHalName, szBootPath);
+    strcat(szHalName, "\\hal.dll");
 
-#if 0
-  printf("Base: %x\n", Base);
-  printf("Size: %u\n", Size);
-  printf("*** System stopped ***\n");
-for(;;);
-#endif
+    /* Load the kernel */
+    if (!FrLdrLoadKernel(szKernelName, 5)) return;
 
   /* Insert boot disk 2 */
   if (MachDiskBootingFromFloppy())
     {
-#ifdef USE_UI
       UiMessageBox("Please insert \"ReactOS Boot Disk 2\" and press ENTER");
-#else
-      printf("\n\n Please insert \"ReactOS Boot Disk 2\" and press ENTER\n");
-      MachConsGetCh();
-#endif
 
       /* Open boot drive */
       if (!FsOpenBootVolume())
        {
-#ifdef USE_UI
          UiMessageBox("Failed to open boot drive.");
-#else
-         printf("Failed to open boot drive.");
-#endif
          return;
        }
 
@@ -503,11 +346,7 @@ for(;;);
   /* Load ANSI codepage file */
   if (!LoadNlsFile(SourcePath, LoadOptions, "ansi.nls"))
     {
-#ifdef USE_UI
       UiMessageBox("Failed to load the ANSI codepage file.");
-#else
-      printf("Failed to load the ANSI codepage file.");
-#endif
       return;
     }
 
@@ -532,11 +371,7 @@ for(;;);
   /* Load OEM codepage file */
   if (!LoadNlsFile(SourcePath, LoadOptions, "oem.nls"))
     {
-#ifdef USE_UI
       UiMessageBox("Failed to load the OEM codepage file.");
-#else
-      printf("Failed to load the OEM codepage file.");
-#endif
       return;
     }
 
@@ -561,91 +396,46 @@ for(;;);
   /* Load Unicode casemap file */
   if (!LoadNlsFile(SourcePath, LoadOptions, "casemap.nls"))
     {
-#ifdef USE_UI
       UiMessageBox("Failed to load the Unicode casemap file.");
-#else
-      printf("Failed to load the Unicode casemap file.");
-#endif
       return;
     }
 
-#if 0
-  /* Load acpi.sys */
-  if (!LoadDriver(SourcePath, "acpi.sys"))
-    return;
-#endif
-
-#if 0
-  /* Load isapnp.sys */
-  if (!LoadDriver(SourcePath, "isapnp.sys"))
-    return;
-#endif
-
-#if 0
-  /* Load pci.sys */
-  if (!LoadDriver(SourcePath, "pci.sys"))
-    return;
-#endif
-
-  /* Load scsiport.sys */
-  if (!LoadDriver(SourcePath, "scsiport.sys"))
-    return;
-
-  /* Load atapi.sys (depends on hardware detection) */
-  if (!LoadDriver(SourcePath, "atapi.sys"))
-    return;
-
-  /* Load buslogic.sys (depends on hardware detection) */
-  if (!LoadDriver(SourcePath, "buslogic.sys"))
-    return;
-
-  /* Load class2.sys */
-  if (!LoadDriver(SourcePath, "class2.sys"))
-    return;
-
-  /* Load cdrom.sys */
-  if (!LoadDriver(SourcePath, "cdrom.sys"))
-    return;
-
-  /* Load cdfs.sys */
-  if (!LoadDriver(SourcePath, "cdfs.sys"))
-    return;
-
-  /* Load disk.sys */
-  if (!LoadDriver(SourcePath, "disk.sys"))
-    return;
-
-  /* Load floppy.sys */
-  if (!LoadDriver(SourcePath, "floppy.sys"))
-    return;
-
   /* Load vfatfs.sys (could be loaded by the setup prog!) */
   if (!LoadDriver(SourcePath, "vfatfs.sys"))
     return;
 
+    /* Load additional files specified in txtsetup.inf */
+    if (InfFindFirstLine(InfHandle,
+                         "SourceDisksFiles",
+                         NULL,
+                         &InfContext))
+    {
+        do
+        {
+            LPCSTR Media, DriverName;
+            if (InfGetDataField(&InfContext, 7, &Media) &&
+                InfGetDataField(&InfContext, 0, &DriverName))
+            {
+                if (strcmp(Media, "x") == 0)
+                {
+                    if (!LoadDriver(SourcePath, DriverName))
+                        return;
+                }
+            }
+        } while (InfFindNextLine(&InfContext, &InfContext));
+    }
 
-  /* Load keyboard driver */
-#if 0
-  if (!LoadDriver(SourcePath, "keyboard.sys"))
-    return;
-#endif
-  if (!LoadDriver(SourcePath, "i8042prt.sys"))
-    return;
-  if (!LoadDriver(SourcePath, "kbdclass.sys"))
-    return;
-
-  /* Load screen driver */
-  if (!LoadDriver(SourcePath, "blue.sys"))
-    return;
-
-#ifdef USE_UI
   UiUnInitialize("Booting ReactOS...");
-#endif
 
-  /* Now boot the kernel */
-  DiskStopFloppyMotor();
-  MachVideoPrepareForReactOS();
-  FrLdrStartup(0x2badb002);
+    //
+    // Perform architecture-specific pre-boot configuration
+    //
+    MachPrepareForReactOS(FALSE);
+    
+    //
+    // Setup paging and jump to kernel
+    //
+       FrLdrStartup(0x2badb002);
 }
 
 /* EOF */