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
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
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
+
{
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!");
--- /dev/null
+/*
+ * 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
--- /dev/null
+/* 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
+++ /dev/null
-/*
- * 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
/*
* 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];
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;
* 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;
* 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.");
/*
* 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
/*
* 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)
{
}
}
- /*
- * 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
*/
* 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);
* 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
+}
#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