* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define _NTSYSTEM_
#include <freeldr.h>
#include <debug.h>
-#include <arch.h>
-#include <disk.h>
-#include <reactos.h>
-#include <rtl.h>
-#include <fs.h>
-#include <multiboot.h>
-#include <mm.h>
-#include <machine.h>
-#include <ui.h>
-#include <inffile.h>
-#include "registry.h"
-
-
-//#define USE_UI
-
-
-static BOOL
-LoadKernel(PCHAR szSourcePath, PCHAR szFileName)
+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
+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;
+
+extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
+
+#define USE_UI
+
+BOOLEAN
+NTAPI
+static FrLdrLoadKernel(IN PCHAR szFileName,
+ IN INT nPos)
{
- CHAR szFullName[256];
-#ifdef USE_UI
- CHAR szBuffer[80];
-#endif
- PFILE FilePointer;
- PCHAR szShortName;
+ PFILE FilePointer;
+ PCHAR szShortName;
+ CHAR szBuffer[256];
+ PVOID LoadBase;
+ PIMAGE_NT_HEADERS NtHeader;
- if (szSourcePath[0] != '\\')
+ /* Extract Kernel filename without path */
+ szShortName = strrchr(szFileName, '\\');
+ if (!szShortName)
{
- strcpy(szFullName, "\\");
- strcat(szFullName, szSourcePath);
+ /* No path, leave it alone */
+ szShortName = szFileName;
}
- else
+ else
{
- strcpy(szFullName, szSourcePath);
+ /* Skip the path */
+ szShortName = szShortName + 1;
}
- if (szFullName[strlen(szFullName)] != '\\')
+ /* Open the Kernel */
+ FilePointer = FsOpenFile(szFileName);
+ if (!FilePointer)
{
- strcat(szFullName, "\\");
+ /* Return failure on the short name */
+ strcpy(szBuffer, szShortName);
+ strcat(szBuffer, " not found.");
+ UiMessageBox(szBuffer);
+ return FALSE;
}
- if (szFileName[0] != '\\')
- {
- strcat(szFullName, szFileName);
- }
- else
- {
- strcat(szFullName, szFileName + 1);
- }
+ /* Update the status bar with the current file */
+ strcpy(szBuffer, "Reading ");
+ strcat(szBuffer, szShortName);
+ UiDrawStatusText(szBuffer);
- szShortName = strrchr(szFileName, '\\');
- if (szShortName == NULL)
- szShortName = szFileName;
- else
- szShortName = szShortName + 1;
+ /* Do the actual loading */
+ LoadBase = FrLdrMapImage(FilePointer, szShortName, 1);
- FilePointer = FsOpenFile(szFullName);
- if (FilePointer == NULL)
- {
- printf("Could not find %s\n", szShortName);
- return(FALSE);
- }
+ /* 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;
- /*
- * Update the status bar with the current file
- */
-#ifdef USE_UI
- sprintf(szBuffer, "Reading %s", szShortName);
- UiDrawStatusText(szBuffer);
-#else
- printf("Reading %s\n", szShortName);
-#endif
-
- /*
- * Load the kernel
- */
- FrLdrMapKernel(FilePointer);
-
- return(TRUE);
+ /* Update Processbar and return success */
+ return TRUE;
}
-
-static BOOL
-LoadDriver(PCHAR szSourcePath, PCHAR szFileName)
+static BOOLEAN
+LoadDriver(PCSTR szSourcePath, PCSTR szFileName)
{
- CHAR szFullName[256];
-#ifdef USE_UI
- CHAR szBuffer[80];
-#endif
- PFILE FilePointer;
- PCHAR 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, "Reading %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);
}
-static BOOL
-LoadNlsFile(PCHAR szSourcePath, PCHAR szFileName, PCHAR szModuleName)
+static BOOLEAN
+LoadNlsFile(PCSTR szSourcePath, PCSTR szFileName, PCSTR szModuleName)
{
CHAR szFullName[256];
-#ifdef USE_UI
CHAR szBuffer[80];
-#endif
PFILE FilePointer;
- PCHAR szShortName;
+ PCSTR szShortName;
if (szSourcePath[0] != '\\')
{
/*
* Update the status bar with the current file
*/
-#ifdef USE_UI
- sprintf(szBuffer, "Reading %s", szShortName);
+ sprintf(szBuffer, "Setup is loading files (%s)", szShortName);
UiDrawStatusText(szBuffer);
-#else
- printf("Reading %s\n", szShortName);
-#endif
/* Load the driver */
FrLdrLoadModule(FilePointer, szModuleName, NULL);
return(TRUE);
}
-
VOID RunLoader(VOID)
{
- ULONG_PTR Base;
- ULONG Size;
- char *SourcePath;
- char *LoadOptions;
- int i;
+ ULONG i;
+ const char *SourcePath;
+ 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_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
+ LoaderBlock.CommandLine = reactos_kernel_cmdline;
LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
- LoaderBlock.BootDevice = 0xffffffff;
- LoaderBlock.CommandLine = (unsigned long)multiboot_kernel_cmdline;
LoaderBlock.ModsCount = 0;
- LoaderBlock.ModsAddr = (unsigned long)multiboot_modules;
- LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&multiboot_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)&multiboot_memory_map;
- LoaderBlock.Flags |= MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_MEMORY_MAP;
- multiboot_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 == multiboot_memory_map[i].type &&
- 0 == multiboot_memory_map[i].base_addr_low)
- {
- LoaderBlock.MemLower = (multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low) / 1024;
+ {
+#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
+#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 == multiboot_memory_map[i].type &&
- multiboot_memory_map[i].base_addr_low <= 1024 * 1024 &&
- 1024 * 1024 <= multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low)
- {
- LoaderBlock.MemHigher = (multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low) / 1024 - 1024;
- }
-#if 0
- printf("start: %x\t size: %x\t type %d\n",
- multiboot_memory_map[i].base_addr_low,
- multiboot_memory_map[i].length_low,
- multiboot_memory_map[i].type);
-#endif
- }
- }
-#if 0
- printf("low_mem = %d\n", LoaderBlock.MemLower);
- printf("high_mem = %d\n", LoaderBlock.MemHigher);
- MachConsGetCh();
+ }
+ }
+ 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;
+ }
+ }
#endif
+ }
#ifdef USE_UI
- UiInitialize();
- UiDrawStatusText("");
+ SetupUiInitialize();
#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 drive and partition */
- ((char *)(&LoaderBlock.BootDevice))[0] = (char)BootDrive;
- ((char *)(&LoaderBlock.BootDevice))[1] = (char)BootPartition;
+ /* set boot device */
+ MachDiskGetBootDevice(&LoaderBlock.BootDevice);
/* Open boot drive */
- if (!FsOpenVolume(BootDrive, BootPartition))
+ 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,
- (BootDrive < 0x80) ? "\\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))
printf("Failed to get load options\n");
return;
}
-#if 0
- printf("LoadOptions: '%s'\n", LoadOptions);
-#endif
-
- if (BootDrive < 0x80)
- {
- /* Boot from floppy disk */
- SourcePath = "\\";
- }
- else
- {
- /* Boot from cdrom */
- SourcePath = "\\reactos";
- }
/* Set kernel command line */
- sprintf(multiboot_kernel_cmdline,
- "multi(0)disk(0)%s(%u)%s %s",
- (BootDrive < 0x80) ? "fdisk" : "cdrom",
- (unsigned int)BootDrive,
- SourcePath,
- LoadOptions);
-
- /* Load ntoskrnl.exe */
- if (!LoadKernel(SourcePath, "ntoskrnl.exe"))
- return;
+ MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
+ strcat(strcat(strcat(strcat(reactos_kernel_cmdline, SourcePath), " "),
+ LoadOptions), DbgLoadOptions);
+ strcpy(SystemRoot, SourcePath);
+ strcat(SystemRoot, "\\");
- /* Load hal.dll */
- if (!LoadDriver(SourcePath, "hal.dll"))
- return;
-
+ /* 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 ("\\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 (BootDrive < 0x80)
+ 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 (!FsOpenVolume(BootDrive, BootPartition))
+ if (!FsOpenBootVolume())
{
-#ifdef USE_UI
UiMessageBox("Failed to open boot drive.");
-#else
- printf("Failed to open boot drive.");
-#endif
return;
}
/* 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;
}
/* 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;
}
/* 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 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 (!LoadDriver(SourcePath, "keyboard.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 */