[FREELDR]

- Convert Boot*LinuxKernel to new realmode call mechanism
- Remove switch to realmode when multiboot fails
- remove switch_to_prot and switch_to_real completely

svn path=/trunk/; revision=52329
This commit is contained in:
Timo Kreuzer 2011-06-18 10:46:06 +00:00
parent 014e413e00
commit b6ca5be6b4
7 changed files with 74 additions and 158 deletions

View file

@ -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

View file

@ -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 */

View file

@ -0,0 +1,53 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <asm.inc>
#include <arch/pc/x86common.h>
.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

View file

@ -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:

View file

@ -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)

View file

@ -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)

View file

@ -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