diff --git a/reactos/boot/freeldr/freeldr/CMakeLists.txt b/reactos/boot/freeldr/freeldr/CMakeLists.txt index 17db1a68bd4..08499861383 100644 --- a/reactos/boot/freeldr/freeldr/CMakeLists.txt +++ b/reactos/boot/freeldr/freeldr/CMakeLists.txt @@ -15,11 +15,11 @@ if(ARCH MATCHES i386) arch/i386/i386trap.S arch/i386/i386pnp.cmake.S arch/i386/i386bug.c + arch/i386/linux.cmake.S arch/i386/mb.S) if(NOT MSVC) list(APPEND FREELDR_BASE64K_SOURCE arch/i386/drvmap.S - arch/i386/linux.S arch/i386/multiboot.S) else() list(APPEND FREELDR_BASE64K_SOURCE diff --git a/reactos/boot/freeldr/freeldr/arch/i386/entry.S b/reactos/boot/freeldr/freeldr/arch/i386/entry.S index 816ae641f8e..6a9c76696bc 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/entry.S +++ b/reactos/boot/freeldr/freeldr/arch/i386/entry.S @@ -82,151 +82,6 @@ stop: nop nop -#ifndef _USE_ML -/* - * Switches the processor to protected mode - * it destroys eax - */ -EXTERN(switch_to_prot) - -.code16 - - cli /* None of these */ - - /* We don't know what values are currently */ - /* in the segment registers. So we are */ - /* going to reload them with sane values. */ - /* Of course CS has to already be valid. */ - /* We are currently in real-mode so we */ - /* need real-mode segment values. */ - xor ax, ax - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - /* Get the return address off the stack */ - pop word ptr ds:[code32ret] - - /* Save 16-bit stack pointer */ - mov word ptr ds:[stack16], sp - - /* Load the GDT */ - lgdt gdtptr - - /* Load the IDT */ - lidt i386idtptr - - /* Enable Protected Mode */ - mov eax, cr0 - or eax, CR0_PE_SET - mov cr0, eax - - /* Clear prefetch queue & correct CS */ - //ljmp PMODE_CS, inpmode - jmp far ptr PMODE_CS:inpmode - -.code32 - -inpmode: - /* Setup segment selectors */ - mov ax, PMODE_DS - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - mov esp, dword ptr [stack32] - - /* Put the return address back onto the stack */ - push dword ptr [code32ret] - - /* Now return in p-mode! */ - ret - -/* - * Switches the processor back to real mode - * it destroys eax - */ -EXTERN(switch_to_real) - -.code32 - - /* We don't know what values are currently */ - /* in the segment registers. So we are */ - /* going to reload them with sane values. */ - /* Of course CS has to already be valid. */ - /* We are currently in protected-mode so we */ - /* need protected-mode segment values. */ - mov ax, PMODE_DS - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - /* Get the return address off the stack */ - pop dword ptr [code16ret] - - /* Save 32-bit stack pointer */ - mov dword ptr [stack32], esp - - /* jmp to 16-bit segment to set the limit correctly */ - ljmp RMODE_CS, switch_to_real16 - -switch_to_real16: -.code16 - - /* Restore segment registers to correct limit */ - mov ax, RMODE_DS - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - /* Disable Protected Mode */ - mov eax, cr0 - and eax, CR0_PE_CLR - mov cr0, eax - - /* Clear prefetch queue & correct CS */ - //ljmp $0, $inrmode - jmp far ptr 0:inrmode - -inrmode: - mov ax, cs - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - /* Clear out the high 16-bits of ESP */ - /* This is needed because I have one */ - /* machine that hangs when booted to dos if */ - /* anything other than 0x0000 is in the high */ - /* 16-bits of ESP. Even though real-mode */ - /* code should only use SP and not ESP. */ - xor esp, esp - - mov sp, word ptr ds:[stack16] - - /* Put the return address back onto the stack */ - push word ptr ds:[code16ret] - - /* Load IDTR with real mode value */ - lidt rmode_idtptr - - sti /* These are ok now */ - - /* Now return in r-mode! */ - ret -#endif - -.code32 - Int386_regsin: .long 0 Int386_regsout: @@ -390,15 +245,6 @@ stack16: stack32: .long STACK32ADDR - /* 16-bit return address */ -code16ret: - .long 0 - - /* 32-bit return address */ -code32ret: - .long 0 - - .align 4 /* force 4-byte alignment */ gdt: /* NULL Descriptor */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/linux.cmake.S b/reactos/boot/freeldr/freeldr/arch/i386/linux.cmake.S new file mode 100644 index 00000000000..a0363810c4a --- /dev/null +++ b/reactos/boot/freeldr/freeldr/arch/i386/linux.cmake.S @@ -0,0 +1,53 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +.code32 + +/* + * VOID BootOldLinuxKernel(ULONG KernelSize); + */ +PUBLIC _BootOldLinuxKernel +_BootOldLinuxKernel: + + /* First we have to copy the kernel down from 0x100000 to 0x10000 */ + /* The reason we can overwrite low memory is because this code */ + /* executes between 0000:8000 and 0000:FFFF. That leaves space for */ + /* 32k of code before we start interfering with Linux kernel address space. */ + + /* Get KernelSize in ECX and move the kernel down */ + mov ecx, [esp + 4] + mov esi, HEX(100000) + mov edi, HEX(10000) + rep movsb + + /* Fall through */ + +PUBLIC _BootNewLinuxKernel +_BootNewLinuxKernel: + + mov bx, FNID_BootLinuxKernel + call i386CallRealMode + + /* We should never get here */ + int 3 + +END diff --git a/reactos/boot/freeldr/freeldr/arch/i386/multiboot.S b/reactos/boot/freeldr/freeldr/arch/i386/multiboot.S index 3eff7b2caa9..5c1e7241dd1 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/multiboot.S +++ b/reactos/boot/freeldr/freeldr/arch/i386/multiboot.S @@ -163,9 +163,7 @@ mb7: call _BootMain mbfail: - call switch_to_real - .code16 - int 0x19 + int 3 mbstop: jmp mbstop /* We should never get here */ mb_info: diff --git a/reactos/boot/freeldr/freeldr/arch/realmode/i386.S b/reactos/boot/freeldr/freeldr/arch/realmode/i386.S index 4bcafc9511c..5387cf93875 100644 --- a/reactos/boot/freeldr/freeldr/arch/realmode/i386.S +++ b/reactos/boot/freeldr/freeldr/arch/realmode/i386.S @@ -139,6 +139,7 @@ callback_table: .word PxeCallApi .word PnpBiosGetDeviceNodeCount .word PnpBiosGetDeviceNode + .word BootLinuxKernel /* 16-bit stack pointer */ @@ -191,6 +192,7 @@ rmode_idtptr: #include "int386.inc" #include "pxe.inc" #include "pnp.inc" +#include "linux.inc" #include "helpers.inc" .org (FREELDR_PE_BASE - FREELDR_BASE - 1) diff --git a/reactos/boot/freeldr/freeldr/arch/realmode/linux.inc b/reactos/boot/freeldr/freeldr/arch/realmode/linux.inc new file mode 100644 index 00000000000..c8fb0e9a4a8 --- /dev/null +++ b/reactos/boot/freeldr/freeldr/arch/realmode/linux.inc @@ -0,0 +1,16 @@ + + +BootLinuxKernel: + // dl must be set to the boot drive + + /* Load segment registers */ + cli + mov bx, HEX(9000) + mov ds, bx + mov es, bx + mov fs, bx + mov gs, bx + mov ss, bx + mov sp, HEX(9000) + + ljmp16 HEX(9020), HEX(0000) diff --git a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h index d31a3cebf31..595d07df043 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h +++ b/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h @@ -49,6 +49,7 @@ #define FNID_PxeCallApi 3 #define FNID_PnpBiosGetDeviceNodeCount 4 #define FNID_PnpBiosGetDeviceNode 5 +#define FNID_BootLinuxKernel 6 /* Layout of the REGS structure */ #define REGS_EAX 0