Commit in freeldr on MAIN
notes.txt+14-31.7 -> 1.8
freeldr/cmdline.c+122added 1.1
       /Makefile+10-91.52 -> 1.53
       /bootmgr.c+22-51.7 -> 1.8
       /freeldr.c+3-51.27 -> 1.28
freeldr/arch/i386/arch.S+152-181.7 -> 1.8
freeldr/include/cmdline.h+37added 1.1
               /freeldr.h+1-11.8 -> 1.9
+361-41
2 added + 6 modified, total 8 files
Add ability to be loaded as "multiboot kernel" from other multiboot loaders

freeldr
notes.txt 1.7 -> 1.8
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
cmdline.c added at 1.1
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
Makefile 1.52 -> 1.53
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
bootmgr.c 1.7 -> 1.8
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
freeldr.c 1.27 -> 1.28
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
arch.S 1.7 -> 1.8
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
cmdline.h added at 1.1
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
freeldr.h 1.8 -> 1.9
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