Changes in v1.2 (4/30/2002)

- All Linux kernels are supported (zImage & bzImage, loaded high & low)
- Initrd support
- FreeLoader now compiles under Mingw32 instead of just DJGPP, but
  the Mingw32 linker seems to output a corrupt binary.

svn path=/trunk/; revision=2899
This commit is contained in:
Brian Palmer 2002-04-30 06:26:33 +00:00
parent b5d501b385
commit 467e8c55cc
16 changed files with 383 additions and 59 deletions

View file

@ -1,3 +1,10 @@
Changes in v1.2 (4/30/2002)
- All Linux kernels are supported (zImage & bzImage, loaded high & low)
- Initrd support
- FreeLoader now compiles under Mingw32 instead of just DJGPP, but
the Mingw32 linker seems to output a corrupt binary.
Changes in v1.01 (4/28/2002)
- Fixed FAT short file name buffer overflow that was causing

View file

@ -78,6 +78,7 @@ OS=ReactOS (HD)
OS=ReactOS (Floppy)
;OS=ReactOS (Debug)
OS=Linux
OS=LinuxInitrd
OS=3« Floppy (A:)
OS=Microsoft Windows (C:)
OS=Drive D:
@ -140,6 +141,15 @@ BootDrive=0
Kernel=/vmlinuz
CommandLine="root=/dev/sdb1"
[Linux]
Name="Linux w/Initrd"
BootType=Linux
BootDrive=0x80
BootPartition=1
Kernel=/vmlinuz
Initrd=/initrd.gz
CommandLine=
[3« Floppy (A:)]
Name="3« Floppy (A:)"
BootType=Drive

View file

@ -24,7 +24,7 @@ include rules.mk
# reactos.o tui.o menu.o miscboot.o options.o linux.o multiboot.o arcname.o \
# mem.o memory.o debug.o parseini.o registry.o import.o
#ASM_OBJS = asmcode.o mb.o boot.o mem.o
OBJS = freeldr.o miscboot.o options.o linux.o multiboot.o debug.o oslist.o
OBJS = freeldr.o miscboot.o options.o linux.o multiboot.o debug.o oslist.o version.o
LIBS = arch rtl fs ui reactos comm disk mm cache inifile
LIB_FILES = arch/arch.a rtl/rtl.a fs/fs.a ui/ui.a reactos/reactos.a
LIB_FILES2 = comm/comm.a disk/disk.a mm/mm.a cache/cache.a inifile/inifile.a
@ -34,7 +34,9 @@ LIB_FILES2 = comm/comm.a disk/disk.a mm/mm.a cache/cache.a inifile/inifile.a
all: freeldr.sys
freeldr.sys: c_code.a end.o
$(LD) -N -Ttext=0x8000 --oformat=binary -s -o freeldr.sys c_code.a end.o
# $(LD) -N -Ttext=0x8000 --oformat=binary -s -o freeldr.sys c_code.a end.o
$(LD) -N -Ttext=0x8000 -s -o freeldr.exe c_code.a end.o
$(OBJCOPY) -O binary freeldr.exe freeldr.sys
freeldr.exe: asmcode.a c_code.a
$(LD) -o freeldr.exe asmcode.a c_code.a
@ -69,6 +71,9 @@ debug.o: debug.c debug.h
oslist.o: oslist.c oslist.h
$(CC) $(FLAGS) -o oslist.o -c oslist.c
version.o: version.c version.h
$(CC) $(FLAGS) -o version.o -c version.c
end.o: end.S
$(CC) $(FLAGS) -o end.o -c end.S
@ -107,6 +112,7 @@ inifile:
clean:
- $(RM) *.o
- $(RM) *.a
- $(RM) *.exe
- $(RM) *.sys
$(MAKE) -C arch clean
$(MAKE) -C reactos clean

View file

@ -19,7 +19,7 @@
include ../../rules.mk
OBJS = fathelp.o arch.o boot.o mb.o mem.o disk.o
OBJS = fathelp.o arch.o boot.o linux.o mb.o mem.o disk.o
.PHONY : clean
@ -39,6 +39,9 @@ arch.o: arch.S
boot.o: boot.S
$(CC) $(FLAGS) -o boot.o -c boot.S
linux.o: linux.S
$(CC) $(FLAGS) -o linux.o -c linux.S
mb.o: mb.S
$(CC) $(FLAGS) -o mb.o -c mb.S

View file

@ -22,11 +22,10 @@
#define ASM
#include "arch.h"
#include "multiboot.h"
.code32
EXTERN(_JumpToBootCode)
EXTERN(_ChainLoadBiosBootSectorCode)
call switch_to_real
.code16
@ -44,24 +43,3 @@ EXTERN(_JumpToBootCode)
movw $0x7C00,%sp
ljmpl $0x0000,$0x7C00
.code32
EXTERN(_JumpToLinuxBootCode)
call switch_to_real
.code16
/* Set the boot drive */
movb (_BootDrive),%dl
/* 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

View file

@ -0,0 +1,81 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
.text
.code16
#define ASM
#include "arch.h"
.code32
EXTERN(_BootNewLinuxKernel)
call switch_to_real
.code16
/* Set the boot drive */
movb (_BootDrive),%dl
/* Load segment registers */
cli
movw $0x9000,%bx
movw %bx,%ds
movw %bx,%es
movw %bx,%fs
movw %bx,%gs
movw %bx,%ss
movw $0x9000,%sp
ljmpl $0x9020,$0x0000
.code32
/*
* VOID BootOldLinuxKernel(ULONG KernelSize);
*/
EXTERN(_BootOldLinuxKernel)
/* First we have to copy the kernel down from 0x100000 to 0x10000 */
/* The reason we can overwrite low memory is because this code */
/* executes between 0000:8000 and 0000:FFFF. That leaves space for */
/* 32k of code before we start interfering with Linux kernel address space. */
/* Get KernelSize in ECX and move the kernel down */
movl 0x04(%esp),%ecx
movl $0x100000,%esi
movl $0x10000,%edi
rep movsb
call switch_to_real
.code16
/* Set the boot drive */
movb (_BootDrive),%dl
/* Load segment registers */
cli
movw $0x9000,%bx
movw %bx,%ds
movw %bx,%es
movw %bx,%fs
movw %bx,%gs
movw %bx,%ss
movw $0x9000,%sp
ljmpl $0x9020,$0x0000

View file

@ -21,14 +21,6 @@
#define __FREELDR_H
/* just some stuff */
#define VERSION "FreeLoader v1.01"
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
#define ROSLDR_MAJOR_VERSION 1
#define ROSLDR_MINOR_VERSION 01
#define ROSLDR_PATCH_VERSION 0
#define size_t unsigned int
#define BOOL int
#define BOOLEAN int

View file

@ -33,7 +33,7 @@
PLINUX_BOOTSECTOR LinuxBootSector = NULL;
PLINUX_SETUPSECTOR LinuxSetupSector = NULL;
ULONG SetupSectorSize = 0;
BOOL BigZImageKernel = TRUE;
BOOL NewStyleLinuxKernel = FALSE;
ULONG LinuxKernelSize = 0;
UCHAR LinuxKernelName[260];
UCHAR LinuxInitrdName[260];
@ -88,10 +88,32 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
goto LinuxBootFailed;
}
// Read the initrd (if necessary)
if (LinuxHasInitrd)
{
if (!LinuxReadInitrd())
{
goto LinuxBootFailed;
}
}
// If the default root device is set to FLOPPY (0000h), change to /dev/fd0 (0200h)
if (LinuxBootSector->RootDevice == 0x0000)
{
LinuxBootSector->RootDevice = 0x0200;
}
LinuxBootSector->CommandLineMagic = LINUX_COMMAND_LINE_MAGIC;
LinuxBootSector->CommandLineOffset = 0x9000;
LinuxSetupSector->TypeOfLoader = LINUX_LOADER_TYPE_FREELOADER;
if (NewStyleLinuxKernel)
{
LinuxSetupSector->TypeOfLoader = LINUX_LOADER_TYPE_FREELOADER;
}
else
{
LinuxSetupSector->LoadFlags = 0;
}
RtlCopyMemory((PVOID)0x90000, LinuxBootSector, 512);
RtlCopyMemory((PVOID)0x90200, LinuxSetupSector, SetupSectorSize);
@ -101,7 +123,15 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
clrscr();
stop_floppy();
JumpToLinuxBootCode();
if (LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
{
BootNewLinuxKernel();
}
else
{
BootOldLinuxKernel(LinuxKernelSize);
}
LinuxBootFailed:
@ -123,7 +153,7 @@ LinuxBootFailed:
LinuxBootSector = NULL;
LinuxSetupSector = NULL;
SetupSectorSize = 0;
BigZImageKernel = TRUE;
NewStyleLinuxKernel = FALSE;
LinuxKernelSize = 0;
LinuxHasInitrd = FALSE;
strcpy(LinuxCommandLine, "");
@ -223,7 +253,31 @@ BOOL LinuxReadBootSector(PFILE LinuxKernelFile)
BOOL LinuxReadSetupSector(PFILE LinuxKernelFile)
{
SetupSectorSize = 512 * LinuxBootSector->SetupSectors;
BYTE TempLinuxSetupSector[512];
LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
// Read first linux setup sector
SetFilePointer(LinuxKernelFile, 512);
if (!ReadFile(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)AllocateMemory(SetupSectorSize);
@ -232,17 +286,13 @@ BOOL LinuxReadSetupSector(PFILE LinuxKernelFile)
return FALSE;
}
// Read linux setup sectors
SetFilePointer(LinuxKernelFile, 512);
if (!ReadFile(LinuxKernelFile, SetupSectorSize, NULL, LinuxSetupSector))
{
return FALSE;
}
// Copy over first setup sector
RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512);
// Check for validity
if (LinuxSetupSector->SetupHeaderSignature != LINUX_SETUP_HEADER_ID)
// Read in the rest of the linux setup sectors
SetFilePointer(LinuxKernelFile, 1024);
if (!ReadFile(LinuxKernelFile, SetupSectorSize - 512, NULL, ((PVOID)LinuxSetupSector) + 512))
{
MessageBox("Invalid setup magic (HdrS)");
return FALSE;
}
@ -297,3 +347,97 @@ BOOL LinuxReadKernel(PFILE LinuxKernelFile)
return TRUE;
}
BOOL 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))
{
MessageBox("Error: Cannot load a ramdisk (initrd) with an old kernel image.");
return FALSE;
}
return TRUE;
}
BOOL LinuxReadInitrd(VOID)
{
PFILE LinuxInitrdFile;
UCHAR TempString[260];
ULONG LinuxInitrdSize;
ULONG LinuxInitrdLoadAddress;
ULONG BytesLoaded;
UCHAR StatusText[260];
sprintf(StatusText, " Loading %s", LinuxInitrdName);
DrawStatusText(StatusText);
DrawProgressBar(0);
// Open the initrd file image
LinuxInitrdFile = OpenFile(LinuxInitrdName);
if (LinuxInitrdFile == NULL)
{
sprintf(TempString, "Linux initrd image \'%s\' not found.", LinuxInitrdName);
MessageBox(TempString);
return FALSE;
}
// Get the file size
LinuxInitrdSize = GetFileSize(LinuxInitrdFile);
// Calculate the load address
if (GetExtendedMemorySize() < 0x4000)
{
LinuxInitrdLoadAddress = GetExtendedMemorySize() * 1024; // Load at end of memory
}
else
{
LinuxInitrdLoadAddress = 0x4000 * 1024; // Load at end of 16mb
}
LinuxInitrdLoadAddress -= ROUND_UP(LinuxInitrdSize, 4096);
// Set the information in the setup struct
LinuxSetupSector->RamdiskAddress = LinuxInitrdLoadAddress;
LinuxSetupSector->RamdiskSize = LinuxInitrdSize;
// Read in the ramdisk
for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; )
{
if (!ReadFile(LinuxInitrdFile, 0x4000, NULL, (PVOID)LinuxInitrdLoadAddress))
{
return FALSE;
}
BytesLoaded += 0x4000;
LinuxInitrdLoadAddress += 0x4000;
DrawProgressBar( (BytesLoaded * 100) / LinuxInitrdSize );
}
return TRUE;
}

View file

@ -36,6 +36,9 @@
#define LINUX_KERNEL_LOAD_ADDRESS 0x100000
#define LINUX_FLAG_LOAD_HIGH 0x01
#define LINUX_FLAG_CAN_USE_HEAP 0x80
typedef struct
{
BYTE BootCode1[0x20];
@ -114,7 +117,8 @@ typedef struct
} PACKED LINUX_SETUPSECTOR, *PLINUX_SETUPSECTOR;
void JumpToLinuxBootCode(void); // Implemented in boot.S
VOID BootNewLinuxKernel(VOID); // Implemented in linux.S
VOID BootOldLinuxKernel(ULONG KernelSize); // Implemented in linux.S
VOID LoadAndBootLinux(PUCHAR OperatingSystemName);
@ -122,5 +126,7 @@ BOOL LinuxParseIniSection(PUCHAR OperatingSystemName);
BOOL LinuxReadBootSector(PFILE LinuxKernelFile);
BOOL LinuxReadSetupSector(PFILE LinuxKernelFile);
BOOL LinuxReadKernel(PFILE LinuxKernelFile);
BOOL LinuxCheckKernelVersion(VOID);
BOOL LinuxReadInitrd(VOID);
#endif // defined __LINUX_H

