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/CMakeL... ============================================================================== --- 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/a... ============================================================================== --- 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/r... ============================================================================== --- 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/includ... ============================================================================== --- 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 */