[ros-diffs] [tkreuzer] 53443: [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...

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Thu Aug 25 14:43:16 UTC 2011


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/CMakeLists.txt?rev=53443&r1=53442&r2=53443&view=diff
==============================================================================
--- 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/amd64/entry.S?rev=53443&r1=53442&r2=53443&view=diff
==============================================================================
--- 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/realmode/amd64.S?rev=53443&r1=53442&r2=53443&view=diff
==============================================================================
--- 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/include/arch/pc/x86common.h?rev=53443&r1=53442&r2=53443&view=diff
==============================================================================
--- 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 */




More information about the Ros-diffs mailing list