/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB 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 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 .
*/
#include
.p2align 4 /* force 16-byte alignment */
VARIABLE(grub_linux_trampoline_start)
cli
/* %rdi contains protected memory start and %rsi
contains real memory start. */
mov %rsi, %rbx
call base
base:
pop %rsi
lea (cont1-base)(%rsi, 1), %rax
mov %eax, (jump_vector-base)(%rsi,1)
lea (gdt-base)(%rsi, 1), %rax
mov %rax, (gdtaddr-base)(%rsi,1)
/* Switch to compatibility mode. */
lidt (idtdesc-base)(%rsi,1)
lgdt (gdtdesc-base)(%rsi,1)
/* Update %cs. Thanks to David Miller for pointing this mistake out. */
ljmp *(jump_vector-base)(%rsi,1)
cont1:
.code32
/* Update other registers. */
mov $0x18, %eax
mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
mov %eax, %ss
/* Disable paging. */
mov %cr0, %eax
and $0x7fffffff, %eax
mov %eax, %cr0
/* Disable amd64. */
mov $0xc0000080, %ecx
rdmsr
and $0xfffffeff, %eax
wrmsr
/* Turn off PAE. */
movl %cr4, %eax
and $0xffffffcf, %eax
mov %eax, %cr4
jmp cont2
cont2:
.code32
mov %ebx, %esi
jmp *%edi
/* GDT. */
.p2align 4
gdt:
/* NULL. */
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
/* Reserved. */
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
/* Code segment. */
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
/* Data segment. */
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
gdtdesc:
.word 31
gdtaddr:
.quad gdt
idtdesc:
.word 0
idtaddr:
.quad 0
.p2align 4
jump_vector:
/* Jump location. Is filled by the code */
.long 0
.long 0x10
VARIABLE(grub_linux_trampoline_end)