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
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
+
+ /* Check if CPU supports CPUID */
+
+ pushfd
+ pop eax
+ mov ebx, eax
+ xor eax, 0x00200000
+ push eax
+ popfd
+ pushfd
+ pop eax
+ cmp eax,ebx
+ jz NO_CPUID_SUPPORT_DETECTED
+
+ /* CPUID support detected - getting the PAE/PGE */
+
+ mov eax,1 // Fn0000_0001 - PAE in EDX[6]
+ cpuid
+ xor eax,eax
+ and edx,0x00a0
+ test edx,edx // are PAE and PGE bits set?
+ jz NO_X64_SUPPORT_DETECTED
+
+ /* PAE and PGE are here */
+
+ xor edx, edx
+ mov eax, 0x80000001
+ cpuid
+ and edx, 0x20000000
+ test edx,edx
+ jz NO_X64_SUPPORT_DETECTED
+
+ /* X64 Processor */
+
+ /* checkPoint Charlie - where it all began... */
+ mov si, offset _CheckPoint3
+ call writestr
+
+ jmp _switch64
+
+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
- /* Switch to long mode */
+_switch64:
call x86_16_SwitchToLong
.code64
+// mov ax, LMODE_DS
+// mov ds, ax
+// mov word ptr ds:[0xb8000], 0x0e00 + '1'
+
/* GO! */
xor rcx, rcx
call _BootMain
+ /* Checkpoint */
+// mov ax, LMODE_DS
+// mov ds, ax
+// mov word ptr ds:[0xb8002], 0x0e02 + '2'
+
+
/* Return into real mode */
call x86_64_SwitchToReal
.code16
popa
ret
-
/*
* We define 512 2MB pages at the start of memory, so we can access the first
* 1 GB as if paging was disabled
popa
ret
+/*
+ * writechr,writestr
+ *
+ *
+ */
+writestr:
+ pushfd
+ pushad
+.top:
+ lodsb
+ and al, al
+ jz .end
+ call writechr
+ jmp short .top
+.end:
+ popad
+ popfd
+ ret
+
+
+writechr:
+ pushf
+ pusha
+ mov ah, 0x0E
+ xor bx, bx
+ int 0x10
+ popa
+ popf
+ ret
//.global x86_16_SwitchToLong
x86_16_SwitchToLong:
+
cli
xor ax,ax
/* Now return in long mode! */
ret
-
-/** 64 But functions **********************************************************/
+/** 64 Bit functions **********************************************************/
.code64
.global x86_64_SwitchToReal
/* 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
+// mov ax, LMODE_DS
+// mov ds, ax
+// mov word ptr ds:[0xb8004], 0x0e00 + '3'
+
+ /* Step 1 - jump to compatibility segment */
+ ljmp jumpvector
+
+jumpvector:
+ .long SwitchToReal1
+ .word CMODE_CS
+
+SwitchToReal1:
+.code32
+
+// mov word ptr ds:[0xb8006], 0x0e00 + '4'
+
+ /* Step 2 - deactivate long mode, by disabling paging */
+ mov eax, cr0
+ and eax, 0x000000007fffffff //~0x80000000
+ mov cr0, eax
/* Step 2 - disable long mode in EFER MSR */
- mov rcx, 0xC0000080 // Specify EFER MSR
- rdmsr
- and eax, ~0x00000100 // Disable EFER.LME
- wrmsr
+// mov ecx, 0xC0000080 // Specify EFER MSR
+// rdmsr
+// and eax, ~0x00000100 // Disable EFER.LME
+// wrmsr
- .code32
- /* jmp to 16-bit segment to set the limit correctly */
+ /* Step 3 - jump to 16-bit segment to set the limit correctly */
jmp RMODE_CS: offset SwitchToReal2
SwitchToReal2:
.code16
- /* Step 3 - Disable Protected Mode */
+ /* Step 4 - Disable Protected Mode */
mov eax, cr0
and eax, ~0x00000001
mov cr0, eax
jmp 0:offset BeReal
BeReal:
+ /* Checkpoint */
+// mov ax, 0xb800
+// mov fs, ax
+// mov word ptr fs:[0x0C], 0x0e00 + '7'
+
/* Restore segment registers */
mov ax, 0
mov ds, ax
mov gs, ax
mov ss, ax
- /* Rstore 16 bit stack */
+ /* Restore 16 bit stack */
mov sp, stack16
// lidt rmode_idtptr /* Load IDTR with real mode value */
code64ret:
.quad 0
+.p2align 2
gdt:
.quad 0x0000000000000000 /* 00: NULL descriptor */
.quad 0x0000000000000000 /* 08: */
.quad 0x0020980000000000 /* 10: long mode cs */
- .quad 0x0000900000000000 /* 18: long mode ds */
+ .quad 0x00cff3000000ffff /* 18: long mode ds */
.word 0xFFFF, 0x0000, 0x9E00, 0x0000 /* 16-bit real mode CS */
.word 0xFFFF, 0x0000, 0x9200, 0x0000 /* 16-bit real mode DS */
+ .quad 0x00CF9B000000FFFF /* 30: compat mode cs */
/* GDT table pointer */
gdtptr:
- .word 0x2f /* Limit */
+ .word 0x37 /* Limit */
.long gdt /* Base Address */
_BootPartition:
.long 0
+.global _NotAnX64Processor
+_NotAnX64Processor:
+ .ascii "FreeLoader: No x64-compatible CPU detected! Exiting..."
+ .byte 0x0d, 0x0a, 0
+
+.global _NoCPUIDSupport
+_NoCPUIDSupport:
+ .ascii "FreeLoader: No CPUID instruction support detected! Exiting..."
+ .byte 0x0d, 0x0a, 0
+
+/////////////////////////// Checkpoint messages ///////////////////////////////
+.global _CheckPoint0
+_CheckPoint0:
+ .ascii "Starting FreeLoader..."
+ .byte 0x0d, 0x0a, 0
+
+.global _CheckPoint1
+_CheckPoint1:
+ .ascii "FreeLoader[16-bit]: building page tables..."
+ .byte 0x0d, 0x0a, 0
+
+.global _CheckPoint2
+_CheckPoint2:
+ .ascii "FreeLoader[16-bit]: checking CPU for x64 long mode..."
+ .byte 0x0d, 0x0a, 0
+
+.global _CheckPoint3
+_CheckPoint3:
+ .ascii "FreeLoader: Switching to x64 long mode..."
+ .byte 0x0d, 0x0a, 0
///////////////////////////////////////////////////////////////////////////////