diff cos/kernel/goto64.asm @ 18:6129643f5c34

Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
author windel
date Sun, 20 Nov 2011 20:35:51 +0100
parents fcdae30b2782
children b1fed2171e1a
line wrap: on
line diff
--- a/cos/kernel/goto64.asm	Sat Nov 19 20:01:28 2011 +0100
+++ b/cos/kernel/goto64.asm	Sun Nov 20 20:35:51 2011 +0100
@@ -33,25 +33,20 @@
 ; GDT, three entries: one for code, one for data
 GDT64:
 .Null: equ $ - GDT64
-dw 0
-dw 0
-db 0
-db 0
-db 0
-db 0
+dq 0
 .Code: equ $ - GDT64
-dw 0
-dw 0
-db 0
-db 10011000b ; access
-db 00100000b ; granularity
+dw 0 ; Segment limit 15-0
+dw 0 ; Base 15 - 0
+db 0 ; Base 23 - 16
+db 10011000b ; access 0x98 (P=1 => Present)
+db 00100000b ; granularity 0x20 (L=1 => long mode)
 db 0
 .Data: equ $ - GDT64
 dw 0
 dw 0
 db 0
-db 10010000b ; access
-db 00000000b ; granularity
+db 10010000b ; access ; 0x90
+db 00000000b ; granularity 0x00
 db 0
 .Pointer: ; GDT pointer
 dw $ - GDT64 - 1 ; Limit
@@ -61,6 +56,22 @@
 global loader
 loader:
 
+; Check that the CPU supports long mode:
+mov eax, 80000000h
+cpuid
+cmp eax, 80000000h
+jbe no_long_mode
+mov eax, 80000001h
+cpuid
+bt edx, 29
+jnc no_long_mode
+jmp long_mode
+
+no_long_mode:
+hlt
+
+long_mode:
+
 ; Prepare paging:
 ; PML4T - 0x1000
 ; PDPT - 0x2000
@@ -97,6 +108,9 @@
 or eax, 1 << 5 ; PAE-bit is bit 5
 mov cr4, eax
 
+; Load the GDT:
+lgdt [GDT64.Pointer]
+
 ; Set LM-bit (Long Mode bit):
 mov ecx, 0xC0000080
 rdmsr
@@ -108,8 +122,6 @@
 or eax, 0x80000000 ; Set bit 31 (PG-bit)
 mov cr0, eax
 
-; Load the GDT:
-lgdt [GDT64.Pointer]
 
 ; Jump to 64 bits kernel:
 jmp GDT64.Code:Realm64
@@ -119,13 +131,17 @@
 ; realm64
 Realm64:
 
-cli
-mov ax, GDT64.Data
+; Clear segment registers:
+xor ax, ax
 mov ds, ax
 mov es, ax
+mov ss, ax
 mov fs, ax
 mov gs, ax
 
+; Reoad the GDT:
+lgdt [GDT64.Pointer]
+
 ; Done!
 
 ; Setup stack pointer: