2 added + 6 modified, total 8 files
freeldr
diff -u -r1.7 -r1.8
--- notes.txt 21 Oct 2003 21:23:58 -0000 1.7
+++ notes.txt 1 Nov 2004 20:49:30 -0000 1.8
@@ -4,7 +4,7 @@
0000:0000 - 0000:0FFF: Interrupt vector table & BIOS data
0000:1000 - 0000:6FFF: Real mode stack area
-0000:7000 - 0000:7FFF: Unused
+0000:7000 - 0000:7FFF: Cmdline (multiboot)
0000:8000 - xxxx:xxxx: FreeLoader program & data area
xxxx:xxxx - 7000:7FFF: Random memory allocation heap
7000:8000 - 7000:FFFF: Protected mode stack area
@@ -34,13 +34,24 @@
The BIOS loads the boot sector (2048 bytes) at 0000:7C00. First, the
boot sector relocates itself to 0000:7000 (up to 0000:7800). Then it looks
-for the I386 directory and makes it the current directory. Next it looks for
+for the LOADER directory and makes it the current directory. Next it looks for
FREELDR.SYS and loads it at 0000:8000. Finally it restores the boot drive
number in the DL register and jumps to FreeLoader's entry point at 0000:8000.
+Multiboot
+
+ Freeldr contains a multiboot signature and can itself be loaded by a
+multiboot-compliant loader (like Grub). The multiboot header instructs the
+primary loader to load freeldr.sys at 0x200000 (needs to be above 1MB). Control
+is then transferred to the multiboot entry point. Since freeldr.sys expects to
+be loaded at a base address 0000:8000 it will start by relocating itself there
+and then jumping to the relocated copy.
+
+
+
FreeLoader Initialization
When FreeLoader gets control it saves the boot drive, passed to it in
the DL register, and sets up the stack, enables protected mode, and calls
-BootMain().
\ No newline at end of file
+BootMain().
freeldr/freeldr
diff -N cmdline.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cmdline.c 1 Nov 2004 20:49:32 -0000 1.1
@@ -0,0 +1,122 @@
+/* $Id: cmdline.c,v 1.1 2004/11/01 20:49:32 gvg Exp $
+ *
+ * FreeLoader
+ * Copyright (C) 1998-2003 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 <cmdline.h>
+#include <rtl.h>
+
+static CMDLINEINFO CmdLineInfo;
+
+static char *
+SkipWhitespace(char *s)
+{
+ while ('\0' != *s && isspace(*s))
+ {
+ s++;
+ }
+
+ return s;
+}
+
+void
+CmdLineParse(char *CmdLine)
+{
+ char *s;
+ char *Name;
+ char *Value;
+ char *End;
+
+ CmdLineInfo.DefaultOperatingSystem = NULL;
+ CmdLineInfo.TimeOut = -1;
+
+ if (NULL == CmdLine)
+ {
+ return;
+ }
+
+ /* Skip over "kernel name" */
+ s = CmdLine;
+ while ('\0' != *s && ! isspace(*s))
+ {
+ s++;
+ }
+ s = SkipWhitespace(s);
+
+ while ('\0' != *s)
+ {
+ Name = s;
+ while (! isspace(*s) && '=' != *s && '\0' != *s)
+ {
+ s++;
+ }
+ End = s;
+ s = SkipWhitespace(s);
+ if ('=' == *s)
+ {
+ s++;
+ *End = '\0';
+ s = SkipWhitespace(s);
+ if ('"' == *s)
+ {
+ s++;
+ Value = s;
+ while ('"' != *s && '\0' != *s)
+ {
+ s++;
+ }
+ }
+ else
+ {
+ Value = s;
+ while (! isspace(*s) && '\0' != *s)
+ {
+ s++;
+ }
+ }
+ if ('\0' != *s)
+ {
+ *s++ = '\0';
+ }
+ if (0 == stricmp(Name, "defaultos"))
+ {
+ CmdLineInfo.DefaultOperatingSystem = Value;
+ }
+ else if (0 == stricmp(Name, "timeout"))
+ {
+ CmdLineInfo.TimeOut = atoi(Value);
+ }
+ }
+ }
+}
+
+char *
+CmdLineGetDefaultOS(void)
+{
+ return CmdLineInfo.DefaultOperatingSystem;
+}
+
+S32
+CmdLineGetTimeOut(void)
+{
+ return CmdLineInfo.TimeOut;
+}
+
+/* EOF */
+
freeldr/freeldr
diff -u -r1.52 -r1.53
--- Makefile 30 Oct 2004 11:19:44 -0000 1.52
+++ Makefile 1 Nov 2004 20:49:32 -0000 1.53
@@ -269,17 +269,18 @@
MATH_OBJS = libgcc2.o
BASE_OBJS = freeldr.o \
- debug.o \
- multiboot.o \
- version.o
+ debug.o \
+ multiboot.o \
+ version.o \
+ cmdline.o
FREELDR_OBJS= bootmgr.o \
- drivemap.o \
- miscboot.o \
- options.o \
- linuxboot.o \
- oslist.o \
- custom.o
+ drivemap.o \
+ miscboot.o \
+ options.o \
+ linuxboot.o \
+ oslist.o \
+ custom.o
ROSLDR_OBJS = reactos.o
freeldr/freeldr
diff -u -r1.7 -r1.8
--- bootmgr.c 20 Jan 2003 18:39:53 -0000 1.7
+++ bootmgr.c 1 Nov 2004 20:49:32 -0000 1.8
@@ -34,6 +34,7 @@
#include <bootmgr.h>
#include <drivemap.h>
#include <keycodes.h>
+#include <cmdline.h>
VOID RunLoader(VOID)
@@ -153,20 +154,30 @@
U32 GetDefaultOperatingSystem(PUCHAR OperatingSystemList[], U32 OperatingSystemCount)
{
UCHAR DefaultOSText[80];
- U32 SectionId;
- U32 DefaultOS = 0;
- U32 Idx;
+ char* DefaultOSName;
+ U32 SectionId;
+ U32 DefaultOS = 0;
+ U32 Idx;
if (!IniOpenSection("FreeLoader", &SectionId))
{
return 0;
}
- if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, 80))
+ DefaultOSName = CmdLineGetDefaultOS();
+ if (NULL == DefaultOSName)
+ {
+ if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, 80))
+ {
+ DefaultOSName = DefaultOSText;
+ }
+ }
+
+ if (NULL != DefaultOSName)
{
for (Idx=0; Idx<OperatingSystemCount; Idx++)
{
- if (stricmp(DefaultOSText, OperatingSystemList[Idx]) == 0)
+ if (stricmp(DefaultOSName, OperatingSystemList[Idx]) == 0)
{
DefaultOS = Idx;
break;
@@ -183,6 +194,12 @@
U32 TimeOut;
U32 SectionId;
+ TimeOut = CmdLineGetTimeOut();
+ if (0 <= TimeOut)
+ {
+ return TimeOut;
+ }
+
if (!IniOpenSection("FreeLoader", &SectionId))
{
return -1;
freeldr/freeldr
diff -u -r1.27 -r1.28
--- freeldr.c 19 Jan 2003 01:03:57 -0000 1.27
+++ freeldr.c 1 Nov 2004 20:49:32 -0000 1.28
@@ -24,13 +24,11 @@
#include <debug.h>
#include <bootmgr.h>
#include <fs.h>
+#include <cmdline.h>
-// Variables BootDrive & BootPartition moved to asmcode.S
-//U32 BootDrive = 0; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
-//U32 BootPartition = 0; // Boot Partition, 1-4
-
-VOID BootMain(VOID)
+VOID BootMain(char *CmdLine)
{
+ CmdLineParse(CmdLine);
EnableA20();
freeldr/freeldr/arch/i386
diff -u -r1.7 -r1.8
--- arch.S 26 Jun 2003 15:16:36 -0000 1.7
+++ arch.S 1 Nov 2004 20:49:32 -0000 1.8
@@ -22,6 +22,7 @@
#define ASM
#include <arch.h>
+#include <multiboot.h>
EXTERN(RealEntryPoint)
@@ -52,16 +53,18 @@
movb %dh,(_BootPartition)
/* GO! */
+ xorl %eax,%eax
+ pushl %eax
call _BootMain
call switch_to_real
.code16
- int $0x19
+ int $0x19
/* We should never get here */
stop:
- jmp stop
+ jmp stop
nop
nop
@@ -100,9 +103,9 @@
lidt i386idtptr
/* Enable Protected Mode */
- mov %cr0,%eax
- orl $CR0_PE_SET,%eax
- mov %eax,%cr0
+ mov %cr0,%eax
+ orl $CR0_PE_SET,%eax
+ mov %eax,%cr0
/* Clear prefetch queue & correct CS */
ljmp $PMODE_CS, $inpmode
@@ -168,9 +171,9 @@
movw %ax,%ss
/* Disable Protected Mode */
- mov %cr0,%eax
+ mov %cr0,%eax
andl $CR0_PE_CLR,%eax
- mov %eax,%cr0
+ mov %eax,%cr0
/* Clear prefetch queue & correct CS */
ljmp $0, $inrmode
@@ -211,9 +214,9 @@
.code16
empty_8042:
.word 0x00eb,0x00eb // jmp $+2, jmp $+2
- inb $0x64,%al
- testb $0x02,%al
- jnz empty_8042
+ inb $0x64,%al
+ testb $0x02,%al
+ jnz empty_8042
ret
/*
@@ -228,11 +231,11 @@
.code16
call empty_8042
- movb $0xD1,%al // command write
- outb %al,$0x64
+ movb $0xD1,%al // command write
+ outb %al,$0x64
call empty_8042
- mov $0xDF,%al // A20 on
- out %al,$0x60
+ mov $0xDF,%al // A20 on
+ out %al,$0x60
call empty_8042
call switch_to_prot
.code32
@@ -253,11 +256,11 @@
.code16
call empty_8042
- movb $0xD1,%al // command write
- outb %al,$0x64
+ movb $0xD1,%al // command write
+ outb %al,$0x64
call empty_8042
- mov $0xDD,%al // A20 off
- out %al,$0x60
+ mov $0xDD,%al // A20 off
+ out %al,$0x60
call empty_8042
call switch_to_prot
.code32
@@ -266,8 +269,134 @@
ret
+/* Multiboot support
+ *
+ * Allows freeldr to be loaded as a "multiboot kernel" by
+ * other boot loaders like Grub
+ */
+
+#define MB_INFO_FLAGS_OFFSET 0
+#define MB_INFO_BOOT_DEVICE_OFFSET 12
+#define MB_INFO_COMMAND_LINE_OFFSET 16
+
+/*
+ * We want to execute at 0x8000 (to be compatible with bootsector
+ * loading), but Grub only allows loading of multiboot kernels
+ * above 1MB. So we let Grub load us there and then relocate
+ * ourself to 0x8000
+ */
+#define CMDLINE_BASE 0x7000
+#define FREELDR_BASE 0x8000
+#define INITIAL_BASE 0x200000
+
+ /* Align 32 bits boundary */
+ .align 4
+
+ /* Multiboot header */
+MultibootHeader:
+ /* magic */
+ .long MULTIBOOT_HEADER_MAGIC
+ /* flags */
+ .long MULTIBOOT_HEADER_FLAGS
+ /* checksum */
+ .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+ /* header_addr */
+ .long INITIAL_BASE + MultibootHeader - FREELDR_BASE
+ /* load_addr */
+ .long INITIAL_BASE
+ /* load_end_addr */
+ .long INITIAL_BASE + __bss_start__ - FREELDR_BASE
+ /* bss_end_addr */
+ .long INITIAL_BASE + __bss_end__ - FREELDR_BASE
+ /* entry_addr */
+ .long INITIAL_BASE + MultibootEntry - FREELDR_BASE
+
+MultibootEntry:
+ cli /* Even after setting up the our IDT below we are
+ * not ready to handle hardware interrupts (no entries
+ * in IDT), so there's no sti here. Interrupts will be
+ * enabled in due time */
+
+ /* Although the multiboot spec says we should be called with the
+ * segment registers set to 4GB flat mode, let's be sure and set up
+ * our own */
+ lgdt gdtptrhigh + INITIAL_BASE - FREELDR_BASE
+ /* Reload segment selectors */
+ ljmp $PMODE_CS, $(mb1 + INITIAL_BASE - FREELDR_BASE)
+mb1:
+ movw $PMODE_DS,%dx
+ movw %dx,%ds
+ movw %dx,%es
+
+ /* Copy to low mem */
+ movl $INITIAL_BASE,%esi
+ movl $FREELDR_BASE,%edi
+ movl $(__bss_end__ - FREELDR_BASE),%ecx
+ addl $3,%ecx
+ shrl $2,%ecx
+ rep movsl
+
+ /* Load the GDT and IDT */
+ lgdt gdtptr
+ lidt i386idtptr
+ /* Clear prefetch queue & correct CS,
+ * jump to low mem */
+ ljmp $PMODE_CS, $mb2
+mb2:
+ /* Reload segment selectors */
+ movw $PMODE_DS,%dx
+ movw %dx,%ds
+ movw %dx,%es
+ movw %dx,%fs
+ movw %dx,%gs
+ movw %dx,%ss
+ movl $STACK32ADDR,%esp
+
+ /* Check for valid multiboot signature */
+ cmpl $MULTIBOOT_BOOTLOADER_MAGIC,%eax
+ jne mbfail
+
+ /* See if the boot device was passed in */
+ movl MB_INFO_FLAGS_OFFSET(%ebx),%edx
+ testl $MB_INFO_FLAG_BOOT_DEVICE,%edx
+ jz mb3
+ /* Retrieve boot device info */
+ movl MB_INFO_BOOT_DEVICE_OFFSET(%ebx),%eax
+ shrl $16,%eax
+ incb %al
+ movb %al,_BootPartition
+ movb %ah,_BootDrive
+ jmp mb4
+mb3: /* No boot device known, assume first partition of first harddisk */
+ movb $0x80,_BootDrive
+ movb $1,_BootPartition
+mb4:
+
+ /* Check for a command line */
+ xorl %eax,%eax
+ testl $MB_INFO_FLAG_COMMAND_LINE,%edx
+ jz mb6
+ /* Copy command line to low mem*/
+ movl MB_INFO_COMMAND_LINE_OFFSET(%ebx),%esi
+ movl $CMDLINE_BASE,%edi
+mb5: lodsb
+ stosb
+ testb %al,%al
+ jnz mb5
+ movl $CMDLINE_BASE,%eax
+mb6:
+ /* GO! */
+ pushl %eax
+ call _BootMain
+
+mbfail: call switch_to_real
+ .code16
+ int $0x19
+mbstop: jmp mbstop /* We should never get here */
+
+ .code32
/* 16-bit stack pointer */
stack16:
@@ -323,6 +452,11 @@
.word 0x27 /* Limit */
.long gdt /* Base Address */
+/* Initial GDT table pointer for multiboot */
+gdtptrhigh:
+ .word 0x27 /* Limit */
+ .long gdt + INITIAL_BASE - FREELDR_BASE /* Base Address */
+
/* Real-mode IDT pointer */
rmode_idtptr:
.word 0x3ff /* Limit */
freeldr/freeldr/include
diff -N cmdline.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cmdline.h 1 Nov 2004 20:49:32 -0000 1.1
@@ -0,0 +1,37 @@
+/* $Id: cmdline.h,v 1.1 2004/11/01 20:49:32 gvg Exp $
+ *
+ * FreeLdr boot loader
+ * Copyright (C) 2002, 2003 ReactOS Team
+ *
+ * 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 __CMDLINE_H__
+#define __CMDLINE_H__
+
+typedef struct tagCMDLINEINFO
+{
+ char *DefaultOperatingSystem;
+ S32 TimeOut;
+} CMDLINEINFO, *PCMDLINEINFO;
+
+extern void CmdLineParse(char *CmdLine);
+
+extern char *CmdLineGetDefaultOS(void);
+extern S32 CmdLineGetTimeOut(void);
+
+#endif /* __CMDLINE_H__ */
+
+/* EOF */
freeldr/freeldr/include
diff -u -r1.8 -r1.9
--- freeldr.h 12 Oct 2003 15:52:24 -0000 1.8
+++ freeldr.h 1 Nov 2004 20:49:32 -0000 1.9
@@ -75,7 +75,7 @@
extern U32 BootPartition; // Boot Partition, 1-4
extern BOOL UserInterfaceUp; // Tells us if the user interface is displayed
-void BootMain(void);
+void BootMain(char *CmdLine);
VOID RunLoader(VOID);
#endif // defined __FREELDR_H
CVSspam 0.2.8