Author: tkreuzer
Date: Wed Jul 23 21:27:00 2008
New Revision: 34727
URL:
http://svn.reactos.org/svn/reactos?rev=34727&view=rev
Log:
Implement a LoaderEntry, a function to setup a pagetable, a function to switch to long
mode, a function to switch to real mode, Int386 to call interrupts, add some defines for
amd64, enable full debug output.
now setupldr should compile, and start it's work. It boots into long mode, reads the
memory layout from bios and finally crashes, because the page table is limited to a single
page of 2MB atm
Added:
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S (with
props)
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/int386.S (with
props)
Modified:
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/debug.c
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_base64k.rbuild
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/disk.h
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/mm.h
Added: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S (added)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S [iso-8859-1]
Wed Jul 23 21:27:00 2008
@@ -1,0 +1,303 @@
+.intel_syntax noprefix
+.text
+.code16
+
+//.org 0x8000
+
+#define STACK16ADDR 0x7000 /* The 16-bit stack top will be at 0000:7000 */
+#define STACK64ADDR 0x74000 /* The 64-bit stack top will be at 0x74000 */
+
+.global RealEntryPoint
+RealEntryPoint:
+
+ cli
+
+ /* Setup real mode segment registers */
+ xor ax, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ /* Setup a real mode stack */
+ mov sp, stack16
+
+ /* Zero BootDrive and BootPartition */
+ xor eax, eax
+ mov _BootDrive, eax
+ mov _BootPartition, eax
+
+ /* Store the boot drive */
+ mov _BootDrive, dl
+
+ /* Store the boot partition */
+ mov _BootPartition, dh
+
+ /* Load the GDT */
+ lgdt gdtptr
+ /* Load the IDT */
+// lidt idtptr
+
+ call x86_16_EnableA20
+
+ call x86_16_BuildPageTables
+
+ /* Switch to long mode */
+ call x86_16_SwitchToLong
+
+ .code64
+
+ /* GO! */
+ xor rcx, rcx
+ call _BootMain
+
+ /* Return into real mode */
+ call x86_64_SwitchToReal
+ .code16
+
+// int 0x19
+
+ /* We should never get here */
+stop:
+ jmp stop
+ nop
+ nop
+
+
+/** 16 Bit helper functions ***************************************************/
+.code16
+
+x86_16_Empty8042:
+ .word 0x00eb,0x00eb // jmp $+2, jmp $+2
+ in al, 0x64
+ cmp al, 0xff // legacy-free machine without keyboard
+ jz empty_8042_ret // controllers on Intel Macs read back 0xFF
+ test al, 0x02
+ jnz x86_16_Empty8042
+empty_8042_ret:
+ ret
+
+x86_16_EnableA20:
+ pusha
+ call x86_16_Empty8042
+ mov al, 0xD1 // command write
+ out 0x64, al
+ call x86_16_Empty8042
+ mov al, 0xDF // A20 on
+ out 0x60, al
+ call x86_16_Empty8042
+ popa
+ ret
+
+
+/*
+ * We defines one 2MB page at the start of memory, so we can access the first
+ * 2MBs as if paging was disabled
+ */
+
+#define PML4_PAGENUM 60 // Put it high enough so it doesn't interfere with freeldr
+
+#define PAGESIZE 4096
+#define PDP_PAGENUM (PML4_PAGENUM + 1)
+#define PD_PAGENUM (PDP_PAGENUM + 1)
+#define PML4_ADDRESS (PML4_PAGENUM * PAGESIZE)
+#define PDP_ADDRESS (PDP_PAGENUM * PAGESIZE)
+#define PML4_SEG (PML4_ADDRESS / 16)
+
+x86_16_BuildPageTables:
+ pusha
+ push es
+
+ mov ax, PML4_SEG
+ mov es, ax
+ cld
+ xor di, di
+
+ /* One entry in the PML4 pointing to PDP */
+ mov ax, ((PDP_PAGENUM << 12) & 0xffff) | 0x00f
+ stosw
+ mov ax, (PDP_PAGENUM >> 4)
+ stosw
+ xor ax,ax
+ mov cx, 0x07fe
+ rep stosw
+
+ /* One entry in the PDP pointing to PD */
+ mov ax, ((PD_PAGENUM << 12) & 0xffff) | 0x00f
+ stosw
+ mov ax, (PD_PAGENUM >> 4)
+ stosw
+ xor ax,ax
+ mov cx, 0x07fe
+ rep stosw
+
+ /* One entry in the PD defining a 2MB page */
+ mov ax, 0x018f
+ stosw
+ xor ax,ax
+ mov cx,0x07ff
+ rep stosw
+
+ /* Return */
+ pop es
+ popa
+ ret
+
+
+#define LMODE_CS 0x08
+#define LMODE_DS 0x10
+#define RMODE_CS 0x18 /* RMode code selector, base 0 limit 64k */
+#define RMODE_DS 0x20 /* RMode data selector, base 0 limit 64k */
+
+//.global x86_16_SwitchToLong
+x86_16_SwitchToLong:
+ cli
+
+ 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 code64ret
+
+ /* Save 16-bit stack pointer */
+ mov stack16, sp
+
+ mov eax, 0x00a0 // Set PAE and PGE: 10100000b
+ mov cr4, eax
+
+ mov edx, PML4_ADDRESS // Point cr3 at PML4
+ mov cr3, edx
+
+ mov ecx, 0xC0000080 // Specify EFER MSR
+
+ rdmsr // Enable long mode
+ or eax, 0x00000100
+ wrmsr
+
+ mov ebx, cr0 // Activate long mode
+ or ebx, 0x80000001 // by enabling paging and protection simultaneously
+ mov cr0, ebx // skipping protected mode entirely
+
+ jmp LMODE_CS:offset LongCat //Load CS with 64 bit segment and flush the instruction
cache
+
+.code64
+LongCat:
+ /* Set up 64 bit stack */
+ mov rsp, stack64
+
+ /* Put the return address back onto the stack */
+ push qword ptr code64ret
+
+ /* Now return in long mode! */
+ ret
+
+
+/** 64 But functions **********************************************************/
+.code64
+
+.global x86_64_SwitchToReal
+x86_64_SwitchToReal:
+
+ /* Get the return address off the stack */
+ pop qword ptr code64ret
+
+ /* Save 64-bit stack pointer */
+ mov stack64, rsp
+
+ /* Step 1 - deactivate long mode, by disabling paging */
+ mov rax, cr0
+ and rax, 0x000000007fffffff //~0x80000000
+ mov cr0, rax
+
+ /* Step 2 - disable long mode in EFER MSR */
+ mov rcx, 0xC0000080 // Specify EFER MSR
+ rdmsr
+ and eax, ~0x00000100 // Disable EFER.LME
+ wrmsr
+
+ .code32
+ /* jmp to 16-bit segment to set the limit correctly */
+ jmp RMODE_CS: offset SwitchToReal2
+
+SwitchToReal2:
+ .code16
+
+ /* Step 3 - Disable Protected Mode */
+ mov eax, cr0
+ and eax, ~0x00000001
+ mov cr0, eax
+
+ /* Clear prefetch queue & correct CS */
+ jmp 0:offset BeReal
+
+BeReal:
+ /* Restore segment registers */
+ mov ax, 0
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ /* Rstore 16 bit stack */
+ mov sp, stack16
+
+// lidt rmode_idtptr /* Load IDTR with real mode value */
+
+// sti /* These are ok now */
+
+ /* Put the return address back onto the stack */
+ push word ptr code64ret
+
+ /* Now return in real mode! */
+ ret
+
+
+/** Some data *****************************************************************/
+
+.code64
+
+stack16:
+ .quad STACK16ADDR
+
+stack64:
+ .quad STACK64ADDR
+
+code64ret:
+ .quad 0
+
+gdt:
+ .quad 0x0000000000000000
+ .quad 0x0020980000000000
+ .quad 0x0000900000000000
+ .word 0xFFFF, 0x0000, 0x9E00, 0x0000 /* 16-bit real mode CS */
+ .word 0xFFFF, 0x0000, 0x9200, 0x0000 /* 16-bit real mode DS */
+
+/* GDT table pointer */
+gdtptr:
+ .word 0x27 /* Limit */
+ .long gdt /* Base Address */
+
+
+.global _BootDrive
+_BootDrive:
+ .long 0
+
+.global _BootPartition
+_BootPartition:
+ .long 0
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+/* Need to include them here, because of linking issues between 64 / 16 bit */
+//#include "debug16.S"
+#include "int386.S"
+#include "boot.S"
+#include "i386pnp.S"
+
Propchange: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/arch.S
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/int386.S
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/int386.S (added)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/int386.S
[iso-8859-1] Wed Jul 23 21:27:00 2008
@@ -1,0 +1,170 @@
+/*
+ * FreeLoader
+ * Copyright (C) 1998-2002 Brian Palmer <brianp(a)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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+ .intel_syntax noprefix
+ .text
+ .code16
+
+#define ASM
+#include <arch.h>
+
+
+Int386_REGS:
+
+Int386_eax:
+ .long 0
+Int386_ebx:
+ .long 0
+Int386_ecx:
+ .long 0
+Int386_edx:
+ .long 0
+
+Int386_esi:
+ .long 0
+Int386_edi:
+ .long 0
+
+Int386_ds:
+ .word 0
+Int386_es:
+ .word 0
+Int386_fs:
+ .word 0
+Int386_gs:
+ .word 0
+
+Int386_eflags:
+ .long 0
+
+Int386_vector:
+ .quad 0
+Int386_regsin:
+ .quad 0
+Int386_regsout:
+ .quad 0
+
+/*
+ * int Int386(int ivec, REGS* in, REGS* out);
+ */
+EXTERN(_Int386)
+ .code64
+
+ /* Get the function parameters */
+ mov Int386_vector, rcx
+ mov Int386_vector_opcode, cl
+ mov Int386_regsin, rdx
+ mov Int386_regsout, r8
+
+ /* Save all registers + segment registers */
+// push ds
+// push es
+ push fs
+ push gs
+ push rbx
+ push rcx
+ push rdx
+ push rsi
+ push rdi
+
+ /* Copy the input regs to our variables */
+ lea rdi, Int386_REGS
+ mov esi, Int386_regsin
+ mov ecx, 0x24
+ rep movsb
+
+ call x86_64_SwitchToReal
+ .code16
+
+ /* Setup the registers */
+ mov ax, cs:Int386_ds
+ mov ds, ax /* DS register */
+ mov ax, cs:Int386_es
+ mov es, ax /* ES register */
+ mov ax, cs:Int386_fs
+ mov fs, ax /* FS register */
+ mov ax, cs:Int386_gs
+ mov gs, ax /* GS register */
+
+ mov eax, cs:Int386_eax /* EAX register */
+ mov ebx, cs:Int386_ebx /* EBX register */
+ mov ecx, cs:Int386_ecx /* ECX register */
+ mov edx, cs:Int386_edx /* EDX register */
+
+ mov esi, cs:Int386_esi /* ESI register */
+ mov edi, cs:Int386_edi /* EDI register */
+
+ /* Do not set the flags register */
+ /* only return its value in regsout */
+ //pushl Int386_eflags
+ //popfl /* EFLAGS register */
+
+ /* Call the interrupt vector */
+ /*int Int386_vector*/
+Int386_int_opcode:
+ .byte 0xcd
+Int386_vector_opcode:
+ .byte 0x00
+
+ /* Save the registers */
+ mov cs:Int386_eax, eax /* EAX register */
+ mov cs:Int386_ebx, ebx /* EBX register */
+ mov cs:Int386_ecx, ecx /* ECX register */
+ mov cs:Int386_edx, edx /* EDX register */
+
+ mov cs:Int386_esi, esi /* ESI register */
+ mov cs:Int386_edi, edi /* EDI register */
+
+ mov ax, ds /* DS register */
+ mov cs:Int386_ds, ax
+ mov ax, es /* ES register */
+ mov cs:Int386_es, ax
+ mov ax, fs /* FS register */
+ mov cs:Int386_fs, ax
+ mov ax, gs /* GS register */
+ mov cs:Int386_gs, ax
+
+ pushf
+ pop cs:Int386_eflags /* EFLAGS register */
+
+ call x86_16_SwitchToLong
+ .code64
+
+ /* Copy the variables to the output regs */
+ lea rsi, Int386_REGS
+ mov rdi, Int386_regsout
+ mov rcx, 0x24
+ rep movsb
+
+ /* Restore segment and all other registers */
+ pop rdi
+ pop rsi
+ pop rdx
+ pop rcx
+ pop rbx
+ pop gs
+ pop fs
+// pop es
+// pop ds
+
+ /* Get return value */
+ xor rax, rax
+ mov eax, Int386_eax
+
+ ret
Propchange: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/int386.S
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/debug.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/debug.c [iso-8859-1]
(original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/debug.c [iso-8859-1] Wed Jul
23 21:27:00 2008
@@ -23,11 +23,11 @@
#ifdef DBG
-//#define DEBUG_ALL
+#define DEBUG_ALL
//#define DEBUG_INIFILE
//#define DEBUG_REACTOS
//#define DEBUG_CUSTOM
-#define DEBUG_NONE
+//#define DEBUG_NONE
#if defined (DEBUG_ALL)
ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
@@ -243,7 +243,7 @@
VOID DebugPrint(ULONG Mask, char *format, ...)
{
va_list ap;
- char Buffer[4096];
+ char Buffer[2096];
char *ptr = Buffer;
// Mask out unwanted debug messages
@@ -271,7 +271,7 @@
VOID DebugPrint1(char *format, ...)
{
va_list ap;
- char Buffer[4096];
+ char Buffer[2096];
char *ptr = Buffer;
va_start(ap, format);
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
[iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
[iso-8859-1] Wed Jul 23 21:27:00 2008
@@ -84,6 +84,7 @@
<file>i386disk.c</file>
<file>i386rtl.c</file>
<file>i386vid.c</file>
+ <file>loader.c</file>
<file>pccons.c</file>
<file>pcdisk.c</file>
<file>pcmem.c</file>
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_base64k.rbuild
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_base64k.rbuild
[iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/freeldr_base64k.rbuild
[iso-8859-1] Wed Jul 23 21:27:00 2008
@@ -26,7 +26,6 @@
<file>i386cpu.S</file>
<file>i386idt.S</file>
<file>i386trap.S</file>
- <!-- file>linux.S</file -->
<file>mb.S</file>
</directory>
</if>
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/disk.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1]
(original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1]
Wed Jul 23 21:27:00 2008
@@ -106,14 +106,14 @@
// i386 BIOS Disk Functions (i386disk.c)
//
///////////////////////////////////////////////////////////////////////////////////////
-#ifdef __i386__
+#if defined(__i386__) || defined(_M_AMD64)
BOOLEAN DiskResetController(ULONG DriveNumber);
BOOLEAN DiskInt13ExtensionsSupported(ULONG DriveNumber);
//VOID DiskStopFloppyMotor(VOID);
BOOLEAN DiskGetExtendedDriveParameters(ULONG DriveNumber, PVOID Buffer, USHORT
BufferSize);
-#endif // defined __i386__
+#endif // defined __i386__ || defined(_M_AMD64)
///////////////////////////////////////////////////////////////////////////////////////
//
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/mm.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/mm.h [iso-8859-1]
(original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/mm.h [iso-8859-1] Wed
Jul 23 21:27:00 2008
@@ -49,6 +49,17 @@
( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) )
#endif // defined __i386__ or _PPC_ or _MIPS_
+
+#if defined (_AMD64_)
+
+#define MM_PAGE_SIZE 4096
+#define MM_PAGE_MASK 0xFFF
+#define MM_PAGE_SHIFT 12
+
+#define MM_SIZE_TO_PAGES(a) \
+ ( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) )
+
+#endif
// HEAP and STACK size
#define HEAP_PAGES 0x400