View file

@ -88,7 +88,7 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
if (*((PWORD)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
@ -97,7 +97,7 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
clrscr();
showcursor();
stop_floppy();
JumpToBootCode();
ChainLoadBiosBootSectorCode();
}
VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
@ -150,7 +150,7 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
if (*((PWORD)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
@ -159,7 +159,7 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
clrscr();
showcursor();
stop_floppy();
JumpToBootCode();
ChainLoadBiosBootSectorCode();
}
VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
@ -195,7 +195,7 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
if (*((PWORD)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
@ -204,5 +204,5 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
clrscr();
showcursor();
stop_floppy();
JumpToBootCode();
ChainLoadBiosBootSectorCode();
}

View file

@ -20,7 +20,7 @@
#ifndef __BOOT_H
#define __BOOT_H
void JumpToBootCode(void); // Implemented in boot.S
VOID ChainLoadBiosBootSectorCode(VOID); // Implemented in boot.S
VOID LoadAndBootBootSector(PUCHAR OperatingSystemName);
VOID LoadAndBootPartition(PUCHAR OperatingSystemName);

View file

@ -25,6 +25,7 @@
#include "multiboot.h"
#include "ui.h"
#include "inifile.h"
#include "mm.h"
unsigned long next_module_load_base = 0;
module_t* pOpenModule = NULL;
@ -32,7 +33,7 @@ module_t* pOpenModule = NULL;
BOOL MultiBootLoadKernel(FILE *KernelImage)
{
DWORD ImageHeaders[2048];
PDWORD ImageHeaders;
int Idx;
DWORD dwHeaderChecksum;
DWORD dwFileLoadOffset;
@ -40,11 +41,22 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
DWORD dwBssSize;
ULONG BytesRead;
// Allocate 8192 bytes for multiboot header
ImageHeaders = (PDWORD)AllocateMemory(8192);
if (ImageHeaders == NULL)
{
return FALSE;
}
/*
* Load the first 8192 bytes of the kernel image
* so we can search for the multiboot header
*/
ReadFile(KernelImage, 8192, NULL, ImageHeaders);
if (!ReadFile(KernelImage, 8192, NULL, ImageHeaders))
{
FreeMemory(ImageHeaders);
return FALSE;
}
/*
* Now find the multiboot header and copy it
@ -61,6 +73,8 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
}
}
FreeMemory(ImageHeaders);
/*
* If we reached the end of the 8192 bytes without
* finding the multiboot header then return error

View file

@ -25,6 +25,7 @@ RM = cmd /C del
CP = cmd /C copy
MAKE = make
NASM_CMD = nasm
OBJCOPY = objcopy
# For a release build uncomment this line
#FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -O3

View file

@ -23,6 +23,7 @@
#include <mm.h>
#include <debug.h>
#include <inifile.h>
#include <version.h>
ULONG nScreenWidth = 80; // Screen Width
ULONG nScreenHeight = 25; // Screen Height
@ -171,7 +172,7 @@ void DrawBackdrop(void)
//
DrawText(3,
2,
VERSION,
GetFreeLoaderVersionString(),
ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
//

38
freeldr/freeldr/version.c Normal file
View file

@ -0,0 +1,38 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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>
#include <version.h>
#include <rtl.h>
UCHAR FreeLoaderVersionString[80];
PUCHAR GetFreeLoaderVersionString(VOID)
{
if (FREELOADER_PATCH_VERSION == 0)
{
sprintf(FreeLoaderVersionString, "FreeLoader v%d.%d", FREELOADER_MAJOR_VERSION, FREELOADER_MINOR_VERSION);
}
else
{
sprintf(FreeLoaderVersionString, "FreeLoader v%d.%d.%d", FREELOADER_MAJOR_VERSION, FREELOADER_MINOR_VERSION, FREELOADER_PATCH_VERSION);
}
return FreeLoaderVersionString;
}

43
freeldr/freeldr/version.h Normal file
View file

@ -0,0 +1,43 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#ifndef __VERSION_H
#define __VERSION_H
/* just some stuff */
#define VERSION "FreeLoader v1.2"
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
// FreeLoader version defines
//
// NOTE:
// If you fix bugs then you increment the patch version
// If you add features then you increment the minor version
// If you add major functionality then you increment the major version
//
#define FREELOADER_MAJOR_VERSION 1
#define FREELOADER_MINOR_VERSION 2
#define FREELOADER_PATCH_VERSION 0
PUCHAR GetFreeLoaderVersionString(VOID);
#endif // defined __VERSION_H