mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
FreeLoader version 1.0!
Supports booting Linux bzImage kernels No initrd support (yet) No zImage support (yet) No ext2 file system support (yet) Forward slashes '/' as well as backslashes '\' can be used for path names in FAT & ISO-9660 Fixed bug in LBA code where is was only reading one sector even if you asked for more Fixed bug in FAT code, was also present in ISO-9660 code svn path=/trunk/; revision=2867
This commit is contained in:
parent
8c136a909a
commit
a9450f5a72
17 changed files with 499 additions and 114 deletions
|
@ -71,13 +71,13 @@
|
||||||
|
|
||||||
[FREELOADER]
|
[FREELOADER]
|
||||||
MessageLine=Welcome to FreeLoader!
|
MessageLine=Welcome to FreeLoader!
|
||||||
MessageLine=Copyright (c) 2001 by Brian Palmer <brianp@sginet.com>
|
MessageLine=Copyright (c) 2002 by Brian Palmer <brianp@sginet.com>
|
||||||
MessageLine=
|
MessageLine=
|
||||||
MessageBox=Edit your FREELDR.INI file to change your boot settings.
|
MessageBox=Edit your FREELDR.INI file to change your boot settings.
|
||||||
OS=ReactOS (HD)
|
OS=ReactOS (HD)
|
||||||
OS=ReactOS (Floppy)
|
OS=ReactOS (Floppy)
|
||||||
;OS=ReactOS (Debug)
|
;OS=ReactOS (Debug)
|
||||||
;OS=Linux
|
OS=Linux
|
||||||
OS=3« Floppy (A:)
|
OS=3« Floppy (A:)
|
||||||
OS=Microsoft Windows (C:)
|
OS=Microsoft Windows (C:)
|
||||||
OS=Drive D:
|
OS=Drive D:
|
||||||
|
@ -134,12 +134,12 @@ Driver=\reactos\VFATFS.SYS
|
||||||
;Driver=\DRIVERS\IDE.SYS
|
;Driver=\DRIVERS\IDE.SYS
|
||||||
;Driver=\DRIVERS\VFATFS.SYS
|
;Driver=\DRIVERS\VFATFS.SYS
|
||||||
|
|
||||||
;[Linux]
|
[Linux]
|
||||||
;Name="Linux"
|
Name="Debian Linux 2.2.17"
|
||||||
; Linux boot type not implemented yet
|
BootType=Partition
|
||||||
;BootType=Partition
|
BootDrive=0
|
||||||
;BootDrive=0x80
|
Kernel=/vmlinuz
|
||||||
;BootPartition=2
|
CommandLine=root=/dev/sdb1
|
||||||
|
|
||||||
[3« Floppy (A:)]
|
[3« Floppy (A:)]
|
||||||
Name="3« Floppy (A:)"
|
Name="3« Floppy (A:)"
|
||||||
|
|
|
@ -44,6 +44,6 @@ bin2c.exe: bin2c.c
|
||||||
$(CC) -o bin2c.exe bin2c.c
|
$(CC) -o bin2c.exe bin2c.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.bin
|
- $(RM) *.bin
|
||||||
$(RM) *.exe
|
- $(RM) *.exe
|
||||||
$(RM) *.h
|
- $(RM) *.h
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
cd bootsect
|
|
||||||
call make.bat
|
|
||||||
cd..
|
|
||||||
cd freeldr
|
|
||||||
make
|
|
||||||
copy freeldr.sys ..
|
|
||||||
cd ..
|
|
|
@ -33,6 +33,16 @@ EXTERN(_JumpToBootCode)
|
||||||
/* Set the boot drive */
|
/* Set the boot drive */
|
||||||
movb (_BootDrive),%dl
|
movb (_BootDrive),%dl
|
||||||
|
|
||||||
|
/* Load segment registers */
|
||||||
|
cli
|
||||||
|
movw $0x0000,%bx
|
||||||
|
movw %bx,%ds
|
||||||
|
movw %bx,%es
|
||||||
|
movw %bx,%fs
|
||||||
|
movw %bx,%gs
|
||||||
|
movw %bx,%ss
|
||||||
|
movw $0x7C00,%sp
|
||||||
|
|
||||||
ljmpl $0x0000,$0x7C00
|
ljmpl $0x0000,$0x7C00
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,4 +54,14 @@ EXTERN(_JumpToLinuxBootCode)
|
||||||
/* Set the boot drive */
|
/* Set the boot drive */
|
||||||
movb (_BootDrive),%dl
|
movb (_BootDrive),%dl
|
||||||
|
|
||||||
ljmpl $0x0200,$0x9000
|
/* Load segment registers */
|
||||||
|
cli
|
||||||
|
movw $0x9000,%bx
|
||||||
|
movw %bx,%ds
|
||||||
|
movw %bx,%es
|
||||||
|
movw %bx,%fs
|
||||||
|
movw %bx,%gs
|
||||||
|
movw %bx,%ss
|
||||||
|
movw $0x8FF4,%sp
|
||||||
|
|
||||||
|
ljmpl $0x9020,$0x0000
|
||||||
|
|
|
@ -25,9 +25,10 @@
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
//ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
|
//ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
|
||||||
// DPRINT_UI | DPRINT_DISK | DPRINT_CACHE;
|
// DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS |
|
||||||
ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
|
// DPRINT_LINUX;
|
||||||
DPRINT_UI | DPRINT_DISK;
|
ULONG DebugPrintMask = DPRINT_WARNING | /*DPRINT_FILESYSTEM |
|
||||||
|
DPRINT_CACHE |*/ DPRINT_LINUX;
|
||||||
//ULONG DebugPrintMask = DPRINT_INIFILE;
|
//ULONG DebugPrintMask = DPRINT_INIFILE;
|
||||||
|
|
||||||
#define SCREEN 0
|
#define SCREEN 0
|
||||||
|
@ -153,6 +154,26 @@ VOID DebugPrintHeader(ULONG Mask)
|
||||||
DebugPrintChar(':');
|
DebugPrintChar(':');
|
||||||
DebugPrintChar(' ');
|
DebugPrintChar(' ');
|
||||||
break;
|
break;
|
||||||
|
case DPRINT_REACTOS:
|
||||||
|
DebugPrintChar('R');
|
||||||
|
DebugPrintChar('E');
|
||||||
|
DebugPrintChar('A');
|
||||||
|
DebugPrintChar('C');
|
||||||
|
DebugPrintChar('T');
|
||||||
|
DebugPrintChar('O');
|
||||||
|
DebugPrintChar('S');
|
||||||
|
DebugPrintChar(':');
|
||||||
|
DebugPrintChar(' ');
|
||||||
|
break;
|
||||||
|
case DPRINT_LINUX:
|
||||||
|
DebugPrintChar('L');
|
||||||
|
DebugPrintChar('I');
|
||||||
|
DebugPrintChar('N');
|
||||||
|
DebugPrintChar('U');
|
||||||
|
DebugPrintChar('X');
|
||||||
|
DebugPrintChar(':');
|
||||||
|
DebugPrintChar(' ');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DebugPrintChar('U');
|
DebugPrintChar('U');
|
||||||
DebugPrintChar('N');
|
DebugPrintChar('N');
|
||||||
|
@ -235,4 +256,77 @@ VOID DebugPrint(ULONG Mask, char *format, ...)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length)
|
||||||
|
{
|
||||||
|
PUCHAR BufPtr = (PUCHAR)Buffer;
|
||||||
|
ULONG Idx;
|
||||||
|
ULONG Idx2;
|
||||||
|
|
||||||
|
// Mask out unwanted debug messages
|
||||||
|
if (!(Mask & DebugPrintMask))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugStartOfLine = FALSE; // We don't want line headers
|
||||||
|
DebugPrint(Mask, "Dumping buffer at 0x%x with length of %d bytes:\n", Buffer, Length);
|
||||||
|
|
||||||
|
for (Idx=0; Idx<Length; )
|
||||||
|
{
|
||||||
|
DebugStartOfLine = FALSE; // We don't want line headers
|
||||||
|
|
||||||
|
if (Idx < 0x0010)
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, "000%x:\t", Idx);
|
||||||
|
}
|
||||||
|
else if (Idx < 0x0100)
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, "00%x:\t", Idx);
|
||||||
|
}
|
||||||
|
else if (Idx < 0x1000)
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, "0%x:\t", Idx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, "%x:\t", Idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Idx2=0; Idx2<16; Idx2++,Idx++)
|
||||||
|
{
|
||||||
|
if (BufPtr[Idx] < 0x10)
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, "0");
|
||||||
|
}
|
||||||
|
DebugPrint(Mask, "%x", BufPtr[Idx]);
|
||||||
|
|
||||||
|
if (Idx2 == 7)
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, "-");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Idx -= 16;
|
||||||
|
DebugPrint(Mask, " ");
|
||||||
|
|
||||||
|
for (Idx2=0; Idx2<16; Idx2++,Idx++)
|
||||||
|
{
|
||||||
|
if ((BufPtr[Idx] > 20) && (BufPtr[Idx] < 0x80))
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, "%c", BufPtr[Idx]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugPrint(Mask, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugPrint(Mask, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // defined DEBUG
|
#endif // defined DEBUG
|
||||||
|
|
|
@ -30,17 +30,22 @@
|
||||||
#define DPRINT_UI 0x00000010 // OR this with DebugPrintMask to enable user interface messages
|
#define DPRINT_UI 0x00000010 // OR this with DebugPrintMask to enable user interface messages
|
||||||
#define DPRINT_DISK 0x00000020 // OR this with DebugPrintMask to enable disk messages
|
#define DPRINT_DISK 0x00000020 // OR this with DebugPrintMask to enable disk messages
|
||||||
#define DPRINT_CACHE 0x00000040 // OR this with DebugPrintMask to enable cache messages
|
#define DPRINT_CACHE 0x00000040 // OR this with DebugPrintMask to enable cache messages
|
||||||
|
#define DPRINT_REACTOS 0x00000080 // OR this with DebugPrintMask to enable ReactOS messages
|
||||||
|
#define DPRINT_LINUX 0x00000100 // OR this with DebugPrintMask to enable Linux messages
|
||||||
|
|
||||||
VOID DebugInit(VOID);
|
VOID DebugInit(VOID);
|
||||||
VOID DebugPrint(ULONG Mask, char *format, ...);
|
VOID DebugPrint(ULONG Mask, char *format, ...);
|
||||||
|
VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length);
|
||||||
|
|
||||||
#define DbgPrint(_x_) DebugPrint _x_
|
#define DbgPrint(_x_) DebugPrint _x_
|
||||||
#define BugCheck(_x_) { DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); DebugPrint _x_ ; for (;;); }
|
#define BugCheck(_x_) { DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); DebugPrint _x_ ; for (;;); }
|
||||||
|
#define DbgDumpBuffer(_x_, _y_, _z_) DebugDumpBuffer(_x_, _y_, _z_)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define DbgPrint(_x_)
|
#define DbgPrint(_x_)
|
||||||
#define BugCheck(_x_)
|
#define BugCheck(_x_)
|
||||||
|
#define DbgDumpBuffer(_x_, _y_, _z_)
|
||||||
|
|
||||||
#endif // defined DEBUG
|
#endif // defined DEBUG
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorC
|
||||||
// LBA is easy, nothing to calculate
|
// LBA is easy, nothing to calculate
|
||||||
// Just do the read
|
// Just do the read
|
||||||
//
|
//
|
||||||
if (!BiosInt13ReadExtended(DriveNumber, SectorNumber, 1, Buffer))
|
if (!BiosInt13ReadExtended(DriveNumber, SectorNumber, SectorCount, Buffer))
|
||||||
{
|
{
|
||||||
DiskError("Disk read error.");
|
DiskError("Disk read error.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -43,7 +43,7 @@ BOOL DiskIsDriveRemovable(ULONG DriveNumber)
|
||||||
|
|
||||||
BOOL DiskIsDriveCdRom(ULONG DriveNumber)
|
BOOL DiskIsDriveCdRom(ULONG DriveNumber)
|
||||||
{
|
{
|
||||||
PUCHAR Sector;
|
PUCHAR Sector = (PUCHAR)DISKREADBUFFER;
|
||||||
BOOL Result;
|
BOOL Result;
|
||||||
|
|
||||||
// Hard disks use drive numbers >= 0x80
|
// Hard disks use drive numbers >= 0x80
|
||||||
|
@ -51,7 +51,6 @@ BOOL DiskIsDriveCdRom(ULONG DriveNumber)
|
||||||
// then return FALSE
|
// then return FALSE
|
||||||
if ((DriveNumber >= 0x80) && (BiosInt13ExtensionsSupported(DriveNumber)))
|
if ((DriveNumber >= 0x80) && (BiosInt13ExtensionsSupported(DriveNumber)))
|
||||||
{
|
{
|
||||||
Sector = AllocateMemory(2048);
|
|
||||||
|
|
||||||
if (!BiosInt13ReadExtended(DriveNumber, 16, 1, Sector))
|
if (!BiosInt13ReadExtended(DriveNumber, 16, 1, Sector))
|
||||||
{
|
{
|
||||||
|
@ -67,8 +66,6 @@ BOOL DiskIsDriveCdRom(ULONG DriveNumber)
|
||||||
Sector[4] == '0' &&
|
Sector[4] == '0' &&
|
||||||
Sector[5] == '1');
|
Sector[5] == '1');
|
||||||
|
|
||||||
FreeMemory(Sector);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ VOID BootMain(VOID)
|
||||||
}
|
}
|
||||||
else if (stricmp(SettingValue, "Linux") == 0)
|
else if (stricmp(SettingValue, "Linux") == 0)
|
||||||
{
|
{
|
||||||
MessageBox("Cannot boot this OS type yet!");
|
LoadAndBootLinux(OperatingSystemSectionNames[SelectedOperatingSystem]);
|
||||||
}
|
}
|
||||||
else if (stricmp(SettingValue, "BootSector") == 0)
|
else if (stricmp(SettingValue, "BootSector") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
|
|
||||||
|
|
||||||
/* just some stuff */
|
/* just some stuff */
|
||||||
#define VERSION "FreeLoader v0.9"
|
#define VERSION "FreeLoader v1.0"
|
||||||
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
|
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
|
||||||
|
|
||||||
#define ROSLDR_MAJOR_VERSION 0
|
#define ROSLDR_MAJOR_VERSION 1
|
||||||
#define ROSLDR_MINOR_VERSION 8
|
#define ROSLDR_MINOR_VERSION 0
|
||||||
#define ROSLDR_PATCH_VERSION 0
|
#define ROSLDR_PATCH_VERSION 0
|
||||||
|
|
||||||
#define size_t unsigned int
|
#define size_t unsigned int
|
||||||
|
|
|
@ -576,9 +576,9 @@ BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
|
||||||
memset(FatFileInfoPointer, 0, sizeof(FAT_FILE_INFO));
|
memset(FatFileInfoPointer, 0, sizeof(FAT_FILE_INFO));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check and see if the first character is '\' and remove it if so
|
// Check and see if the first character is '\' or '/' and remove it if so
|
||||||
//
|
//
|
||||||
while (*FileName == '\\')
|
while ((*FileName == '\\') || (*FileName == '/'))
|
||||||
{
|
{
|
||||||
FileName++;
|
FileName++;
|
||||||
}
|
}
|
||||||
|
@ -601,7 +601,7 @@ BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
|
||||||
//
|
//
|
||||||
// Advance to the next part of the path
|
// Advance to the next part of the path
|
||||||
//
|
//
|
||||||
for (; (*FileName != '\\') && (*FileName != '\0'); FileName++)
|
for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
FileName++;
|
FileName++;
|
||||||
|
@ -654,7 +654,7 @@ ULONG FatGetNumPathParts(PUCHAR Path)
|
||||||
|
|
||||||
for (i=0,num=0; i<(int)strlen(Path); i++)
|
for (i=0,num=0; i<(int)strlen(Path); i++)
|
||||||
{
|
{
|
||||||
if (Path[i] == '\\')
|
if ((Path[i] == '\\') || (Path[i] == '/'))
|
||||||
{
|
{
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
@ -681,7 +681,7 @@ VOID FatGetFirstNameFromPath(PUCHAR Buffer, PUCHAR Path)
|
||||||
// and put them in Buffer
|
// and put them in Buffer
|
||||||
for (i=0; i<(int)strlen(Path); i++)
|
for (i=0; i<(int)strlen(Path); i++)
|
||||||
{
|
{
|
||||||
if (Path[i] == '\\')
|
if ((Path[i] == '\\') || (Path[i] == '/'))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1217,8 +1217,8 @@ BOOL FatReadFile(FILE *FileHandle, ULONG BytesToRead, PULONG BytesRead, PVOID Bu
|
||||||
{
|
{
|
||||||
*BytesRead += BytesToRead;
|
*BytesRead += BytesToRead;
|
||||||
}
|
}
|
||||||
BytesToRead -= BytesToRead;
|
|
||||||
FatFileInfo->FilePointer += BytesToRead;
|
FatFileInfo->FilePointer += BytesToRead;
|
||||||
|
BytesToRead -= BytesToRead;
|
||||||
Buffer += BytesToRead;
|
Buffer += BytesToRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ static ULONG IsoGetNumPathParts(PUCHAR Path)
|
||||||
|
|
||||||
for (i=0,num=0; i<(int)strlen(Path); i++)
|
for (i=0,num=0; i<(int)strlen(Path); i++)
|
||||||
{
|
{
|
||||||
if (Path[i] == '\\')
|
if ((Path[i] == '\\') || (Path[i] == '/'))
|
||||||
{
|
{
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ static VOID IsoGetFirstNameFromPath(PUCHAR Buffer, PUCHAR Path)
|
||||||
// and put them in Buffer
|
// and put them in Buffer
|
||||||
for (i=0; i<(int)strlen(Path); i++)
|
for (i=0; i<(int)strlen(Path); i++)
|
||||||
{
|
{
|
||||||
if (Path[i] == '\\')
|
if ((Path[i] == '\\') || (Path[i] == '/'))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ static BOOL IsoLookupFile(PUCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
|
||||||
//
|
//
|
||||||
// Check and see if the first character is '\' and remove it if so
|
// Check and see if the first character is '\' and remove it if so
|
||||||
//
|
//
|
||||||
while (*FileName == '\\')
|
while ((*FileName == '\\') || (*FileName == '/'))
|
||||||
{
|
{
|
||||||
FileName++;
|
FileName++;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,7 @@ static BOOL IsoLookupFile(PUCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
|
||||||
//
|
//
|
||||||
// Advance to the next part of the path
|
// Advance to the next part of the path
|
||||||
//
|
//
|
||||||
for (; (*FileName != '\\') && (*FileName != '\0'); FileName++)
|
for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
FileName++;
|
FileName++;
|
||||||
|
@ -535,8 +535,8 @@ BOOL IsoReadFile(FILE *FileHandle, ULONG BytesToRead, PULONG BytesRead, PVOID Bu
|
||||||
{
|
{
|
||||||
*BytesRead += BytesToRead;
|
*BytesRead += BytesToRead;
|
||||||
}
|
}
|
||||||
BytesToRead -= BytesToRead;
|
|
||||||
IsoFileInfo->FilePointer += BytesToRead;
|
IsoFileInfo->FilePointer += BytesToRead;
|
||||||
|
BytesToRead -= BytesToRead;
|
||||||
Buffer += BytesToRead;
|
Buffer += BytesToRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,77 +25,273 @@
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "linux.h"
|
#include "linux.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "mm.h"
|
||||||
|
#include "inifile.h"
|
||||||
|
|
||||||
void LoadAndBootLinux(int DriveNum, int Partition, char *vmlinuz, char *cmd_line)
|
PLINUX_BOOTSECTOR LinuxBootSector = NULL;
|
||||||
|
PLINUX_SETUPSECTOR LinuxSetupSector = NULL;
|
||||||
|
ULONG SetupSectorSize = 0;
|
||||||
|
BOOL BigZImageKernel = TRUE;
|
||||||
|
ULONG LinuxKernelSize = 0;
|
||||||
|
UCHAR LinuxKernelName[260];
|
||||||
|
UCHAR LinuxInitrdName[260];
|
||||||
|
BOOL LinuxHasInitrd = FALSE;
|
||||||
|
UCHAR LinuxCommandLine[260] = "";
|
||||||
|
ULONG LinuxCommandLineSize = 0;
|
||||||
|
|
||||||
|
VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
|
||||||
{
|
{
|
||||||
/*FILE file;
|
PFILE LinuxKernel = NULL;
|
||||||
char temp[260];
|
UCHAR TempString[260];
|
||||||
char bootsector[512];
|
|
||||||
char setup[2048];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
BootDrive = DriveNum;
|
DrawBackdrop();
|
||||||
BootPartition = Partition;
|
|
||||||
|
|
||||||
|
// Parse the .ini file section
|
||||||
|
if (!LinuxParseIniSection(OperatingSystemName))
|
||||||
|
{
|
||||||
|
goto LinuxBootFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the boot volume
|
||||||
if (!OpenDiskDrive(BootDrive, BootPartition))
|
if (!OpenDiskDrive(BootDrive, BootPartition))
|
||||||
{
|
{
|
||||||
MessageBox("Failed to open boot drive.");
|
MessageBox("Failed to open boot drive.");
|
||||||
return;
|
goto LinuxBootFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!OpenFile(vmlinuz, &file))
|
// Open the kernel
|
||||||
|
LinuxKernel = OpenFile(LinuxKernelName);
|
||||||
|
if (LinuxKernel == NULL)
|
||||||
{
|
{
|
||||||
strcpy(temp, vmlinuz);
|
sprintf(TempString, "Linux kernel \'%s\' not found.", LinuxKernelName);
|
||||||
strcat(temp, " not found.");
|
MessageBox(TempString);
|
||||||
MessageBox(temp);
|
goto LinuxBootFailed;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read boot sector
|
// Read the boot sector
|
||||||
if (ReadFile(&file, 512, bootsector) != 512)
|
if (!LinuxReadBootSector(LinuxKernel))
|
||||||
{
|
{
|
||||||
MessageBox("Disk Read Error");
|
goto LinuxBootFailed;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
MessageBox("bootsector loaded");
|
|
||||||
|
|
||||||
// Read setup code
|
// Read the setup sector
|
||||||
if (ReadFile(&file, 2048, setup) != 2048)
|
if (!LinuxReadSetupSector(LinuxKernel))
|
||||||
{
|
{
|
||||||
MessageBox("Disk Read Error");
|
goto LinuxBootFailed;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
MessageBox("setup loaded");
|
|
||||||
|
|
||||||
// Read kernel code
|
// Read the kernel
|
||||||
len = GetFileSize(&file) - (2048 + 512);
|
if (!LinuxReadKernel(LinuxKernel))
|
||||||
//len = 0x200;
|
|
||||||
if (ReadFile(&file, len, (void*)0x100000) != len)
|
|
||||||
{
|
{
|
||||||
MessageBox("Disk Read Error");
|
goto LinuxBootFailed;
|
||||||
return;
|
|
||||||
}
|
|
||||||
MessageBox("kernel loaded");
|
|
||||||
|
|
||||||
// Check for validity
|
|
||||||
if (*((WORD*)(bootsector + 0x1fe)) != 0xaa55)
|
|
||||||
{
|
|
||||||
MessageBox("Invalid boot sector magic (0xaa55)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (*((DWORD*)(setup + 2)) != 0x53726448)
|
|
||||||
{
|
|
||||||
MessageBox("Invalid setup magic (\"HdrS\")");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy((void*)0x90000, bootsector, 512);
|
LinuxBootSector->CommandLineMagic = LINUX_COMMAND_LINE_MAGIC;
|
||||||
memcpy((void*)0x90200, setup, 2048);
|
LinuxBootSector->CommandLineOffset = 0x9000;
|
||||||
|
|
||||||
|
LinuxSetupSector->TypeOfLoader = LINUX_LOADER_TYPE_FREELOADER;
|
||||||
|
|
||||||
|
RtlCopyMemory((PVOID)0x90000, LinuxBootSector, 512);
|
||||||
|
RtlCopyMemory((PVOID)0x90200, LinuxSetupSector, SetupSectorSize);
|
||||||
|
RtlCopyMemory((PVOID)0x99000, LinuxCommandLine, LinuxCommandLineSize);
|
||||||
|
|
||||||
RestoreScreen(ScreenBuffer);
|
|
||||||
showcursor();
|
showcursor();
|
||||||
gotoxy(CursorXPos, CursorYPos);
|
clrscr();
|
||||||
|
|
||||||
stop_floppy();
|
stop_floppy();
|
||||||
JumpToLinuxBootCode();*/
|
JumpToLinuxBootCode();
|
||||||
|
|
||||||
|
|
||||||
|
LinuxBootFailed:
|
||||||
|
|
||||||
|
if (LinuxKernel != NULL)
|
||||||
|
{
|
||||||
|
CloseFile(LinuxKernel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LinuxBootSector != NULL)
|
||||||
|
{
|
||||||
|
FreeMemory(LinuxBootSector);
|
||||||
|
}
|
||||||
|
if (LinuxSetupSector != NULL)
|
||||||
|
{
|
||||||
|
FreeMemory(LinuxSetupSector);
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxBootSector = NULL;
|
||||||
|
LinuxSetupSector = NULL;
|
||||||
|
SetupSectorSize = 0;
|
||||||
|
BigZImageKernel = TRUE;
|
||||||
|
LinuxKernelSize = 0;
|
||||||
|
LinuxHasInitrd = FALSE;
|
||||||
|
strcpy(LinuxCommandLine, "");
|
||||||
|
LinuxCommandLineSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LinuxParseIniSection(PUCHAR OperatingSystemName)
|
||||||
|
{
|
||||||
|
UCHAR SettingName[260];
|
||||||
|
UCHAR SettingValue[260];
|
||||||
|
ULONG SectionId;
|
||||||
|
|
||||||
|
// Find all the message box settings and run them
|
||||||
|
ShowMessageBoxesInSection(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);
|
||||||
|
MessageBox(SettingName);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue, 260))
|
||||||
|
{
|
||||||
|
MessageBox("Boot drive not specified for selected OS!");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BootDrive = atoi(SettingValue);
|
||||||
|
|
||||||
|
BootPartition = 0;
|
||||||
|
if (IniReadSettingByName(SectionId, "BootPartition", SettingValue, 260))
|
||||||
|
{
|
||||||
|
BootPartition = atoi(SettingValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the kernel name
|
||||||
|
if (!IniReadSettingByName(SectionId, "Kernel", LinuxKernelName, 260))
|
||||||
|
{
|
||||||
|
MessageBox("Linux kernel filename not specified for selected OS!");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the initrd name
|
||||||
|
if (IniReadSettingByName(SectionId, "Initrd", LinuxInitrdName, 260))
|
||||||
|
{
|
||||||
|
LinuxHasInitrd = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the command line
|
||||||
|
if (IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLine, 260))
|
||||||
|
{
|
||||||
|
LinuxCommandLineSize = strlen(LinuxCommandLine) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LinuxReadBootSector(PFILE LinuxKernelFile)
|
||||||
|
{
|
||||||
|
// Allocate memory for boot sector
|
||||||
|
LinuxBootSector = (PLINUX_BOOTSECTOR)AllocateMemory(512);
|
||||||
|
if (LinuxBootSector == NULL)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read linux boot sector
|
||||||
|
SetFilePointer(LinuxKernelFile, 0);
|
||||||
|
if (!ReadFile(LinuxKernelFile, 512, NULL, LinuxBootSector))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for validity
|
||||||
|
if (LinuxBootSector->BootFlag != LINUX_BOOT_SECTOR_MAGIC)
|
||||||
|
{
|
||||||
|
MessageBox("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;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LinuxReadSetupSector(PFILE LinuxKernelFile)
|
||||||
|
{
|
||||||
|
SetupSectorSize = 512 * LinuxBootSector->SetupSectors;
|
||||||
|
|
||||||
|
// Allocate memory for setup sectors
|
||||||
|
LinuxSetupSector = (PLINUX_SETUPSECTOR)AllocateMemory(SetupSectorSize);
|
||||||
|
if (LinuxSetupSector == NULL)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read linux setup sectors
|
||||||
|
SetFilePointer(LinuxKernelFile, 512);
|
||||||
|
if (!ReadFile(LinuxKernelFile, SetupSectorSize, NULL, LinuxSetupSector))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for validity
|
||||||
|
if (LinuxSetupSector->SetupHeaderSignature != LINUX_SETUP_HEADER_ID)
|
||||||
|
{
|
||||||
|
MessageBox("Invalid setup magic (HdrS)");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LinuxReadKernel(PFILE LinuxKernelFile)
|
||||||
|
{
|
||||||
|
PVOID LoadAddress = (PVOID)LINUX_KERNEL_LOAD_ADDRESS;
|
||||||
|
ULONG BytesLoaded;
|
||||||
|
UCHAR StatusText[260];
|
||||||
|
|
||||||
|
sprintf(StatusText, " Loading %s", LinuxKernelName);
|
||||||
|
DrawStatusText(StatusText);
|
||||||
|
DrawProgressBar(0);
|
||||||
|
|
||||||
|
// Calc kernel size
|
||||||
|
LinuxKernelSize = GetFileSize(LinuxKernelFile) - (512 + SetupSectorSize);
|
||||||
|
|
||||||
|
// Read linux kernel to 0x100000 (1mb)
|
||||||
|
SetFilePointer(LinuxKernelFile, 512 + SetupSectorSize);
|
||||||
|
for (BytesLoaded=0; BytesLoaded<LinuxKernelSize; )
|
||||||
|
{
|
||||||
|
if (!ReadFile(LinuxKernelFile, 0x4000, NULL, LoadAddress))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BytesLoaded += 0x4000;
|
||||||
|
LoadAddress += 0x4000;
|
||||||
|
|
||||||
|
DrawProgressBar( (BytesLoaded * 100) / LinuxKernelSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,107 @@
|
||||||
#ifndef __LINUX_H
|
#ifndef __LINUX_H
|
||||||
#define __LINUX_H
|
#define __LINUX_H
|
||||||
|
|
||||||
|
|
||||||
|
#define LINUX_LOADER_TYPE_LILO 0x01
|
||||||
|
#define LINUX_LOADER_TYPE_LOADLIN 0x11
|
||||||
|
#define LINUX_LOADER_TYPE_BOOTSECT 0x21
|
||||||
|
#define LINUX_LOADER_TYPE_SYSLINUX 0x31
|
||||||
|
#define LINUX_LOADER_TYPE_ETHERBOOT 0x41
|
||||||
|
#define LINUX_LOADER_TYPE_FREELOADER 0x81
|
||||||
|
|
||||||
|
#define LINUX_COMMAND_LINE_MAGIC 0xA33F
|
||||||
|
|
||||||
|
#define LINUX_SETUP_HEADER_ID 0x53726448 // 'HdrS'
|
||||||
|
|
||||||
|
#define LINUX_BOOT_SECTOR_MAGIC 0xAA55
|
||||||
|
|
||||||
|
#define LINUX_KERNEL_LOAD_ADDRESS 0x100000
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BYTE BootCode1[0x20];
|
||||||
|
|
||||||
|
WORD CommandLineMagic;
|
||||||
|
WORD CommandLineOffset;
|
||||||
|
|
||||||
|
BYTE BootCode2[0x1CD];
|
||||||
|
|
||||||
|
BYTE SetupSectors;
|
||||||
|
WORD RootFlags;
|
||||||
|
WORD SystemSize;
|
||||||
|
WORD SwapDevice;
|
||||||
|
WORD RamSize;
|
||||||
|
WORD VideoMode;
|
||||||
|
WORD RootDevice;
|
||||||
|
WORD BootFlag; // 0xAA55
|
||||||
|
|
||||||
|
} PACKED LINUX_BOOTSECTOR, *PLINUX_BOOTSECTOR;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BYTE JumpInstruction[2];
|
||||||
|
DWORD SetupHeaderSignature; // Signature for SETUP-header
|
||||||
|
WORD Version; // Version number of header format
|
||||||
|
WORD RealModeSwitch; // Default switch
|
||||||
|
WORD SetupSeg; // SETUPSEG
|
||||||
|
WORD StartSystemSeg;
|
||||||
|
WORD KernelVersion; // Offset to kernel version string
|
||||||
|
BYTE TypeOfLoader; // Loader ID
|
||||||
|
// =0, old one (LILO, Loadlin,
|
||||||
|
// Bootlin, SYSLX, bootsect...)
|
||||||
|
// else it is set by the loader:
|
||||||
|
// 0xTV: T=0 for LILO
|
||||||
|
// T=1 for Loadlin
|
||||||
|
// T=2 for bootsect-loader
|
||||||
|
// T=3 for SYSLX
|
||||||
|
// T=4 for ETHERBOOT
|
||||||
|
// V = version
|
||||||
|
|
||||||
|
BYTE LoadFlags; // flags, unused bits must be zero (RFU)
|
||||||
|
// LOADED_HIGH = 1
|
||||||
|
// bit within loadflags,
|
||||||
|
// if set, then the kernel is loaded high
|
||||||
|
// CAN_USE_HEAP = 0x80
|
||||||
|
// if set, the loader also has set heap_end_ptr
|
||||||
|
// to tell how much space behind setup.S
|
||||||
|
// can be used for heap purposes.
|
||||||
|
// Only the loader knows what is free!
|
||||||
|
|
||||||
|
WORD SetupMoveSize; // size to move, when we (setup) are not
|
||||||
|
// loaded at 0x90000. We will move ourselves
|
||||||
|
// to 0x90000 then just before jumping into
|
||||||
|
// the kernel. However, only the loader
|
||||||
|
// know how much of data behind us also needs
|
||||||
|
// to be loaded.
|
||||||
|
|
||||||
|
DWORD Code32Start; // here loaders can put a different
|
||||||
|
// start address for 32-bit code.
|
||||||
|
//
|
||||||
|
// 0x1000 = default for zImage
|
||||||
|
//
|
||||||
|
// 0x100000 = default for big kernel
|
||||||
|
|
||||||
|
DWORD RamdiskAddress; // address of loaded ramdisk image
|
||||||
|
// Here the loader (or kernel generator) puts
|
||||||
|
// the 32-bit address were it loaded the image.
|
||||||
|
DWORD RamdiskSize; // its size in bytes
|
||||||
|
|
||||||
|
WORD BootSectKludgeOffset;
|
||||||
|
WORD BootSectKludgeSegment;
|
||||||
|
WORD HeapEnd; // space from here (exclusive) down to
|
||||||
|
// end of setup code can be used by setup
|
||||||
|
// for local heap purposes.
|
||||||
|
|
||||||
|
|
||||||
|
} PACKED LINUX_SETUPSECTOR, *PLINUX_SETUPSECTOR;
|
||||||
|
|
||||||
void JumpToLinuxBootCode(void); // Implemented in boot.S
|
void JumpToLinuxBootCode(void); // Implemented in boot.S
|
||||||
|
|
||||||
void LoadAndBootLinux(int DriveNum, int Partition, char *vmlinuz, char *cmd_line);
|
VOID LoadAndBootLinux(PUCHAR OperatingSystemName);
|
||||||
|
|
||||||
|
BOOL LinuxParseIniSection(PUCHAR OperatingSystemName);
|
||||||
|
BOOL LinuxReadBootSector(PFILE LinuxKernelFile);
|
||||||
|
BOOL LinuxReadSetupSector(PFILE LinuxKernelFile);
|
||||||
|
BOOL LinuxReadKernel(PFILE LinuxKernelFile);
|
||||||
|
|
||||||
#endif // defined __LINUX_H
|
#endif // defined __LINUX_H
|
||||||
|
|
|
@ -45,6 +45,7 @@ PVOID AllocateMemory(ULONG NumberOfBytes)
|
||||||
if (NumberOfBytes == 0)
|
if (NumberOfBytes == 0)
|
||||||
{
|
{
|
||||||
DbgPrint((DPRINT_MEMORY, "AllocateMemory() called for 0 bytes. Returning NULL.\n"));
|
DbgPrint((DPRINT_MEMORY, "AllocateMemory() called for 0 bytes. Returning NULL.\n"));
|
||||||
|
MessageBox("Memory allocation failed: AllocateMemory() called for 0 bytes.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
cd bootsect
|
|
||||||
call install.bat
|
|
||||||
cd..
|
|
||||||
copy freeldr.sys a:\FREELDR.SYS
|
|
||||||
copy freeldr.ini a:\FREELDR.INI
|
|
|
@ -1,25 +1,10 @@
|
||||||
FreeLoader notes
|
FreeLoader notes
|
||||||
|
|
||||||
To build FreeLoader you will need DJGPP because Mingw32 doesn't support 16-bit code
|
To build FreeLoader you will need DJGPP because Mingw32 doesn't support 16-bit code
|
||||||
FreeLoader does not currently work with extended partitions.
|
|
||||||
Linux booting support needs to be added.
|
|
||||||
ext2 filesystem support needs to be added.
|
ext2 filesystem support needs to be added.
|
||||||
The MessageBox() function needs to not allocate memory. Because it gets called when memory allocation fails.
|
The MessageBox() function needs to not allocate memory. Because it gets called when memory allocation fails.
|
||||||
|
|
||||||
Old memory layout:
|
Memory layout:
|
||||||
|
|
||||||
0000:0000 - 0000:0FFF: Interrupt vector table & BIOS data
|
|
||||||
0000:1000 - 0000:6FFF: Real mode stack area
|
|
||||||
0000:7000 - xxxx:xxxx: FreeLoader program & data area
|
|
||||||
xxxx:xxxx - 6000:0000: Protected mode stack area & heap
|
|
||||||
6000:0000 - 6000:C000: Filesystem data buffer
|
|
||||||
6000:C000 - 7000:0000: FREELDR.INI loaded here
|
|
||||||
7000:0000 - 7000:FFFF: scratch area for any function's use (ie sector buffer for biosdisk()) - can be overwritten by any function
|
|
||||||
8000:0000 - 9000:FFFF: fat table entry buffer
|
|
||||||
A000:0000 - FFFF:FFFF: reserved
|
|
||||||
|
|
||||||
|
|
||||||
New memory layout:
|
|
||||||
|
|
||||||
0000:0000 - 0000:0FFF: Interrupt vector table & BIOS data
|
0000:0000 - 0000:0FFF: Interrupt vector table & BIOS data
|
||||||
0000:1000 - 0000:6FFF: Real mode stack area
|
0000:1000 - 0000:6FFF: Real mode stack area
|
||||||
|
|
Loading…
Reference in a new issue