/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
.file "startup_raw.S"
.text
/* Tell GAS to generate 16-bit instructions so that this code works
in real mode. */
/*
* Guarantee that "main" is loaded at 0x0:0x8200.
*/
#ifdef __APPLE__
#else
#endif
/*
* This is a special data area.
*/
.long 0
.long 0
.long 0
/*
* This is the area for all of the special variables.
*/
.byte 0x00
/* the real mode code continues... */
cli /* we're not safe here! */
/* set up %ds, %ss, and %es */
sti /* we're safe again */
/* save the boot drive */
/* reset disk system (%ah = 0) */
int $0x13
/* transition to protected mode */
/* The ".code32" directive takes GAS out of 16-bit mode. */
#include "../../../kern/i386/realmode.S"
#include <rs_decoder.S>
.text
/*
* Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
* This uses the a.out kludge to load raw binary to the area starting at 1MB,
* and relocates itself after loaded.
*/
/* magic */
.long 0x1BADB002
/* flags */
.long (1 << 16)
/* checksum */
.long -0x1BADB002 - (1 << 16)
/* header addr */
/* load addr */
.long 0x100000
/* load end addr */
.long 0
/* bss end addr */
.long 0
/* entry addr */
/* obtain the boot device */
/* relocate the code */
/* jump to the real address */
/* fill the boot information */
/* enter the usual booting */
#ifdef ENABLE_LZMA
/* Don't remove this push: it's an argument. */
/* _LzmaDecodeA clears DF, so no need to run cld */
#endif
/*
* grub_gate_a20(int on)
*
* Gate address-line 20 for high memory.
*
* This routine is probably overconservative in what it does, but so what?
*
* It also eats any keystrokes in the keyboard buffer. :-(
*/
/* first of all, test if already in a good state */
/* second, try a BIOS call */
jz 1f
1: int $0x15
/*
* In macbook, the keyboard test would hang the machine, so we move
* this forward.
*/
/* fourth, try the system control port A */
inb $0x92
jz 6f
/* When turning off Gate A20, do not check the state strictly,
because a failure is not fatal usually, and Gate A20 is always
on some modern machines. */
jz 7f
7: ret
inb $0x64
2:
inb $0x64
jz 3f
inb $0x60
jmp 2b
3:
/* third, try the keyboard controller */
outb $0x64
4:
inb $0x64
jnz 4b
jz 5f
/* output a dummy command (USB keyboard hack) */
outb $0x64
/* everything failed, so restart from the beginning */
/* iterate the checking for a while */
1:
call 3f
jz 2f
loop 1b
2:
3:
/* compare the byte at 0x8000 with that at 0x108000 */
/* save the original byte in CL */
/* store the value at 0x108000 in AL */
/* try to set one less value at 0x8000 */
/* serialize */
/* obtain the value at 0x108000 in CH */
/* this result is 1 if A20 is on or 0 if it is off */
/* restore the original */
#ifdef ENABLE_LZMA
#include "lzma_decode.S"
#endif
.p2align 4