Files
reactos/linuxboot.c
T
Aleksey Bragin 9177998d8e Commit my initial work on getting Windows NT booting.
Right now, if stars on the sky get in proper places and you are lucky, it will load Windows NT 4.0 to GUI (it will be unusable due to absence of mouse/keyboard though).

Here are log messages from my local tree which I used to develop this initial version (just for reference):
Revision: 8
Author: alekseyb
Date: 22:56:15, 24 íîÿáðÿ 2006 ã.
Message:
- Initialize "ValidBootPartition" field of ArcDiskInfo (without it Windows thinks the partition is not good)
- Zero ArcDiskInfo before usage
- Load filesystem driver (fastfat.sys for now)

Windows NT4 now boots, but of course there are no mouse/keyboard.
----
Modified : /freeldr/arch/i386/hardware.c
Modified : /freeldr/windows/winldr.c
Modified : /freeldr/windows/wlregistry.c


Revision: 7
Author: alekseyb
Date: 15:37:37, 24 íîÿáðÿ 2006 ã.
Message:
- Fix Disk Peripheral entries to really be of DiskPeripheral type and PeripheralClass
- Add to PcHwDetect() proper Child/Sibling-isation (depending on what has been found)
- Fixed PCI information recognizing (changed structure + properly filling HardwareMechanism field)
- Creating of actual configuration descriptor for PCI bus added
- Fix conversion of hardware configuration list to virtual addressing, also adding better debug prints
- Remove annoying DbgPrints from PE loader
- Remove memory map dumping
----
Modified : /freeldr/arch/i386/hardware.c
Modified : /freeldr/arch/i386/hwpci.c
Modified : /freeldr/include/arch/i386/hardware.h
Modified : /freeldr/windows/conversion.c
Modified : /freeldr/windows/peloader.c
Modified : /freeldr/windows/winldr.c


Revision: 6
Author: alekseyb
Date: 1:42:20, 23 íîÿáðÿ 2006 ã.
Message:
- Add ISA bus configuration entry, Disk Controller and Peripherals
- Comment about number of GDT entries
- Changed order of boot drivers - now they should correspond to what NT awaits

The compatibility with ReactOS booting is broken at this point, because hardware detection results are being placed into configuration list and not in-memory registry.
----
Modified : /freeldr/arch/i386/hardware.c
Modified : /freeldr/include/winldr.h
Modified : /freeldr/windows/wlregistry.c


Revision: 5
Author: alekseyb
Date: 23:37:40, 18 íîÿáðÿ 2006 ã.
Message:
- Modify number of GDT descriptors, since NT Kernel assumes space for 128 GDT descriptors, and if it is less - it overwrites IDT entries following them, which lead to a major fsckup, and how kernel booted to some stage is a mystery.
- Slightly modified comments, removed unnecessary TODO

WinDBG connects now and seems to work (don't forget to disable debug output of freeldr, otherwise WinDBG can't connect).
----
Modified : /freeldr/include/winldr.h
Modified : /freeldr/windows/winldr.c


Revision: 4
Author: alekseyb
Date: 18:25:49, 16 íîÿáðÿ 2006 ã.
Message:
- Fix RegistryPath in boot drivers (appended service name)
- Convert RegistryPath.Buffer and pointer to DTE to VirtualAddresses (fixes KMODE_EXCEPTION)
----
Modified : /freeldr/windows/winldr.c
Modified : /freeldr/windows/wlregistry.c


Revision: 3
Author: alekseyb
Date: 17:10:21, 15 íîÿáðÿ 2006 ã.
Message:
- Implemented storing configuration data of disks.
- Moved hardware detection to a later stage so that it doesn't write to an unitialized pointer and actually stores the data in LoaderBlock->ConfigurationRoot.

InitializeHWConfig() function should go away soon.
----
Modified : /freeldr/arch/i386/hardware.c
Modified : /freeldr/windows/conversion.c
Modified : /freeldr/windows/winldr.c


