Multiboot Kernel Compliance
authorBrian Palmer <brianp@sginet.com>
Tue, 5 Jun 2001 21:45:51 +0000 (21:45 +0000)
committerBrian Palmer <brianp@sginet.com>
Tue, 5 Jun 2001 21:45:51 +0000 (21:45 +0000)
svn path=/trunk/; revision=1945

freeldr/freeldr/Makefile
freeldr/freeldr/asmcode.S
freeldr/freeldr/freeldr.c
freeldr/freeldr/multiboot.S [new file with mode: 0644]
freeldr/freeldr/multiboot.h [new file with mode: 0644]
freeldr/freeldr/ros.S [deleted file]
freeldr/freeldr/rosboot.c
freeldr/freeldr/rosboot.h

index e281738..b05b180 100644 (file)
@@ -24,12 +24,13 @@ export AR = ar
 export RM = cmd /C del
 export CP = cmd /C copy
 
-FLAGS = -Wall -nostdinc -fno-builtin
+#FLAGS = -Wall -nostdinc -fno-builtin
+FLAGS = -Wall -fno-builtin
 
 # asmcode.o has to be first in the link line because it contains the startup code
-OBJS = asmcode.a asmcode.o ros.o boot.o freeldr.o stdlib.o fs.a fs.o fs_fat.o \
+OBJS = asmcode.a asmcode.o multiboot.o boot.o freeldr.o stdlib.o fs.a fs.o fs_fat.o \
        rosboot.o tui.o menu.o miscboot.o options.o linux.o
-ASM_OBJS = asmcode.o ros.o boot.o
+ASM_OBJS = asmcode.o multiboot.o boot.o
 C_OBJS = freeldr.o stdlib.o fs.a rosboot.o tui.o menu.o miscboot.o options.o linux.o
 
 all:   freeldr.sys
@@ -61,11 +62,11 @@ fs.o:       fs.c freeldr.h fs.h stdlib.h tui.h asmcode.h Makefile
 fs_fat.o:      fs_fat.c freeldr.h fs.h stdlib.h tui.h Makefile
        $(CC) $(FLAGS) -o fs_fat.o -c fs_fat.c
 
-rosboot.o:     rosboot.c freeldr.h rosboot.h stdlib.h fs.h tui.h Makefile
+rosboot.o:     rosboot.c freeldr.h rosboot.h stdlib.h fs.h tui.h multiboot.h Makefile
        $(CC) $(FLAGS) -o rosboot.o -c rosboot.c
 
-ros.o: ros.S asmcode.h Makefile
-       $(CC) $(FLAGS) -o ros.o -c ros.S
+multiboot.o:   multiboot.S asmcode.h multiboot.h Makefile
+       $(CC) $(FLAGS) -o multiboot.o -c multiboot.S
 
 tui.o: tui.c freeldr.h stdlib.h tui.h Makefile
        $(CC) $(FLAGS) -o tui.o -c tui.c
index ae91d6e..e4c6f1d 100644 (file)
@@ -1116,6 +1116,37 @@ _get_sectors_done:
        ret
 
 
+       /*
+        * Needed for enabling the a20 address line
+        */
+       .code16
+empty_8042:
+       .word   0x00eb,0x00eb            // jmp $+2, jmp $+2
+       inb     $0x64,%al
+    testb   $0x02,%al
+    jnz     empty_8042
+       ret
+
+       /*
+        * Enable the A20 address line (to allow access to over 1mb)
+        */
+       .code32
+EXTERN(_enable_a20)
+       call    switch_to_real
+       .code16
+
+       call    empty_8042
+    movb       $0xD1,%al                // command write
+    outb       %al,$0x64
+       call    empty_8042
+    mov                $0xDF,%al                // A20 on
+    out                %al,$0x60
+       call    empty_8042
+       call    switch_to_prot
+       .code32
+
+       ret
+
 
 
 
