138786Sdfr/** 238786Sdfr * \file 338786Sdfr * \brief Bootstrap the bootloader. 438786Sdfr */ 538786Sdfr 638786Sdfr/* 738786Sdfr * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich. 838786Sdfr * All rights reserved. 938786Sdfr * 1038786Sdfr * This file is distributed under the terms in the attached LICENSE file. 1138786Sdfr * If you do not find this file, copies can be found by writing to: 1238786Sdfr * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 1338786Sdfr */ 1438786Sdfr 1538786Sdfr#include <multiboot.h> 1638786Sdfr 1738786Sdfr#define STACK_SIZE 4096 1838786Sdfr 1938786Sdfr#define MSR_IA32_EFER 0xc0000080 ///< Extended features enables 2038786Sdfr#define PAGING_ENABLE 31 2138786Sdfr#define LONG_MODE_CS 0x0008 2238786Sdfr#define PAE 0x20 2338786Sdfr#define LME 8 2438786Sdfr 2538786Sdfr/* The flags for the Multiboot header */ 2638786Sdfr#define MB_FLAGS (MULTIBOOT_HEADER_FLAG_MODS_PGALIGNED | MULTIBOOT_HEADER_FLAG_NEED_MEMINFO) 2738786Sdfr 2838786Sdfr.code32 2950476Speter.text 3038786Sdfr.globl start, halt 31231244Sgjb 3238786Sdfr/* Multiboot header, 4-byte aligned */ 3379538Sru .align 4 3438786Sdfr .long MULTIBOOT_HEADER_MAGIC /* magic */ 3538786Sdfr .long MB_FLAGS /* flags */ 3638786Sdfr .long -(MULTIBOOT_HEADER_MAGIC + MB_FLAGS) /* checksum */ 3738786Sdfr 3884306Srustart: 3984306Sru /* Initialize the stack pointer */ 4038786Sdfr movl $(stack + STACK_SIZE), %esp 4138786Sdfr 4238786Sdfr /* Reset EFLAGS */ 43139772Skeramida pushl $0 44139772Skeramida popf 45139772Skeramida 4669052Sru /* Enter main -- this should never return */ 4769052Sru push %ebp 4869052Sru mov %esp, %ebp 4957695Ssheldonh push %ebx /* Pointer to multiboot info struct */ 5057695Ssheldonh push %eax /* Multiboot magic value */ 5157695Ssheldonh call startup 5247984Sn_hibma 53121379Shmp // Load 64-bit GDT 54121379Shmp mov $gdt_ptr, %esi 55121379Shmp lgdt (%esi) 56121379Shmp 5792566Sru // enable page address extension 5892566Sru mov %cr4,%eax 5992566Sru or $PAE,%eax 6047984Sn_hibma mov %eax,%cr4 6138786Sdfr 6247984Sn_hibma // set PML4 pointer to cr3 6347984Sn_hibma mov $boot_pml4, %eax 6457695Ssheldonh mov %eax,%cr3 6557695Ssheldonh 6647984Sn_hibma // enable long-mode by setting EFER.LME 6747984Sn_hibma mov $MSR_IA32_EFER,%ecx 6857695Ssheldonh rdmsr 69128104Simp bts $LME,%eax 70128104Simp wrmsr 71128104Simp 72128104Simp // enable paging 73128104Simp mov %cr0,%eax 7457695Ssheldonh bts $PAGING_ENABLE,%eax 75128104Simp mov %eax,%cr0 76128104Simp 77133526Simp // Setup multiboot registers 78133526Simp mov eax, %eax 7938786Sdfr mov multiboot_info, %ebx 8047984Sn_hibma mov kernel_entry, %ecx 81131530Sru 82131530Sru // jmp to long-mode to the linear address corresponding the 8347984Sn_hibma // real mode segment REAL_MODE_SEGMENT 84108260Sru // jmp LONG_MODE_CS:start_64 85131530Sru .byte 0xea 86176966Simp .long start_64 87176966Simp .word LONG_MODE_CS 88176966Simp 89176966Simp/* start the 64bit long-mode code here */ 90176966Simp.code64 91176966Simpstart_64: 92176966Simp 93176966Simp // initialize bootup stack for the 64bit long mode 94211397Sjoel lea (start_64_stack)(%rip), %rsp 95176966Simp // Jump to kernel image entry 96176966Simp jmp *%rcx 97176966Simp 98176966Simp/* Halt -- this should never be reached */ 99233648Seadlerhalt: 100176966Simp hlt 101176966Simp jmp halt 102176966Simp 103176966Simp/* Stack for 64bit mode */ 104176966Simp .comm stack, STACK_SIZE 105176966Simp .align 16 106176966Simp .fill STACK_SIZE,1,0 107176966Simpstart_64_stack: 108176966Simp 109176966Simp/* Global descriptor table */ 110176966Simp.align 16 111176966Simpgdt: 112176966Simp .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 113176966Simp .byte 0xff,0xff,0x00,0x00,0x00,0x9a,0xaf,0x00 // 64bit code segment, D _cleared_ => "16bit" 114176966Simp .byte 0xff,0xff,0x00,0x00,0x00,0x92,0xcf,0x00 // data 115176966Simp .byte 0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00 // 32bit code segment for protected-mode 116176966Simp .byte 0xff,0xff,0x00,0x80,0x0b,0x92,0xff,0x00 // screen 117210669Sjoel .byte 0xff,0xff,0x00,0x60,0x00,0x9a,0xcf,0x00 // segment at linear address 0x6000 118176966Simp .byte 0xff,0xff,0x00,0x00,0x00,0x92,0xaf,0x00 // stack segment in 64bit mode 119176966Simp 120176966Simpgdt_ptr: 121176966Simp .word gdt_ptr - gdt 122233648Seadler .long gdt 123233648Seadler .long 0 124176966Simp