Revision: 2
Author: alekseyb
Date: 16:54:12, 13 íîÿáðÿ 2006 ã.
Message:
Import of what has been already done so far by me (WinNT 4.0 says INACCESSIBLE_BOOT_DEVICE). Just started working on Configuration List.
----
Modified : /freeldr/arch/i386/hardware.c
Modified : /freeldr/arch/i386/i386idt.S
Modified : /freeldr/arch/i386/i386trap.S
Modified : /freeldr/arch/i386/xboxhw.c
Modified : /freeldr/debug.c
Modified : /freeldr/freeldr_arch.rbuild
Modified : /freeldr/freeldr_base.rbuild
Modified : /freeldr/freeldr_base64k.rbuild
Modified : /freeldr/freeldr_main.rbuild
Modified : /freeldr/include/arch/i386/machpc.h
Modified : /freeldr/include/arch/i386/machxbox.h
Modified : /freeldr/include/machine.h
Modified : /freeldr/include/mm.h
Modified : /freeldr/include/winldr.h
Modified : /freeldr/linuxboot.c
Modified : /freeldr/machine.c
Modified : /freeldr/mm/meminit.c
Modified : /freeldr/mm/mm.c
Modified : /freeldr/reactos/binhive.c
Modified : /freeldr/reactos/reactos.c
Modified : /freeldr/reactos/setupldr.c
Modified : /freeldr/windows/peloader.c
Modified : /freeldr/windows/winldr.c
Modified : /freeldr/windows/wlmemory.c
Modified : /freeldr/windows/wlregistry.c


