mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
Multiboot Kernel Compliance
svn path=/trunk/; revision=1945
This commit is contained in:
parent
49e30c043c
commit
4531d3752a
8 changed files with 600 additions and 631 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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!");
|
||||
|
|
260
freeldr/freeldr/multiboot.S
Normal file
260
freeldr/freeldr/multiboot.S
Normal file
|
@ -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
|
129
freeldr/freeldr/multiboot.h
Normal file
129
freeldr/freeldr/multiboot.h
Normal file
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
@ -24,19 +24,11 @@
|
|||
#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));
|
||||
|
||||
/*
|
||||
* Check file magic numbers
|
||||
*/
|
||||
if(PEDosHeader->e_magic != IMAGE_DOS_MAGIC)
|
||||
for (Idx=0; Idx<2048; Idx++)
|
||||
{
|
||||
MessageBox("Incorrect MZ magic");
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we reached the end of the 8192 bytes without
|
||||
* finding the multiboot header then return error
|
||||
*/
|
||||
if (Idx == 2048)
|
||||
{
|
||||
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)
|
||||
{
|
||||
MessageBox("Incorrect Architecture");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*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();*/
|
||||
|
||||
/*
|
||||
* Get header size and bump next_load_base
|
||||
* Calculate the checksum and make sure it matches
|
||||
*/
|
||||
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);
|
||||
dwHeaderChecksum = mb_header.magic;
|
||||
dwHeaderChecksum += mb_header.flags;
|
||||
dwHeaderChecksum += mb_header.checksum;
|
||||
if (dwHeaderChecksum != 0)
|
||||
{
|
||||
MessageBox("Multiboot header checksum invalid!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the file offset, this should be 0, and move the file pointer
|
||||
*/
|
||||
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*/);
|
||||
dwBssSize = (mb_header.bss_end_addr - mb_header.load_end_addr);
|
||||
memset((void*)mb_header.load_end_addr, 0, dwBssSize);
|
||||
|
||||
//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*/);
|
||||
|
||||
//MessageBox("zeroing a section");
|
||||
memset((void *)next_load_base, '\0', PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/);
|
||||
}
|
||||
|
||||
PESectionHeaders[Idx].PointerToRawData = next_load_base - ImageBase;
|
||||
|
||||
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);
|
||||
|
||||
//DrawProgressBar((Idx * 100) / PEFileHeader->NumberOfSections);
|
||||
}
|
||||
next_module_load_base = ROUND_UP(mb_header.bss_end_addr, /*PAGE_SIZE*/4096);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
next_module_load_base = ROUND_UP(pModule->mod_end, /*PAGE_SIZE*/4096);
|
||||
mb_info.mods_count++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -26,50 +26,24 @@
|
|||
|
||||
#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
|
Loading…
Reference in a new issue