Author: tkreuzer
Date: Thu Aug 25 14:43:15 2011
New Revision: 53443
URL:
http://svn.reactos.org/svn/reactos?rev=53443&view=rev
Log:
[FREELDR]
- Implement real mode entry point for amd64 (amd64 freeldr starts but dies later, it
cannot yet switch back to real mode, which is a bit more complicated)
- delete empty folders
Removed:
trunk/reactos/boot/freeldr/freeldr/windows/amd64/
trunk/reactos/boot/freeldr/freeldr/windows/arm/
trunk/reactos/boot/freeldr/freeldr/windows/i386/
Modified:
trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt
trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S
trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S
trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
Modified: trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/CMake…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] Thu Aug 25 14:43:15
2011
@@ -1,7 +1,12 @@
-if(ARCH MATCHES i386 OR ARCH MATCHES amd64)
+if(ARCH MATCHES i386)
CreateBootSectorTarget2(frldr16
${CMAKE_CURRENT_SOURCE_DIR}/arch/realmode/i386.S
+ ${CMAKE_CURRENT_BINARY_DIR}/frldr16.bin
+ F800)
+elseif(ARCH MATCHES amd64)
+ CreateBootSectorTarget2(frldr16
+ ${CMAKE_CURRENT_SOURCE_DIR}/arch/realmode/amd64.S
${CMAKE_CURRENT_BINARY_DIR}/frldr16.bin
F800)
endif()
Modified: trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S [iso-8859-1] Thu Aug 25 14:43:15
2011
@@ -3,10 +3,20 @@
#include <asm.inc>
#include <arch/pc/x86common.h>
+EXTERN BootMain:PROC
+
.code64
PUBLIC RealEntryPoint
RealEntryPoint:
+ //mov ax, LMODE_DS
+ //mov ds, ax
+ //mov word ptr [HEX(b8000)], HEX(0e00) + '1'
+
+ /* GO! */
+ xor rcx, rcx
+ call BootMain
+
PUBLIC FrldrBootDrive
FrldrBootDrive:
Modified: trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S [iso-8859-1] Thu Aug 25
14:43:15 2011
@@ -1,8 +1,8 @@
#include <asm.inc>
-#include <arch/pc/x86common.h>
-
-#define IMAGE_DOS_HEADER_e_lfanew 36
+#include "../../include/arch/pc/x86common.h"
+
+#define IMAGE_DOS_HEADER_e_lfanew 60
#define IMAGE_FILE_HEADER_SIZE 20
#define IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint 16
@@ -13,7 +13,7 @@
#include "fathelp.inc"
.org 512
-RealEntryPoint:
+Startup:
cli
@@ -25,41 +25,98 @@
mov gs, ax
mov ss, ax
- /* checkPoint Charlie - where it all began... */
- mov si, offset CheckPoint0
- call writestr
-
/* 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
+ mov sp, word ptr ds:[stack16]
+
+ /* Output first status */
+ mov si, offset Msg_Starting
+ call writestr
+
+ /* Enable A20 address line */
+ call EnableA20
+
+ /* Check the CPU */
+ call CheckFor64BitSupport
+ test al, al
+ jnz .LongModeSupported
+
+ /* Output failure message */
+ mov si, offset Msg_Unsupported
+ call writestr
+
+ /* Wait for a keypress */
+ int HEX(16)
+ jmp SoftReboot
+
+Msg_Unsupported:
+ .ascii "This CPU is not supported.", CR, LF
+ .ascii "Press any key to reboot...", NUL
+
+Msg_Starting:
+ .ascii "Starting FreeLoader...", CR, LF, NUL
+
+Msg_LongModeSupported:
+ .ascii "Long mode support detected.", CR, LF, NUL
+
+.LongModeSupported:
+ /* Output status */
+ mov si, offset Msg_LongModeSupported
+ call writestr
/* Load the GDT */
- lgdt gdtptr
- /* Load the IDT */
-// lidt idtptr
-
- call x86_16_EnableA20
-
- /* checkPoint Charlie - where it all began... */
- mov si, offset CheckPoint1
- call writestr
-
- call x86_16_BuildPageTables
-
- /* checkPoint Charlie - where it all began... */
- mov si, offset CheckPoint2
- call writestr
-
+ lgdt fword ptr [gdtptr]
+
+ /* Build the startup page tables */
+ call BuildPageTables
+
+ /* Safe real mode entry point in shared memory */
+ mov dword ptr ds:[BSS_RealModeEntry], offset RealModeEntryPoint
+
+ /* Address the image with es segment */
+ mov ax, FREELDR_PE_BASE / 16
+ mov es, ax
+
+ /* Get address of optional header */
+ mov eax, dword ptr es:[IMAGE_DOS_HEADER_e_lfanew]
+ add eax, 4 + IMAGE_FILE_HEADER_SIZE
+
+ /* Get address of entry point */
+ mov eax, dword ptr es:[eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint]
+ add eax, FREELDR_PE_BASE
+
+ /* Save entry point */
+ mov dword ptr ds:[LongModeEntryPoint], eax
+
+ /* Restore es */
+ xor ax, ax
+ mov es, ax
+
+ /* Output status */
+ mov si, offset Msg_SwitchToLongMode
+ call writestr
+
+ jmp ExitToLongMode
+
+Msg_SwitchToLongMode:
+ .ascii "Switching to long mode....", CR, LF, NUL
+
+.align 4
+gdt:
+ .word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */
+ .word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 08: */
+ .word HEX(0000), HEX(0000), HEX(9800), HEX(0020) /* 10: long mode cs */
+ .word HEX(ffff), HEX(0000), HEX(f300), HEX(00cf) /* 18: long mode ds */
+ .word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 16-bit real mode CS */
+ .word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 16-bit real mode DS */
+ .word HEX(FFFF), HEX(0000), HEX(9B00), HEX(00CF) /* 30: compat mode cs */
+
+/* GDT table pointer */
+gdtptr:
+ .word HEX(37) /* Limit */
+ .long offset gdt /* Base Address */
+
+
+CheckFor64BitSupport:
/* Check if CPU supports CPUID */
pushfd
pop eax
@@ -70,107 +127,97 @@
pushfd
pop eax
cmp eax,ebx
- jz no_cpuid_support_detected
-
+ jnz .CheckForPAE
+
+ mov si, offset .Msg_NoCpuidSupport
+ call writestr
+ xor al, al
+ ret
+
+.Msg_NoCpuidSupport:
+ .ascii "The system doesn't support CPUID.", CR, LF, NUL
+
+.CheckForPAE:
/* CPUID support detected - getting the PAE/PGE */
-
mov eax,1 // Fn0000_0001 - PAE in EDX[6]
cpuid
- xor eax,eax
and edx, HEX(00a0)
- test edx,edx // are PAE and PGE bits set?
- jz no_x64_support_detected
-
- /* PAE and PGE are here */
-
+ cmp edx, HEX(00a0)
+ je .CheckForLongMode
+
+ mov si, offset .Msg_NoPAE
+ call writestr
+ xor al, al
+ ret
+
+.Msg_NoPAE:
+ .ascii "PAE or PGE not set.", CR, LF, NUL
+
+.CheckForLongMode:
xor edx, edx
mov eax, HEX(80000001)
cpuid
and edx, HEX(20000000)
test edx,edx
- jz no_x64_support_detected
-
- /* X64 Processor */
-
- /* checkPoint Charlie - where it all began... */
- mov si, offset CheckPoint3
- call writestr
-
- /* Get address of optional header */
- mov eax, dword ptr ds:[FREELDR_PE_BASE + IMAGE_DOS_HEADER_e_lfanew]
- add eax, FREELDR_PE_BASE + 4 + IMAGE_FILE_HEADER_SIZE
-
- /* Get address of entry point */
- mov eax, dword ptr ds:[eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint]
-
- /* Store the address in the callback return variable */
- mov dword ptr ds:[CallbackReturnAddress], eax
-
-switch64:
- mov
- jmp x86_16_ReturnToLong
-
-
-no_x64_support_detected:
- mov si, offset NotAnX64Processor // Loading message
- call writestr
- jmp fail
-
-no_cpuid_support_detected:
- mov si, offset NoCPUIDSupport // Loading message
- call writestr
-
-fail:
- jmp fail
- nop
- nop
-
-/*
- * We define 512 2MB pages at the start of memory, so we can access the first
- * 1 GB as if paging was disabled
- */
-x86_16_BuildPageTables:
+ jnz .Success
+
+ mov si, offset .Msg_NoLongMode
+ call writestr
+ xor al, al
+ ret
+
+.Msg_NoLongMode:
+ .ascii "Long mode is not supported.", CR, LF, NUL
+
+.Success:
+ xor al, al
+ inc al
+ ret
+
+
+BuildPageTables:
pusha
push es
- /* Get segment of pml4 */
- mov eax, offset pml4_startup
- shr eax, 4
+ /* Get segment of the PML4 */
+ mov eax, PML4_ADDRESS / 16
mov es, ax
cld
xor di, di
/* One entry in the PML4 pointing to PDP */
- mov eax, offset pdp_startup
- or eax, HEX(00f)
+ mov eax, PDP_ADDRESS
+ or eax, HEX(0f)
stosd
+
/* clear rest */
xor eax, eax
- mov cx, HEX(03ff)
+ mov cx, 1023
rep stosd
/* One entry in the PDP pointing to PD */
- mov eax, offset pd_startup
- or eax, HEX(00f)
+ mov eax, PD_ADDRESS
+ or eax, HEX(0f)
stosd
+
/* clear rest */
xor eax, eax
- mov ecx, HEX(03ff)
+ mov ecx, 1023
rep stosd
- /* 512 entries in the PD defining a 2MB page each */
+ /* 512 entries in the PD, each defining a 2MB page each */
mov ecx, 512
mov eax, HEX(008f)
-Bpt2:
+.Bpt2:
mov es: [di], eax
mov dword ptr es: [di + 4], 0
- add eax, 512 << 12 // add 512 4k pages
+ add eax, 512 * 4096 // add 512 4k pages
add di, 8
- /* Loop it */
+ /* Loop all PDEs */
dec cx
- jnz Bpt2
+ jnz .Bpt2
/* Return */
pop es
@@ -178,13 +225,21 @@
ret
-
-
-
-x86_16_ReturnToLong:
-
- cli
-
+/******************************************************************************/
+
+#define MSR_EFER HEX(C0000080)
+#define LMODE_CS HEX(10)
+
+/* This is the entry point from long mode */
+RealModeEntryPoint:
+
+
+
+ExitToLongMode:
+ /* Disable interrupts */
+ cli
+
+ /* Set correct segment registers */
xor ax,ax
mov ds,ax
mov es,ax
@@ -192,34 +247,57 @@
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
+ /* Safe current stack pointer */
+ mov word ptr ds:[stack16], sp
+
+ /* Set PAE and PGE: 10100000b */
+ mov eax, HEX(00a0)
mov cr4, eax
- mov edx, offset pml4_startup // Point cr3 at PML4
+ /* Point cr3 at the PML4 */
+ mov edx, PML4_ADDRESS
mov cr3, edx
- mov ecx, HEX(0C0000080) // Specify EFER MSR
-
- rdmsr // Enable long mode
+
+ /* Enable long mode */
+ mov ecx, MSR_EFER
+ rdmsr
or eax, HEX(00000100)
wrmsr
- mov ebx, cr0 // Activate long mode
- or ebx, HEX(080000001) // 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
- // Do a long jmp to the CallbackReturn address
+ /* Activate long mode by enabling paging and protection simultaneously,
+ skipping protected mode entirely */
+ mov ebx, cr0
+ or ebx, HEX(80000001)
+ mov cr0, ebx
+
+ /* Clear prefetch queue & correct CS */
+ ljmp16 LMODE_CS, InLongMode
+InLongMode:
+ DB 66h, 0B8h, 18h, 00h // mov ax, LMODE_DS
+ DB 66h, 8Eh, 0D8h // mov ds, ax
+ DB 66h, 66h, 0C7h, 04h, 25h, 00h, 80h, 0Bh, 00h, 31h, 0Eh
+ //mov word ptr [HEX(b8000)], HEX(0e00) + '1'
+
+ .byte HEX(0ff), HEX(25) // opcode of indirect jump
+ .long 1 // relative address of LongModeEntryPoint
+ nop
+LongModeEntryPoint:
+ .long 0, 0
+
+ int HEX(16)
+ jmp SoftReboot
+
+
+ /* 16-bit stack pointer */
+stack16:
+ .word STACK16ADDR
#include "helpers.inc"
+.org (FREELDR_PE_BASE - FREELDR_BASE - 1)
+.byte 0
.endcode16
END
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1]
(original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] Thu Aug 25
14:43:15 2011
@@ -4,6 +4,11 @@
#endif
/* Memory layout */
+//#ifdef _M_AMD64
+#define PML4_ADDRESS HEX(1000) /* One page PML4 page table */
+#define PDP_ADDRESS HEX(2000) /* One page PDP page table */
+#define PD_ADDRESS HEX(3000) /* One page PD page table */
+//#endif
#define STACK16ADDR HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */
#define BSS_START HEX(6F00)
#define FREELDR_BASE HEX(F800)
@@ -60,21 +65,7 @@
#define REGS_GS 30
#define REGS_EFLAGS 32
-
-// Flag Masks
-#define I386FLAG_CF HEX(0001) // Carry Flag
-#define I386FLAG_RESV1 HEX(0002) // Reserved - Must be 1
-#define I386FLAG_PF HEX(0004) // Parity Flag
-#define I386FLAG_RESV2 HEX(0008) // Reserved - Must be 0
-#define I386FLAG_AF HEX(0010) // Auxiliary Flag
-#define I386FLAG_RESV3 HEX(0020) // Reserved - Must be 0
-#define I386FLAG_ZF HEX(0040) // Zero Flag
-#define I386FLAG_SF HEX(0080) // Sign Flag
-#define I386FLAG_TF HEX(0100) // Trap Flag (Single Step)
-#define I386FLAG_IF HEX(0200) // Interrupt Flag
-#define I386FLAG_DF HEX(0400) // Direction Flag
-#define I386FLAG_OF HEX(0800) // Overflow Flag
-
+/* Flag Masks */
#define CR0_PE_SET HEX(00000001) /* OR this value with CR0 to enable pmode */
#define CR0_PE_CLR HEX(FFFFFFFE) /* AND this value with CR0 to disable pmode */
@@ -85,6 +76,10 @@
#define PMODE_DS HEX(10) /* PMode data selector, base 0 limit 4g */
#define RMODE_CS HEX(18) /* RMode code selector, base 0 limit 64k */
#define RMODE_DS HEX(20) /* RMode data selector, base 0 limit 64k */
+//#else
+/* Long mode selectors */
+#define LMODE_CS HEX(10)
+#define LMODE_DS HEX(18)
//#endif
/* Makes "x" a global variable or label */