Revision: 1
Author: alekseyb
Date: 16:45:55, 13 íîÿáðÿ 2006 ã.
Message:
FreeLdr import from ReactOS trunk r24725
----
Added : /freeldr
Added : /freeldr/CHANGELOG
Added : /freeldr/arch
Added : /freeldr/arch/i386
Added : /freeldr/arch/i386/_alloca.S
Added : /freeldr/arch/i386/arch.S
Added : /freeldr/arch/i386/archmach.c
Added : /freeldr/arch/i386/boot.S
Added : /freeldr/arch/i386/drvmap.S
Added : /freeldr/arch/i386/fathelp.asm
Added : /freeldr/arch/i386/hardware.c
Added : /freeldr/arch/i386/hwacpi.c
Added : /freeldr/arch/i386/hwapm.c
Added : /freeldr/arch/i386/hwcpu.c
Added : /freeldr/arch/i386/hwpci.c
Added : /freeldr/arch/i386/i386cpu.S
Added : /freeldr/arch/i386/i386disk.c
Added : /freeldr/arch/i386/i386idt.S
Added : /freeldr/arch/i386/i386pnp.S
Added : /freeldr/arch/i386/i386rtl.c
Added : /freeldr/arch/i386/i386trap.S
Added : /freeldr/arch/i386/i386vid.c
Added : /freeldr/arch/i386/int386.S
Added : /freeldr/arch/i386/linux.S
Added : /freeldr/arch/i386/loader.c
Added : /freeldr/arch/i386/machpc.c
Added : /freeldr/arch/i386/machxbox.c
Added : /freeldr/arch/i386/mb.S
Added : /freeldr/arch/i386/pccons.c
Added : /freeldr/arch/i386/pcdisk.c
Added : /freeldr/arch/i386/pcmem.c
Added : /freeldr/arch/i386/pcrtc.c
Added : /freeldr/arch/i386/pcvideo.c
Added : /freeldr/arch/i386/portio.c
Added : /freeldr/arch/i386/xboxcons.c
Added : /freeldr/arch/i386/xboxdisk.c
Added : /freeldr/arch/i386/xboxfont.c
Added : /freeldr/arch/i386/xboxhw.c
Added : /freeldr/arch/i386/xboxi2c.c
Added : /freeldr/arch/i386/xboxmem.c
Added : /freeldr/arch/i386/xboxrtc.c
Added : /freeldr/arch/i386/xboxvideo.c
Added : /freeldr/arch/powerpc
Added : /freeldr/arch/powerpc/boot.s
Added : /freeldr/arch/powerpc/mach.c
Added : /freeldr/arch/powerpc/mboot.c
Added : /freeldr/bootmgr.c
Added : /freeldr/cache
Added : /freeldr/cache/blocklist.c
Added : /freeldr/cache/cache.c
Added : /freeldr/cmdline.c
Added : /freeldr/comm
Added : /freeldr/comm/rs232.c
Added : /freeldr/custom.c
Added : /freeldr/debug.c
Added : /freeldr/disk
Added : /freeldr/disk/disk.c
Added : /freeldr/disk/partition.c
Added : /freeldr/drivemap.c
Added : /freeldr/freeldr.c
Added : /freeldr/freeldr.rbuild
Added : /freeldr/freeldr_arch.rbuild
Added : /freeldr/freeldr_base.rbuild
Added : /freeldr/freeldr_base64k.rbuild
Added : /freeldr/freeldr_main.rbuild
Added : /freeldr/freeldr_startup.rbuild
Added : /freeldr/fs
Added : /freeldr/fs/ext2.c
Added : /freeldr/fs/fat.c
Added : /freeldr/fs/fs.c
Added : /freeldr/fs/fsrec.c
Added : /freeldr/fs/iso.c
Added : /freeldr/fs/ntfs.c
Added : /freeldr/include
Added : /freeldr/include/arch
Added : /freeldr/include/arch/i386
Added : /freeldr/include/arch/i386/hardware.h
Added : /freeldr/include/arch/i386/i386.h
Added : /freeldr/include/arch/i386/machpc.h
Added : /freeldr/include/arch/i386/machxbox.h
Added : /freeldr/include/arch.h
Added : /freeldr/include/bootmgr.h
Added : /freeldr/include/cache.h
Added : /freeldr/include/cmdline.h
Added : /freeldr/include/comm.h
Added : /freeldr/include/debug.h
Added : /freeldr/include/disk.h
Added : /freeldr/include/drivemap.h
Added : /freeldr/include/freeldr.h
Added : /freeldr/include/fs
Added : /freeldr/include/fs/ext2.h
Added : /freeldr/include/fs/fat.h
Added : /freeldr/include/fs/iso.h
Added : /freeldr/include/fs/ntfs.h
Added : /freeldr/include/fs.h
Added : /freeldr/include/fsrec.h
Added : /freeldr/include/inffile.h
Added : /freeldr/include/inifile.h
Added : /freeldr/include/keycodes.h
Added : /freeldr/include/linux.h
Added : /freeldr/include/machine.h
Added : /freeldr/include/miscboot.h
Added : /freeldr/include/mm.h
Added : /freeldr/include/multiboot.h
Added : /freeldr/include/of.h
Added : /freeldr/include/options.h
Added : /freeldr/include/oslist.h
Added : /freeldr/include/portio.h
Added : /freeldr/include/reactos.h
Added : /freeldr/include/registry.h
Added : /freeldr/include/rtl.h
Added : /freeldr/include/ui
Added : /freeldr/include/ui/gui.h
Added : /freeldr/include/ui/tui.h
Added : /freeldr/include/ui.h
Added : /freeldr/include/ver.h
Added : /freeldr/include/video.h
Added : /freeldr/include/winldr.h
Added : /freeldr/inffile
Added : /freeldr/inffile/inffile.c
Added : /freeldr/inifile
Added : /freeldr/inifile/ini_init.c
Added : /freeldr/inifile/inifile.c
Added : /freeldr/inifile/parse.c
Added : /freeldr/linuxboot.c
Added : /freeldr/machine.c
Added : /freeldr/math
Added : /freeldr/math/i386.h
Added : /freeldr/math/libgcc2.c
Added : /freeldr/math/libgcc2.h
Added : /freeldr/math/longlong.h
Added : /freeldr/math/powerpc.h
Added : /freeldr/miscboot.c
Added : /freeldr/mm
Added : /freeldr/mm/meminit.c
Added : /freeldr/mm/mm.c
Added : /freeldr/options.c
Added : /freeldr/oslist.c
Added : /freeldr/reactos
Added : /freeldr/reactos/arcname.c
Added : /freeldr/reactos/binhive.c
Added : /freeldr/reactos/reactos.c
Added : /freeldr/reactos/registry.c
Added : /freeldr/reactos/setupldr.c
Added : /freeldr/rtl
Added : /freeldr/rtl/libsupp.c
Added : /freeldr/rtl/list.c
Added : /freeldr/setupldr.rbuild
Added : /freeldr/setupldr_main.rbuild
Added : /freeldr/ui
Added : /freeldr/ui/gui.c
Added : /freeldr/ui/tui.c
Added : /freeldr/ui/tuimenu.c
Added : /freeldr/ui/ui.c
Added : /freeldr/version.c
Added : /freeldr/video
Added : /freeldr/video/bank.c
Added : /freeldr/video/fade.c
Added : /freeldr/video/palette.c
Added : /freeldr/video/pixel.c
Added : /freeldr/video/video.c
Added : /freeldr/windows
Added : /freeldr/windows/conversion.c
Added : /freeldr/windows/peloader.c
Added : /freeldr/windows/winldr.c
Added : /freeldr/windows/wlmemory.c
Added : /freeldr/windows/wlregistry.c