index b38d189..c36415f 100644 (file)
@@ -96,11 +96,10 @@ void BootMain(void)
        {
                nOSToBoot = RunMenu();
 
-               LoadAndBootLinux(0x80, 0, "vmlinuz", "");
                switch (OSList[nOSToBoot].nOSType)
                {
                case OSTYPE_REACTOS:
-                       LoadAndBootReactOS(nOSToBoot);
+                       LoadAndBootReactOS(OSList[nOSToBoot].name);
                        break;
                case OSTYPE_LINUX:
                        MessageBox("Cannot boot this OS type yet!");
diff --git a/freeldr/freeldr/multiboot.S b/freeldr/freeldr/multiboot.S
new file mode 100644 (file)
index 0000000..d22044a
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 1999, 2000, 2001  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
+
+#include "asmcode.h"
+
+       /*
+     * Here we assume the kernel is loaded at 1mb
+     * This boots the kernel
+        */
+       .code32
+EXTERN(_boot_ros)
+       call    switch_to_real
+       .code16
+
+    /* Save cursor position */
+       movw    $3,%ax          //! Reset video mode
+       int     $0x10
+
+
+       movb    $10,%bl
+       movb    $12,%ah
+       int     $0x10
+
+       movw    $0x1112,%ax             // Use 8x8 font
+       xorb    %bl,%bl
+       int     $0x10
+       movw    $0x1200,%ax             // Use alternate print screen
+       movb    $0x20,%bl
+       int     $0x10
+       movb    $1,%ah                  // Define cursor (scan lines 6 to 7)
+       movw    $0x0607,%cx
+       int     $0x10
+
+       movb    $1,%ah
+       movw    $0x600,%cx
+       int     $0x10
+
+       movb    $6,%ah                  // Scroll active page up
+       movb    $0x32,%al               // Clear 25 lines
+       movw    $0,%cx                  // Upper left of scroll
+       movw    $0x314F,%dx             // Lower right of scroll
+       movb    $(1*0x10+1),%bh // Use normal attribute on blanked line
+       int             $0x10                   // Video-IO
+
+
+       movw    $0,%dx
+       movb    $0,%dh
+
+       movb    $2,%ah
+       movb    $0,%bh
+       int             $0x10
+
+       movw    $0,%dx
+       movb    $0,%dh
+
+       movb    $2,%ah
+       movb    $0,%bh
+       int             $0x10
+
+       call    _multi_boot
+
+       // Should never get here
+       cli
+       hlt
+
+
+       /*
+        * After you have setup the _mb_header and _mb_info structures
+        * then call this routine to transfer control to the kernel.
+        * This routine must be entered in 16-bit mode.
+        */
+       .code16
+EXTERN(_multi_boot)
+
+       cli
+
+       /*
+        * Setup various variables
+        */
+       movw    %ds,%bx
+       movzwl  %bx,%eax
+       shll    $4,%eax
+       addl    %eax,kernel_gdtbase
+
+       /*
+        * Load the absolute address of the multiboot information structure
+        */
+       movl    $_mb_info,%ebx
+
+       /*
+        * load gdt
+        */
+       lgdt    kernel_gdtptr
+
+       /*       
+        * Enter pmode and clear prefetch queue
+        */
+       movl    %cr0,%eax
+       orl             $0x10001,%eax
+       movl    %eax,%cr0
+       jmp             next
+next:
+       /*
+        * NOTE: This must be position independant (no references to
+        * non absolute variables)
+        */
+
+       /*
+        * Initalize segment registers
+        */
+       movw    $KERNEL_DS,%ax
+       movw    %ax,%ds
+       movw    %ax,%ss
+       movw    %ax,%es
+       movw    %ax,%fs
+       movw    %ax,%gs
+
+       /*
+        * Initalize eflags
+        */
+       pushl   $0
+       popfl   
+
+       /*
+        * Load the multiboot magic value into eax
+        */     
+       movl    $0x2badb002,%eax
+
+       /*
+        * Jump to start of 32 bit code at 0xc0000000 + 0x1000
+        */
+
+       pushl   $KERNEL_CS
+       pushl   _mb_entry_addr
+       lretl
+
+       //ljmpl $KERNEL_CS,$(0x0200000+0x1000)
+       //ljmpl $KERNEL_CS,(_mb_entry_addr)
+       //ljmpl $KERNEL_CS,$(KERNEL_BASE+0x1000)
+
+
+       .p2align        2       /* force 4-byte alignment */
+kernel_gdt:
+       .word 0               // Zero descriptor
+       .word 0
+       .word 0
+       .word 0
+
+       .word 0xffff          // Kernel code descriptor 
+       .word 0x0000          // 
+       .word 0x9a00          // base 0h limit 4gb
+       .word 0x00cf
+                       
+       .word 0xffff          // Kernel data descriptor
+       .word 0x0000          // 
+       .word 0x9200          // base 0h limit 4gb
+       .word 0x00cf
+
+kernel_gdtptr:
+       .word   (3*8)-1                 /* Limit */
+kernel_gdtbase:
+       .long   kernel_gdt                              /* Base Address */
+
+
+EXTERN(_mb_header)
+_mb_magic:
+       .long   0               // unsigned long magic;
+_mb_flags:
+       .long   0               // unsigned long flags;
+_mb_checksum:
+       .long   0               // unsigned long checksum;
+_mb_header_addr:
+       .long   0               // unsigned long header_addr;
+_mb_load_addr:
+       .long   0               // unsigned long load_addr;
+_mb_load_end_addr:
+       .long   0               // unsigned long load_end_addr;
+_mb_bss_end_addr:
+       .long   0               // unsigned long bss_end_addr;
+_mb_entry_addr:
+       .long   0               // unsigned long entry_addr;
+
+       //
+       // Boot information structure
+       //
+
+EXTERN(_mb_info)
+_multiboot_flags:
+       .long   0
+_multiboot_mem_lower:
+       .long   0
+_multiboot_mem_upper:
+       .long   0
+_multiboot_boot_device:
+       .long   0
+_multiboot_cmdline:    
+       .long   0
+_multiboot_mods_count:
+       .long   0
+_multiboot_mods_addr:
+       .long   0
+_multiboot_syms:
+       .rept   12
+       .byte   0
+       .endr
+_multiboot_mmap_length:
+       .long   0
+_multiboot_mmap_addr:
+       .long   0
+_multiboot_drives_count:
+       .long   0
+_multiboot_drives_addr:
+       .long   0
+_multiboot_config_table:
+       .long   0
+_multiboot_boot_loader_name:
+       .long   0
+_multiboot_apm_table:
+       .long   0
+
+EXTERN(_multiboot_modules)
+       .rept   (64 * /*multiboot_module_size*/ 16)
+       .byte   0
+       .endr
+EXTERN(_multiboot_module_strings)
+       .rept   (64*256)
+       .byte   0
+       .endr
+
+_multiboot_address_range_descriptor_size:
+       .long   0
+
+_multiboot_address_ranges:
+       .rept   (64 * /*multiboot_address_range_size*/24)
+       .byte   0
+       .endr
+
+EXTERN(_multiboot_kernel_cmdline)
+       .rept   255
+       .byte   0
+       .endr
diff --git a/freeldr/freeldr/multiboot.h b/freeldr/freeldr/multiboot.h
new file mode 100644 (file)
index 0000000..cb73ccd
--- /dev/null
@@ -0,0 +1,129 @@
+/* multiboot.h - the header for Multiboot */
+/* Copyright (C) 1999  Free Software Foundation, Inc.
+   
+   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 __MULTIBOOT_H
+#define __MULTIBOOT_H
+
+/* Macros. */
+
+/* The magic number for the Multiboot header. */
+#define MULTIBOOT_HEADER_MAGIC          0x1BADB002
+
+/* The flags for the Multiboot header. */
+#define MULTIBOOT_HEADER_FLAGS          0x00010003
+
+/* The magic number passed by a Multiboot-compliant boot loader. */
+#define MULTIBOOT_BOOTLOADER_MAGIC      0x2BADB002
+
+/* The size of our stack (16KB). */
+#define STACK_SIZE                      0x4000
+
+/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym)                     _ ## sym
+#else
+# define EXT_C(sym)                     sym
+#endif
+
+#ifndef ASM
+/* Do not include here in boot.S. */
+
+/* Types. */
+
+/* The Multiboot header. */
+typedef struct multiboot_header
+{
+  unsigned long magic;
+  unsigned long flags;
+  unsigned long checksum;
+  unsigned long header_addr;
+  unsigned long load_addr;
+  unsigned long load_end_addr;
+  unsigned long bss_end_addr;
+  unsigned long entry_addr;
+} multiboot_header_t;
+
+/* The symbol table for a.out. */
+typedef struct aout_symbol_table
+{
+  unsigned long tabsize;
+  unsigned long strsize;
+  unsigned long addr;
+  unsigned long reserved;
+} aout_symbol_table_t;
+
+/* The section header table for ELF. */
+typedef struct elf_section_header_table
+{
+  unsigned long num;
+  unsigned long size;
+  unsigned long addr;
+  unsigned long shndx;
+} elf_section_header_table_t;
+
+/* The Multiboot information. */
+typedef struct multiboot_info
+{
+  unsigned long flags;
+  unsigned long mem_lower;
+  unsigned long mem_upper;
+  unsigned long boot_device;
+  unsigned long cmdline;
+  unsigned long mods_count;
+  unsigned long mods_addr;
+  union
+  {
+    aout_symbol_table_t aout_sym;
+    elf_section_header_table_t elf_sec;
+  } u;
+  unsigned long mmap_length;
+  unsigned long mmap_addr;
+} multiboot_info_t;
+
+/* The module structure. */
+typedef struct module
+{
+  unsigned long mod_start;
+  unsigned long mod_end;
+  unsigned long string;
+  unsigned long reserved;
+} module_t;
+
+/* The memory map. Be careful that the offset 0 is base_addr_low
+   but no size. */
+typedef struct memory_map
+{
+  unsigned long size;
+  unsigned long base_addr_low;
+  unsigned long base_addr_high;
+  unsigned long length_low;
+  unsigned long length_high;
+  unsigned long type;
+} memory_map_t;
+
+#endif /* ! ASM */
+
+
+multiboot_header_t             mb_header;                                                      // Multiboot header structure defined in kernel image file
+multiboot_info_t               mb_info;                                                        // Multiboot info structure passed to kernel
+char                                   multiboot_kernel_cmdline[255];          // Command line passed to kernel
+module_t                               multiboot_modules[64];                          // Array to hold boot module info loaded for the kernel
+char                                   multiboot_module_strings[64][256];      // Array to hold module names
+
+
+#endif // defined __MULTIBOOT_H
\ No newline at end of file
diff --git a/freeldr/freeldr/ros.S b/freeldr/freeldr/ros.S
deleted file mode 100644 (file)
index b10b735..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- *  FreeLoader
- *  Copyright (C) 1999, 2000  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
-
-#include "asmcode.h"
-
-       /*
-        * Needed for enabling the a20 address line
-        */
-empty_8042:
-       .word   0x00eb,0x00eb            // jmp $+2, jmp $+2
-       inb     $0x64,%al
-    testb   $0x02,%al
-    jnz     empty_8042
-       ret
-
-       /*
-        * Enable the A20 address line (to allow access to over 1mb)
-        */
-       .code32
-EXTERN(_enable_a20)
-       call    switch_to_real
-       .code16
-
-       call    empty_8042
-    movb       $0xD1,%al                // command write
-    outb       %al,$0x64
-       call    empty_8042
-    mov                $0xDF,%al                // A20 on
-    out                %al,$0x60
-       call    empty_8042
-       call    switch_to_prot
-       .code32
-
-       ret
-
-       .code16
-
-    /*
-     * Reprogram the PIC because they overlap the Intel defined
-     * exceptions 
-        */
-reprogram_pic:
-       movb    $0x11,%al                // initialization sequence
-       outb    %al,$0x20                // send it to 8259A-1
-       .word   0x00eb,0x00eb            // jmp $+2, jmp $+2
-       outb    %al,$0xA0                // and to 8259A-2
-       .word   0x00eb,0x00eb
-       movb    $0x40,%al                // start of hardware int's (0x20)
-       outb    %al,$0x21
-       .word   0x00eb,0x00eb
-       movb    $0x48,%al                // start of hardware int's 2 (0x28)
-       outb    %al,$0xA1
-       .word   0x00eb,0x00eb
-       movb    $0x04,%al                // 8259-1 is master
-       outb    %al,$0x21
-       .word   0x00eb,0x00eb
-       movb    $0x02,%al                // 8259-2 is slave
-       outb    %al,$0xA1
-       .word   0x00eb,0x00eb
-       movb    $0x01,%al                // 8086 mode for both
-       outb    %al,$0x21
-       .word   0x00eb,0x00eb
-       outb    %al,$0xA1
-       .word   0x00eb,0x00eb
-       movb    $0xFF,%al                // mask off all interrupts for now
-       outb    %al,$0x21
-       .word   0x00eb,0x00eb
-       outb    %al,$0xA1
-       ret
-
-       /*
-        * In: EDI = address
-        * Out: FS = segment
-        *      DI = base
-        */
-convert_to_seg:
-       pushl   %eax
-
-       movl    %edi,%eax
-       //shrl  $16,%eax
-       //shll  $12,%eax
-       //movw  %ax,%fs
-
-       shrl    $4,%eax
-       movw    %ax,%fs
-       andl    $0xf,%edi
-
-       //andl  $0xFFFF,%edi
-
-       popl    %eax
-       ret
-
-       /*
-     * Here we assume the kernel is loaded at 1mb
-     * This boots the kernel
-        */
-       .code32
-EXTERN(_boot_ros)
-       call    switch_to_real
-       .code16
-
-    /* Save cursor position */
-       movw    $3,%ax          //! Reset video mode
-       int     $0x10
-
-
-       movb    $10,%bl
-       movb    $12,%ah
-       int     $0x10
-
-       movw    $0x1112,%ax      //! Use 8x8 font
-       xorb    %bl,%bl
-       int     $0x10
-       movw    $0x1200,%ax      //! Use alternate print screen
-       movb    $0x20,%bl
-       int     $0x10
-       movb    $1,%ah         //! Define cursor (scan lines 6 to 7)
-       movw    $0x0607,%cx
-       int     $0x10
-
-       movb    $1,%ah
-       movw    $0x600,%cx
-       int     $0x10
-
-       MOVb      $6,%AH        //SCROLL ACTIVE PAGE UP
-       MOVb      $0x32,%AL      //CLEAR 25 LINES
-       MOVw      $0,%CX       //UPPER LEFT OF SCROLL
-       MOVw      $0x314F,%dx    //LOWER RIGHT OF SCROLL
-       MOVb      $(1*0x10+1),%bh  //USE NORMAL ATTRIBUTE ON BLANKED LINE
-       INT       $0x10         //VIDEO-IO
-
-
-       movw     $0,%dx
-       movb     $0,%dh
-
-       movb     $2,%ah
-       movb     $0,%bh
-       int     $0x10
-
-       movw     $0,%dx
-       movb     $0,%dh
-
-       movb     $2,%ah
-       movb     $0,%bh
-       int      $0x10
-
-       cli
-
-       // The page tables are setup elsewhere
-       /*
-       // Map in the lowmem page table (and reuse it for the identity map)
-       movl    _kernel_page_directory_base,%edi
-       call    convert_to_seg
-
-       movl    _lowmem_page_table_base,%eax
-       addl    $0x07,%eax
-       movl    %eax,%fs:(%edi)
-       movl    %eax,%fs:0xd00(%edi)//(0xd0000000/(1024*1024))(%edi)
-       
-       // Map the page tables from the page directory
-       movl    _kernel_page_directory_base,%eax
-       addl    $0x07,%eax
-       movl    %eax,%fs:0xf00(%edi)//(0xf0000000/(1024*1024))(%edi)
-
-       // Map in the kernel page table
-       movl    _system_page_table_base,%eax
-       addl    $0x07,%eax
-       movl    %eax,%fs:0xc00(%edi)//(0xc0000000/(1024*1024))(%edi)
-
-       // Setup the lowmem page table
-       movl    _lowmem_page_table_base,%edi
-       call    convert_to_seg
-
-       movl    $0,%ebx
-l9:
-       movl    %ebx,%eax
-       shll    $12,%eax        // ebx = ebx * 4096
-       addl    $07,%eax        // user, rw, present
-       movl    %eax,%fs:(%edi,%ebx,4)
-       incl    %ebx
-       cmpl    $1024,%ebx
-       jl              l9
-
-       // Setup the system page table
-       movl    _system_page_table_base,%edi
-       call    convert_to_seg
-
-       movl    $07,%eax
-l8:
-       movl    %eax,%edx
-       addl    _start_kernel,%edx
-       movl    %edx,%fs:(%edi)
-       addl    $4,%edi
-       addl    $0x1000,%eax
-       cmpl    $0x100007,%eax
-       jl      l8
-       */
-
-       /*
-        * Load the page directory into cr3
-        */
-       movl    _kernel_page_directory_base,%eax
-       movl    %eax,%cr3
-
-       /*
-        * Setup various variables
-        */
-       movw    %ds,%bx
-       movzwl  %bx,%eax
-       shll    $4,%eax
-       addl    %eax,kernel_gdtbase
-
-       //call  enable_a20 // enabled elsewhere
-       call    reprogram_pic
-
-       /*
-        * Load stack
-        */
-       movw    %ds,%bx
-       movzwl  %bx,%eax
-       shll    $4,%eax
-       addl    $real_stack_end,%eax
-       movl    %eax,real_stack_base
-       movl    real_stack_base,%esp
-       movl    _boot_param_struct_base,%edx
-
-       /*
-        * load gdt
-        */
-       lgdt    kernel_gdtptr
-
-       /*       
-        * Enter pmode and clear prefetch queue
-        */
-       movl    %cr0,%eax
-       orl             $0x80010001,%eax
-       /*orl           $0x80000001,%eax*/
-       movl    %eax,%cr0
-       jmp             next
-next:
-       /*
-        * NOTE: This must be position independant (no references to
-        * non absolute variables)
-        */
-
-       /*
-        * Initalize segment registers
-        */
-       movw    $KERNEL_DS,%ax
-       movw    %ax,%ds
-       movw    %ax,%ss
-       movw    %ax,%es
-       movw    %ax,%fs
-       movw    %ax,%gs
-
-       /*
-        * Initalize eflags
-        */
-       pushl   $0
-       popfl   
-
-       /*
-        * Jump to start of 32 bit code at 0xc0000000 + 0x1000
-        */
-       pushl   %edx
-       pushl   $0
-       ljmpl   $KERNEL_CS,$(KERNEL_BASE+0x1000)
-
-
-       .p2align        2       /* force 4-byte alignment */
-kernel_gdt:
-       .word 0               // Zero descriptor
-       .word 0
-       .word 0
-       .word 0
-                        
-       //.word 0x0000          // User code descriptor
-       //.word 0x0000          // base: 0h limit: 3gb
-       //.word 0xfa00
-       //.word 0x00cc
-                       
-       //.word 0x0000          // User data descriptor
-       //.word 0x0000          // base: 0h limit: 3gb
-       //.word 0xf200
-       //.word 0x00cc
-                    
-       //.word 0x0000         
-       //.word 0x0000         
-       //.word 0x0000
-       //.word 0x0000
-
-       .word 0xffff          // Kernel code descriptor 
-       .word 0x0000          // 
-       .word 0x9a00          // base 0h limit 4gb
-       .word 0x00cf
-                       
-       .word 0xffff          // Kernel data descriptor
-       .word 0x0000          // 
-       .word 0x9200          // base 0h limit 4gb
-       .word 0x00cf
-
-    /* TSS space */    
-       //.rept NR_TASKS
-       //.word 0
-       //.word 0
-       //.word 0
-       //.word 0
-       //.endr
-
-kernel_gdtptr:
-       .word   (((6+NR_TASKS)*8)-1)    /* Limit */
-kernel_gdtbase:
-       .long   kernel_gdt                              /* Base Address */
-
-EXTERN(_boot_param_struct_base)
-       .long   0
-EXTERN(_start_mem)
-       .long   0
-EXTERN(_kernel_page_directory_base)
-       .long   0
-EXTERN(_system_page_table_base)
-       .long   0
-EXTERN(_lowmem_page_table_base)
-       .long   0
-EXTERN(_start_kernel)
-       .long   0
-EXTERN(_load_base)
-       .long   0
-
-/* boot_param structure */
-EXTERN(_boot_parameters)
-       .long   0               // Magic
-       .long   0               // Cursor X
-       .long   0               // Cursor Y
-       .long   0               // nr_files
-       .long   0               // start_mem
-       .long   0               // end_mem
-
-       .rept   64
-       .long   0               // List of module lengths (terminated by a 0)
-       .endr
-
-       .rept   256
-       .byte   0               // Kernel parameter string
-       .endr
-
-/* Our initial stack */
-real_stack:
-               .rept 1024
-               .byte 0
-               .endr
-real_stack_end:
-
-real_stack_base:
-               .long 0
index 371fe14..6b0756b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  FreeLoader
- *  Copyright (C) 1999, 2000  Brian Palmer  <brianp@sginet.com>
+ *  Copyright (C) 1999, 2000, 2001  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
 #include "stdlib.h"
 #include "fs.h"
 #include "tui.h"
+#include "multiboot.h"
 
-extern boot_param      boot_parameters;                        // Boot parameter structure passed to the kernel
-extern int     boot_param_struct_base;         // Physical address of the boot parameters structure
-extern int     start_mem;                                      // Start of the continuous range of physical kernel memory
-extern int     kernel_page_directory_base;     // Physical address of the kernel page directory
-extern int     system_page_table_base;         // Physical address of the system page table
-extern int     lowmem_page_table_base;         // Physical address of the low mem page table
-extern int     start_kernel;                           // Physical address of the start of kernel code
-extern int     load_base;                                      // Physical address of the loaded kernel modules 
+unsigned long                          next_module_load_base = 0;
 
-static int     next_load_base;
-
-void LoadAndBootReactOS(int nOSToBoot)
+void LoadAndBootReactOS(char *OperatingSystemName)
 {
        FILE            file;
        char            name[1024];
@@ -47,35 +39,27 @@ void LoadAndBootReactOS(int nOSToBoot)
        int                     nNumFilesLoaded=0;
 
        /*
-        * Enable a20 so we can load at 1mb and initialize the page tables
+        * Setup multiboot information structure
         */
-       //enable_a20(); // enabled in freeldr.c
-       ReactOSMemInit();
-
-       // Setup kernel parameters
-       boot_param_struct_base = (int)&boot_parameters;
-       boot_parameters.magic = 0xdeadbeef;
-       boot_parameters.cursorx = 0;
-       boot_parameters.cursory = 0;
-       boot_parameters.nr_files = 0;
-       boot_parameters.start_mem = start_mem;
-       boot_parameters.end_mem = load_base;
-       boot_parameters.kernel_parameters[0] = 0;
-
-       next_load_base = load_base;
+       mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
+       mb_info.mem_lower = 640;//(640 * 1024);
+       mb_info.mem_upper = (8 * 1024);
+       mb_info.boot_device = 0xffffffff;
+       mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
+       mb_info.mods_count = 0;
+       mb_info.mods_addr = (unsigned long)multiboot_modules;
+       mb_info.mmap_length = 0;
+       mb_info.mmap_addr = 0;
 
        /*
-        * Read the optional kernel parameters
+        * Read the optional kernel parameters (if any)
         */
-       if(ReadSectionSettingByName(OSList[nOSToBoot].name, "Options", name, value))
-       {
-               strcpy(boot_parameters.kernel_parameters,value);
-       }
+       ReadSectionSettingByName(OperatingSystemName, "Options", name, multiboot_kernel_cmdline);
 
        /*
         * Find the kernel image name
         */
-       if(!ReadSectionSettingByName(OSList[nOSToBoot].name, "Kernel", name, value))
+       if(!ReadSectionSettingByName(OperatingSystemName, "Kernel", name, value))
        {
                MessageBox("Kernel image file not specified for selected operating system.");
                return;
@@ -85,13 +69,16 @@ void LoadAndBootReactOS(int nOSToBoot)
         * Get the boot partition
         */
        BootPartition = 0;
-       if (ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", name, value))
+       if (ReadSectionSettingByName(OperatingSystemName, "BootPartition", name, value))
+       {
                BootPartition = atoi(value);
-
+       }
+       ((char *)(&mb_info.boot_device))[1] = (char)BootPartition;
+       
        /*
         * Make sure the boot drive is set in the .ini file
         */
-       if(!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", name, value))
+       if(!ReadSectionSettingByName(OperatingSystemName, "BootDrive", name, value))
        {
                MessageBox("Boot drive not specified for selected operating system.");
                return;
@@ -106,6 +93,7 @@ void LoadAndBootReactOS(int nOSToBoot)
         * Set the boot drive and try to open it
         */
        BootDrive = atoi(value);
+       ((char *)(&mb_info.boot_device))[0] = (char)BootDrive;
        if (!OpenDiskDrive(BootDrive, BootPartition))
        {
                MessageBox("Failed to open boot drive.");
@@ -115,27 +103,62 @@ void LoadAndBootReactOS(int nOSToBoot)
        /*
         * Parse the ini file and count the kernel and drivers
         */
-       for (i=1; i<=GetNumSectionItems(OSList[nOSToBoot].name); i++)
+       for (i=1; i<=GetNumSectionItems(OperatingSystemName); i++)
        {
                /*
                 * Read the setting and check if it's a driver
                 */
-               ReadSectionSettingByNumber(OSList[nOSToBoot].name, i, name, value);
+               ReadSectionSettingByNumber(OperatingSystemName, i, name, value);
                if ((stricmp(name, "Kernel") == 0) || (stricmp(name, "Driver") == 0))
                        nNumDriverFiles++;
        }
 
+       /*
+        * Find the kernel image name
+        * and try to load the kernel off the disk
+        */
+       if(ReadSectionSettingByName(OperatingSystemName, "Kernel", name, value))
+       {
+               /*
+                * Set the name and try to open the PE image
+                */
+               strcpy(szFileName, value);
+               if (!OpenFile(szFileName, &file))
+               {
+                       strcat(value, " not found.");
+                       MessageBox(value);
+                       return;
+               }
+
+               /*
+                * Update the status bar with the current file
+                */
+               strcpy(name, " Reading ");
+               strcat(name, value);
+               while (strlen(name) < 80)
+                       strcat(name, " ");
+               DrawStatusText(name);
+
+               /*
+                * Load the kernel image
+                */
+               MultiBootLoadKernel(&file);
+               
+               nNumFilesLoaded++;
+               DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
+       }
+
        /*
         * Parse the ini file and load the kernel and
         * load all the drivers specified
         */
-       for (i=1; i<=GetNumSectionItems(OSList[nOSToBoot].name); i++)
+       for (i=1; i<=GetNumSectionItems(OperatingSystemName); i++)
        {
                /*
                 * Read the setting and check if it's a driver
                 */
-               ReadSectionSettingByNumber(OSList[nOSToBoot].name, i, name, value);
-               if ((stricmp(name, "Kernel") == 0) || (stricmp(name, "Driver") == 0))
+               ReadSectionSettingByNumber(OperatingSystemName, i, name, value);
+               if (stricmp(name, "Driver") == 0)
                {
                        /*
                         * Set the name and try to open the PE image
@@ -160,13 +183,11 @@ void LoadAndBootReactOS(int nOSToBoot)
                        /*
                         * Load the driver
                         */
-                       ReactOSLoadPEImage(&file);
+                       MultiBootLoadModule(&file, szFileName);
+
 
                        nNumFilesLoaded++;
                        DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
-
-                       // Increment the number of files we loaded
-                       boot_parameters.nr_files++;
                }
                else if (stricmp(name, "MessageBox") == 0)
                {
@@ -185,13 +206,6 @@ void LoadAndBootReactOS(int nOSToBoot)
                }
        }
 
-       /*
-        * End the list of modules we load with a zero length entry
-        * and update the end of kernel mem
-        */
-       boot_parameters.module_lengths[boot_parameters.nr_files] = 0;
-       boot_parameters.end_mem = next_load_base;
-
        /*
         * Clear the screen and redraw the backdrop and status bar
         */
@@ -202,7 +216,7 @@ void LoadAndBootReactOS(int nOSToBoot)
         * Wait for user
         */
        strcpy(name, "Kernel and Drivers loaded.\nPress any key to boot ");
-       strcat(name, OSList[nOSToBoot].name);
+       strcat(name, OperatingSystemName);
        strcat(name, ".");
        //MessageBox(name);
 
@@ -212,179 +226,114 @@ void LoadAndBootReactOS(int nOSToBoot)
         * Now boot the kernel
         */
        stop_floppy();
-       ReactOSBootKernel();
-}
-
-void ReactOSMemInit(void)
-{
-       int             base;
-
-       /* Calculate the start of extended memory */
-       base = 0x100000;
-
-       /* Set the start of the page directory */
-       kernel_page_directory_base = base;
-
-       /*
-        * Set the start of the continuous range of physical memory
-        * occupied by the kernel
-        */
-       start_mem = base;
-       base += 0x1000;
-
-       /* Calculate the start of the system page table (0xc0000000 upwards) */
-       system_page_table_base = base;
-       base += 0x1000;
-
-       /* Calculate the start of the page table to map the first 4mb */
-       lowmem_page_table_base = base;
-       base += 0x1000;
-
-       /* Set the position for the first module to be loaded */
-       load_base = base;
-
-       /* Set the address of the start of kernel code */
-       start_kernel = base;
-}
-
-void ReactOSBootKernel(void)
-{
-       int             i;
-       int             *pPageDirectory = (int *)kernel_page_directory_base;
-       int             *pLowMemPageTable = (int *)lowmem_page_table_base;
-       int             *pSystemPageTable = (int *)system_page_table_base;
-
-       /* Zero out the kernel page directory */
-       for(i=0; i<1024; i++)
-               pPageDirectory[i] = 0;
-
-       /* Map in the lowmem page table */
-       pPageDirectory[(0x00/4)] = lowmem_page_table_base + 0x07;
-
-       /* Map in the lowmem page table (and reuse it for the identity map) */
-       pPageDirectory[(0xd00/4)] = lowmem_page_table_base + 0x07;
-       
-       /* Map the page tables from the page directory */
-       pPageDirectory[(0xf00/4)] = kernel_page_directory_base + 0x07;
-
-       /* Map in the kernel page table */
-       pPageDirectory[(0xc00/4)] = system_page_table_base + 0x07;
-
-       /* Setup the lowmem page table */
-       for(i=0; i<1024; i++)
-               pLowMemPageTable[i] = (i * 4096) + 0x07;
-
-       /* Setup the system page table */
-       for(i=0; i<1024; i++)
-               pSystemPageTable[i] = ((i * 4096) + start_kernel) + 0x07;
-
        boot_ros();
 }
 
-BOOL ReactOSLoadPEImage(FILE *pImage)
+BOOL MultiBootLoadKernel(FILE *KernelImage)
 {
-       unsigned int                    Idx, ImageBase;
-       PULONG                                  PEMagic;
-       PIMAGE_DOS_HEADER               PEDosHeader;
-       PIMAGE_FILE_HEADER              PEFileHeader;
-       PIMAGE_OPTIONAL_HEADER  PEOptionalHeader;
-       PIMAGE_SECTION_HEADER   PESectionHeaders;
-
-       ImageBase = next_load_base;
-       boot_parameters.module_lengths[boot_parameters.nr_files] = 0;
+       DWORD                           ImageHeaders[2048];
+       int                                     Idx;
+       DWORD                           dwHeaderChecksum;
+       DWORD                           dwFileLoadOffset;
+       DWORD                           dwDataSize;
+       DWORD                           dwBssSize;
 
        /*
-        * Load the headers
+        * Load the first 8192 bytes of the kernel image
+        * so we can search for the multiboot header
         */
-       ReadFile(pImage, 0x1000, (void *)next_load_base);
+       ReadFile(KernelImage, 8192, ImageHeaders);
 
        /*
-        * Get header pointers
+        * Now find the multiboot header and copy it
         */
-       PEDosHeader = (PIMAGE_DOS_HEADER) next_load_base;
-       PEMagic = (PULONG) ((unsigned int) next_load_base + 
-                               PEDosHeader->e_lfanew);
-       PEFileHeader = (PIMAGE_FILE_HEADER) ((unsigned int) next_load_base + 
-                                       PEDosHeader->e_lfanew + sizeof(ULONG));
-       PEOptionalHeader = (PIMAGE_OPTIONAL_HEADER) ((unsigned int) next_load_base + 
-                                       PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
-       PESectionHeaders = (PIMAGE_SECTION_HEADER) ((unsigned int) next_load_base + 
-                                       PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) +
-                                       sizeof(IMAGE_OPTIONAL_HEADER));
+       for (Idx=0; Idx<2048; Idx++)
+       {
+               // Did we find it?
+               if (ImageHeaders[Idx] == MULTIBOOT_HEADER_MAGIC)
+               {
+                       // Yes, copy it and break out of this loop
+                       memcpy(&mb_header, &ImageHeaders[Idx], sizeof(multiboot_header_t));
+
+                       break;
+               }
+       }
 
        /*
-        * Check file magic numbers
+        * If we reached the end of the 8192 bytes without
+        * finding the multiboot header then return error
         */
-       if(PEDosHeader->e_magic != IMAGE_DOS_MAGIC)
+       if (Idx == 2048)
        {
-               MessageBox("Incorrect MZ magic");
+               MessageBox("No multiboot header found!");
                return FALSE;
        }
-       if(PEDosHeader->e_lfanew == 0)
-       {
-               MessageBox("Invalid lfanew offset");
-               return 0;
-       }
-       if(*PEMagic != IMAGE_PE_MAGIC)
-       {
-               MessageBox("Incorrect PE magic");
-               return 0;
-       }
-       if(PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
+
+       /*printf("multiboot header:\n");
+       printf("0x%x\n", mb_header.magic);
+       printf("0x%x\n", mb_header.flags);
+       printf("0x%x\n", mb_header.checksum);
+       printf("0x%x\n", mb_header.header_addr);
+       printf("0x%x\n", mb_header.load_addr);
+       printf("0x%x\n", mb_header.load_end_addr);
+       printf("0x%x\n", mb_header.bss_end_addr);
+       printf("0x%x\n", mb_header.entry_addr);
+       getch();*/
+
+       /*
+        * Calculate the checksum and make sure it matches
+        */
+       dwHeaderChecksum = mb_header.magic;
+       dwHeaderChecksum += mb_header.flags;
+       dwHeaderChecksum += mb_header.checksum;
+       if (dwHeaderChecksum != 0)
        {
-               MessageBox("Incorrect Architecture");
-               return 0;
+               MessageBox("Multiboot header checksum invalid!");
+               return FALSE;
        }
-
+       
        /*
-        * Get header size and bump next_load_base
+        * Get the file offset, this should be 0, and move the file pointer
         */
-       next_load_base += ROUND_UP(PEOptionalHeader->SizeOfHeaders, PEOptionalHeader->SectionAlignment);
-       boot_parameters.module_lengths[boot_parameters.nr_files] += ROUND_UP(PEOptionalHeader->SizeOfHeaders, PEOptionalHeader->SectionAlignment);
-       boot_parameters.end_mem += ROUND_UP(PEOptionalHeader->SizeOfHeaders, PEOptionalHeader->SectionAlignment);
+       dwFileLoadOffset = (Idx * sizeof(DWORD)) - (mb_header.header_addr - mb_header.load_addr);
+       fseek(KernelImage, dwFileLoadOffset);
+       
+       /*
+        * Load the file image
+        */
+       dwDataSize = (mb_header.load_end_addr - mb_header.load_addr);
+       ReadFile(KernelImage, dwDataSize, (void*)mb_header.load_addr);
 
        /*
-        * Copy image sections into virtual section
+        * Initialize bss area
         */
-//  memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData);
-//  CurrentBase = (PVOID) ((DWORD)DriverBase + PESectionHeaders[0].PointerToRawData);
-//     CurrentSize = 0;
-       for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
-       {
-               /*
-                * Copy current section into current offset of virtual section
-                */
-               if (PESectionHeaders[Idx].Characteristics & 
-                       (IMAGE_SECTION_CHAR_CODE | IMAGE_SECTION_CHAR_DATA))
-               {
-                       //memcpy(PESectionHeaders[Idx].VirtualAddress + DriverBase,
-                       //      (PVOID)(ModuleLoadBase + PESectionHeaders[Idx].PointerToRawData),
-                       //      PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/);
-
-                       //MessageBox("loading a section");
-                       fseek(pImage, PESectionHeaders[Idx].PointerToRawData);
-                       ReadFile(pImage, PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/, (void *)next_load_base);
-                       //printf("PointerToRawData: %x\n", PESectionHeaders[Idx].PointerToRawData);
-                       //printf("bytes at next_load_base: %x\n", *((unsigned long *)next_load_base));
-                       //getch();
-               }
-               else
-               {
-                       //memset(PESectionHeaders[Idx].VirtualAddress + DriverBase, 
-                       //      '\0', PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/);
+       dwBssSize = (mb_header.bss_end_addr - mb_header.load_end_addr);
+       memset((void*)mb_header.load_end_addr, 0, dwBssSize);
 
-                       //MessageBox("zeroing a section");
-                       memset((void *)next_load_base, '\0', PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/);
-               }
+       next_module_load_base = ROUND_UP(mb_header.bss_end_addr, /*PAGE_SIZE*/4096);
 
-               PESectionHeaders[Idx].PointerToRawData = next_load_base - ImageBase;
+       return TRUE;
+}
 
-               next_load_base += ROUND_UP(PESectionHeaders[Idx].Misc.VirtualSize,      PEOptionalHeader->SectionAlignment);
-               boot_parameters.module_lengths[boot_parameters.nr_files] += ROUND_UP(PESectionHeaders[Idx].Misc.VirtualSize,    PEOptionalHeader->SectionAlignment);
-               boot_parameters.end_mem += ROUND_UP(PESectionHeaders[Idx].Misc.VirtualSize,     PEOptionalHeader->SectionAlignment);
+BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName)
+{
+       DWORD           dwModuleSize;
+       module_t*       pModule = &multiboot_modules[mb_info.mods_count];
+       char*           ModuleNameString = multiboot_module_strings[mb_info.mods_count];
+
+       dwModuleSize = GetFileSize(ModuleImage);
+       pModule->mod_start = next_module_load_base;
+       pModule->mod_end = next_module_load_base + dwModuleSize;
+       strcpy(ModuleNameString, ModuleName);
+       pModule->string = (unsigned long)ModuleNameString;
+       
+       /*
+        * Load the file image
+        */
+       ReadFile(ModuleImage, dwModuleSize, (void*)next_module_load_base);
 
-               //DrawProgressBar((Idx * 100) / PEFileHeader->NumberOfSections);
-       }
+       next_module_load_base = ROUND_UP(pModule->mod_end, /*PAGE_SIZE*/4096);
+       mb_info.mods_count++;
 
        return TRUE;
-}
\ No newline at end of file
+}
index 19b449e..499a513 100644 (file)
 
 #define PACKED __attribute__((packed))
 
-void   LoadAndBootReactOS(int nOSToBoot);
-void   ReactOSMemInit(void);
-void   ReactOSBootKernel(void);
-BOOL   ReactOSLoadPEImage(FILE *pImage);
+#define MB_INFO_FLAG_MEM_SIZE                  0x00000001
+#define MB_INFO_FLAG_BOOT_DEVICE               0x00000002
+#define MB_INFO_FLAG_COMMAND_LINE              0x00000004
+#define MB_INFO_FLAG_MODULES                   0x00000008
+#define MB_INFO_FLAG_AOUT_SYMS                 0x00000010
+#define MB_INFO_FLAG_ELF_SYMS                  0x00000020
+#define MB_INFO_FLAG_MEMORY_MAP                        0x00000040
+#define MB_INFO_FLAG_DRIVES                            0x00000080
+#define MB_INFO_FLAG_CONFIG_TABLE              0x00000100
+#define MB_INFO_FLAG_BOOT_LOADER_NAME  0x00000200
+#define MB_INFO_FLAG_APM_TABLE                 0x00000400
+#define MB_INFO_FLAG_GRAPHICS_TABLE            0x00000800
+
+void   LoadAndBootReactOS(char *OperatingSystemName);
+BOOL   MultiBootLoadKernel(FILE *KernelImage);
+BOOL   MultiBootLoadModule(FILE *ModuleImage, char *ModuleName);
 void   enable_a20(void);
 void   boot_ros(void);
 
 
-// WARNING:
-// This structure is prototyped here but allocated in ros.S
-// if you change this prototype make sure to update ros.S
-typedef struct
-{
-       /*
-        * Magic value (useless really)
-        */
-       unsigned int magic;
-
-       /*
-        * Cursor position
-        */
-       unsigned int cursorx;
-       unsigned int cursory;
-
-       /*
-        * Number of files (including the kernel) loaded
-        */
-       unsigned int nr_files;
-
-       /*
-        * Range of physical memory being used by the system
-        */
-       unsigned int start_mem;
-       unsigned int end_mem;
-
-       /*
-        * List of module lengths (terminated by a 0)
-        */
-       unsigned int module_lengths[64];
-
-       /*
-        * Kernel parameter string
-        */
-       char kernel_parameters[256];
-} boot_param PACKED;
-
 #endif // defined __ROSBOOT_H
\ No newline at end of file