svn path=/branches/winldr/; revision=25067
2006-12-04 22:08:02 +00:00

494 lines
13 KiB
C

/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
#define LINUX_READ_CHUNK_SIZE 0x20000 // Read 128k at a time
PLINUX_BOOTSECTOR LinuxBootSector = NULL;
PLINUX_SETUPSECTOR LinuxSetupSector = NULL;
ULONG SetupSectorSize = 0;
BOOLEAN NewStyleLinuxKernel = FALSE;
ULONG LinuxKernelSize = 0;
ULONG LinuxInitrdSize = 0;
CHAR LinuxKernelName[260];
CHAR LinuxInitrdName[260];
BOOLEAN LinuxHasInitrd = FALSE;
CHAR LinuxCommandLine[260] = "";
ULONG LinuxCommandLineSize = 0;
PVOID LinuxKernelLoadAddress = NULL;
PVOID LinuxInitrdLoadAddress = NULL;
CHAR LinuxBootDescription[80];
CHAR LinuxBootPath[260] = "";
VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description)
{
PFILE LinuxKernel = NULL;
PFILE LinuxInitrdFile = NULL;
CHAR TempString[260];
UiDrawBackdrop();
if (Description)
{
sprintf(LinuxBootDescription, "Loading %s...", Description);
}
else
{
strcpy(LinuxBootDescription, "Loading Linux...");
}
UiDrawStatusText(LinuxBootDescription);
UiDrawProgressBarCenter(0, 100, LinuxBootDescription);
// Parse the .ini file section
if (!LinuxParseIniSection(OperatingSystemName))
{
goto LinuxBootFailed;
}
// Open the boot volume
if (!MachDiskNormalizeSystemPath(LinuxBootPath, sizeof(LinuxBootPath)))
{
UiMessageBox("Invalid boot path");
goto LinuxBootFailed;
}
if (!FsOpenSystemVolume(LinuxBootPath, NULL, NULL))
{
UiMessageBox("Failed to open boot drive.");
goto LinuxBootFailed;
}
// Open the kernel
LinuxKernel = FsOpenFile(LinuxKernelName);
if (LinuxKernel == NULL)
{
sprintf(TempString, "Linux kernel \'%s\' not found.", LinuxKernelName);
UiMessageBox(TempString);
goto LinuxBootFailed;
}
// Open the initrd file image (if necessary)
if (LinuxHasInitrd)
{
LinuxInitrdFile = FsOpenFile(LinuxInitrdName);
if (LinuxInitrdFile == NULL)
{
sprintf(TempString, "Linux initrd image \'%s\' not found.", LinuxInitrdName);
UiMessageBox(TempString);
goto LinuxBootFailed;
}
}
// Read the boot sector
if (!LinuxReadBootSector(LinuxKernel))
{
goto LinuxBootFailed;
}
// Read the setup sector
if (!LinuxReadSetupSector(LinuxKernel))
{
goto LinuxBootFailed;
}
// Calc kernel size
LinuxKernelSize = FsGetFileSize(LinuxKernel) - (512 + SetupSectorSize);
// Get the file size
LinuxInitrdSize = FsGetFileSize(LinuxInitrdFile);
// Read the kernel
if (!LinuxReadKernel(LinuxKernel))
{
goto LinuxBootFailed;
}
// Read the initrd (if necessary)
if (LinuxHasInitrd)
{
if (!LinuxReadInitrd(LinuxInitrdFile))
{
goto LinuxBootFailed;
}
}
// If the default root device is set to FLOPPY (0000h), change to /dev/fd0 (0200h)
if (LinuxBootSector->RootDevice == 0x0000)
{
LinuxBootSector->RootDevice = 0x0200;
}
if (LinuxSetupSector->Version >= 0x0202)
{
LinuxSetupSector->CommandLinePointer = 0x99000;
}
else
{
LinuxBootSector->CommandLineMagic = LINUX_COMMAND_LINE_MAGIC;
LinuxBootSector->CommandLineOffset = 0x9000;
}
if (NewStyleLinuxKernel)
{
LinuxSetupSector->TypeOfLoader = LINUX_LOADER_TYPE_FREELOADER;
}
else
{
LinuxSetupSector->LoadFlags = 0;
}
RtlCopyMemory((PVOID)0x90000, LinuxBootSector, 512);
RtlCopyMemory((PVOID)0x90200, LinuxSetupSector, SetupSectorSize);
RtlCopyMemory((PVOID)0x99000, LinuxCommandLine, LinuxCommandLineSize);
UiUnInitialize("Booting Linux...");
DiskStopFloppyMotor();
if (LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
{
BootNewLinuxKernel();
}
else
{
BootOldLinuxKernel(LinuxKernelSize);
}
LinuxBootFailed:
if (LinuxKernel != NULL)
{
FsCloseFile(LinuxKernel);
}
if (LinuxInitrdFile != NULL)
{
FsCloseFile(LinuxInitrdFile);
}
if (LinuxBootSector != NULL)
{
MmFreeMemory(LinuxBootSector);
}
if (LinuxSetupSector != NULL)
{
MmFreeMemory(LinuxSetupSector);
}
if (LinuxKernelLoadAddress != NULL)
{
MmFreeMemory(LinuxKernelLoadAddress);
}
if (LinuxInitrdLoadAddress != NULL)
{
MmFreeMemory(LinuxInitrdLoadAddress);
}
LinuxBootSector = NULL;
LinuxSetupSector = NULL;
LinuxKernelLoadAddress = NULL;
LinuxInitrdLoadAddress = NULL;
SetupSectorSize = 0;
NewStyleLinuxKernel = FALSE;
LinuxKernelSize = 0;
LinuxHasInitrd = FALSE;
strcpy(LinuxCommandLine, "");
LinuxCommandLineSize = 0;
}
BOOLEAN LinuxParseIniSection(PCSTR OperatingSystemName)
{
CHAR SettingName[260];
ULONG SectionId;
// Find all the message box settings and run them
UiShowMessageBoxesInSection(OperatingSystemName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
UiMessageBox(SettingName);
return FALSE;
}
if (!IniReadSettingByName(SectionId, "BootPath", LinuxBootPath, sizeof(LinuxBootPath)))
{
UiMessageBox("Boot path not specified for selected OS!");
return FALSE;
}
// Get the kernel name
if (!IniReadSettingByName(SectionId, "Kernel", LinuxKernelName, sizeof(LinuxKernelName)))
{
UiMessageBox("Linux kernel filename not specified for selected OS!");
return FALSE;
}
// Get the initrd name
if (IniReadSettingByName(SectionId, "Initrd", LinuxInitrdName, sizeof(LinuxInitrdName)))
{
LinuxHasInitrd = TRUE;
}
// Get the command line
if (IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLine, sizeof(LinuxCommandLine)))
{
RemoveQuotes(LinuxCommandLine);
LinuxCommandLineSize = strlen(LinuxCommandLine) + 1;
}
return TRUE;
}
BOOLEAN LinuxReadBootSector(PFILE LinuxKernelFile)
{
// Allocate memory for boot sector
LinuxBootSector = (PLINUX_BOOTSECTOR)MmAllocateMemory(512);
if (LinuxBootSector == NULL)
{
return FALSE;
}
// Read linux boot sector
FsSetFilePointer(LinuxKernelFile, 0);
if (!FsReadFile(LinuxKernelFile, 512, NULL, LinuxBootSector))
{
return FALSE;
}
// Check for validity
if (LinuxBootSector->BootFlag != LINUX_BOOT_SECTOR_MAGIC)
{
UiMessageBox("Invalid boot sector magic (0xaa55)");
return FALSE;
}
DbgDumpBuffer(DPRINT_LINUX, LinuxBootSector, 512);
DbgPrint((DPRINT_LINUX, "SetupSectors: %d\n", LinuxBootSector->SetupSectors));
DbgPrint((DPRINT_LINUX, "RootFlags: 0x%x\n", LinuxBootSector->RootFlags));
DbgPrint((DPRINT_LINUX, "SystemSize: 0x%x\n", LinuxBootSector->SystemSize));
DbgPrint((DPRINT_LINUX, "SwapDevice: 0x%x\n", LinuxBootSector->SwapDevice));
DbgPrint((DPRINT_LINUX, "RamSize: 0x%x\n", LinuxBootSector->RamSize));
DbgPrint((DPRINT_LINUX, "VideoMode: 0x%x\n", LinuxBootSector->VideoMode));
DbgPrint((DPRINT_LINUX, "RootDevice: 0x%x\n", LinuxBootSector->RootDevice));
DbgPrint((DPRINT_LINUX, "BootFlag: 0x%x\n", LinuxBootSector->BootFlag));
return TRUE;
}
BOOLEAN LinuxReadSetupSector(PFILE LinuxKernelFile)
{
UCHAR TempLinuxSetupSector[512];
LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
// Read first linux setup sector
FsSetFilePointer(LinuxKernelFile, 512);
if (!FsReadFile(LinuxKernelFile, 512, NULL, TempLinuxSetupSector))
{
return FALSE;
}
// Check the kernel version
if (!LinuxCheckKernelVersion())
{
return FALSE;
}
if (NewStyleLinuxKernel)
{
SetupSectorSize = 512 * LinuxBootSector->SetupSectors;
}
else
{
SetupSectorSize = 4 * 512; // Always 4 setup sectors
}
// Allocate memory for setup sectors
LinuxSetupSector = (PLINUX_SETUPSECTOR)MmAllocateMemory(SetupSectorSize);
if (LinuxSetupSector == NULL)
{
return FALSE;
}
// Copy over first setup sector
RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512);
// Read in the rest of the linux setup sectors
FsSetFilePointer(LinuxKernelFile, 1024);
if (!FsReadFile(LinuxKernelFile, SetupSectorSize - 512, NULL, (PVOID)((ULONG_PTR)LinuxSetupSector + 512)))
{
return FALSE;
}
DbgDumpBuffer(DPRINT_LINUX, LinuxSetupSector, SetupSectorSize);
DbgPrint((DPRINT_LINUX, "SetupHeaderSignature: 0x%x (HdrS)\n", LinuxSetupSector->SetupHeaderSignature));
DbgPrint((DPRINT_LINUX, "Version: 0x%x\n", LinuxSetupSector->Version));
DbgPrint((DPRINT_LINUX, "RealModeSwitch: 0x%x\n", LinuxSetupSector->RealModeSwitch));
DbgPrint((DPRINT_LINUX, "SetupSeg: 0x%x\n", LinuxSetupSector->SetupSeg));
DbgPrint((DPRINT_LINUX, "StartSystemSeg: 0x%x\n", LinuxSetupSector->StartSystemSeg));
DbgPrint((DPRINT_LINUX, "KernelVersion: 0x%x\n", LinuxSetupSector->KernelVersion));
DbgPrint((DPRINT_LINUX, "TypeOfLoader: 0x%x\n", LinuxSetupSector->TypeOfLoader));
DbgPrint((DPRINT_LINUX, "LoadFlags: 0x%x\n", LinuxSetupSector->LoadFlags));
DbgPrint((DPRINT_LINUX, "SetupMoveSize: 0x%x\n", LinuxSetupSector->SetupMoveSize));
DbgPrint((DPRINT_LINUX, "Code32Start: 0x%x\n", LinuxSetupSector->Code32Start));
DbgPrint((DPRINT_LINUX, "RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress));
DbgPrint((DPRINT_LINUX, "RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize));
DbgPrint((DPRINT_LINUX, "BootSectKludgeOffset: 0x%x\n", LinuxSetupSector->BootSectKludgeOffset));
DbgPrint((DPRINT_LINUX, "BootSectKludgeSegment: 0x%x\n", LinuxSetupSector->BootSectKludgeSegment));
DbgPrint((DPRINT_LINUX, "HeapEnd: 0x%x\n", LinuxSetupSector->HeapEnd));
return TRUE;
}
BOOLEAN LinuxReadKernel(PFILE LinuxKernelFile)
{
ULONG BytesLoaded;
CHAR StatusText[260];
PVOID LoadAddress;
sprintf(StatusText, "Loading %s", LinuxKernelName);
UiDrawStatusText(StatusText);
// Allocate memory for Linux kernel
LinuxKernelLoadAddress = MmAllocateMemoryAtAddress(LinuxKernelSize, (PVOID)LINUX_KERNEL_LOAD_ADDRESS, LoaderSystemCode);
if (LinuxKernelLoadAddress != (PVOID)LINUX_KERNEL_LOAD_ADDRESS)
{
return FALSE;
}
LoadAddress = LinuxKernelLoadAddress;
// Read linux kernel to 0x100000 (1mb)
FsSetFilePointer(LinuxKernelFile, 512 + SetupSectorSize);
for (BytesLoaded=0; BytesLoaded<LinuxKernelSize; )
{
if (!FsReadFile(LinuxKernelFile, LINUX_READ_CHUNK_SIZE, NULL, LoadAddress))
{
return FALSE;
}
BytesLoaded += LINUX_READ_CHUNK_SIZE;
LoadAddress = (PVOID)((ULONG_PTR)LoadAddress + LINUX_READ_CHUNK_SIZE);
UiDrawProgressBarCenter(BytesLoaded, LinuxKernelSize + LinuxInitrdSize, LinuxBootDescription);
}
return TRUE;
}
BOOLEAN LinuxCheckKernelVersion(VOID)
{
// Just assume old kernel until we find otherwise
NewStyleLinuxKernel = FALSE;
// Check for new style setup header
if (LinuxSetupSector->SetupHeaderSignature != LINUX_SETUP_HEADER_ID)
{
NewStyleLinuxKernel = FALSE;
}
// Check for version below 2.0
else if (LinuxSetupSector->Version < 0x0200)
{
NewStyleLinuxKernel = FALSE;
}
// Check for version 2.0
else if (LinuxSetupSector->Version == 0x0200)
{
NewStyleLinuxKernel = TRUE;
}
// Check for version 2.01+
else if (LinuxSetupSector->Version >= 0x0201)
{
NewStyleLinuxKernel = TRUE;
LinuxSetupSector->HeapEnd = 0x9000;
LinuxSetupSector->LoadFlags |= LINUX_FLAG_CAN_USE_HEAP;
}
if ((NewStyleLinuxKernel == FALSE) && (LinuxHasInitrd == TRUE))
{
UiMessageBox("Error: Cannot load a ramdisk (initrd) with an old kernel image.");
return FALSE;
}
return TRUE;
}
BOOLEAN LinuxReadInitrd(PFILE LinuxInitrdFile)
{
ULONG BytesLoaded;
CHAR StatusText[260];
sprintf(StatusText, "Loading %s", LinuxInitrdName);
UiDrawStatusText(StatusText);
// Allocate memory for the ramdisk
//LinuxInitrdLoadAddress = MmAllocateMemory(LinuxInitrdSize);
// Try to align it at the next MB boundary after the kernel
//LinuxInitrdLoadAddress = MmAllocateMemoryAtAddress(LinuxInitrdSize, (PVOID)ROUND_UP((LINUX_KERNEL_LOAD_ADDRESS + LinuxKernelSize), 0x100000));
if (LinuxSetupSector->Version <= 0x0202)
{
LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LINUX_MAX_INITRD_ADDRESS, LoaderSystemCode);
}
else
{
LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LinuxSetupSector->InitrdAddressMax, LoaderSystemCode);
}
if (LinuxInitrdLoadAddress == NULL)
{
return FALSE;
}
// Set the information in the setup struct
LinuxSetupSector->RamdiskAddress = (ULONG)LinuxInitrdLoadAddress;
LinuxSetupSector->RamdiskSize = LinuxInitrdSize;
DbgPrint((DPRINT_LINUX, "RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress));
DbgPrint((DPRINT_LINUX, "RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize));
if (LinuxSetupSector->Version >= 0x0203)
{
DbgPrint((DPRINT_LINUX, "InitrdAddressMax: 0x%x\n", LinuxSetupSector->InitrdAddressMax));
}
// Read in the ramdisk
for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; )
{
if (!FsReadFile(LinuxInitrdFile, LINUX_READ_CHUNK_SIZE, NULL, (PVOID)LinuxInitrdLoadAddress))
{
return FALSE;
}
BytesLoaded += LINUX_READ_CHUNK_SIZE;
LinuxInitrdLoadAddress = (PVOID)((ULONG_PTR)LinuxInitrdLoadAddress + LINUX_READ_CHUNK_SIZE);
UiDrawProgressBarCenter(BytesLoaded + LinuxKernelSize, LinuxInitrdSize + LinuxKernelSize, LinuxBootDescription);
}
return TRUE;
}