annotate 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
rev   line source
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
1 ;#!/usr/bin/nasm
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
2
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
3 ;
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
4 ; See http://wiki.osdev.org/User:Stephanvanschaik/Setting_Up_Long_Mode
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
5 ; Loader assembly to load the 64 bits kernel just after this file.
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
6
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
7 ; Assume that we are loaded at 1M (0x100000)
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
8 ;org 0x100000 ; this only works with flat bin output, not with elf64 output.
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
10 bits 32 ; Start in 32 bits mode.
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
11 ; Multiboot header:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
12 ; Settings for multiboot header
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
13 PAGE_ALIGN equ 1 << 0
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
14 MEM_INFO equ 1 << 1
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
15 KLUDGE equ 1 << 16
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
16 MAGIC equ 0x1BADB002
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
17 FLAGS equ PAGE_ALIGN | MEM_INFO | KLUDGE ; align and provide memory map
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
18 CHECKSUM equ -(MAGIC+FLAGS)
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
19
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
20 ; actual multiboot header:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
21 align 4
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
22 MultiBootHeader:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
23 dd MAGIC
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
24 dd FLAGS
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
25 dd CHECKSUM
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
26 ; item below are present if bit 16 is set in flags
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
27 dd MultiBootHeader ; physical address in file of header (will be 0x100000 if put at start)
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
28 dd 0x100000 ; load_addr: load address, the address to start loading
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
29 dd 0x0 ; load_end_addr: zero indicates to load whole file
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
30 dd 0x0 ; bss_end_addr: zero indicates no bss segment present
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
31 dd loader ; entry_addr: jump to here
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
32
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
33 ; GDT, three entries: one for code, one for data
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
34 GDT64:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
35 .Null: equ $ - GDT64
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
36 dq 0
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
37 .Code: equ $ - GDT64
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
38 dw 0 ; Segment limit 15-0
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
39 dw 0 ; Base 15 - 0
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
40 db 0 ; Base 23 - 16
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
41 db 10011000b ; access 0x98 (P=1 => Present)
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
42 db 00100000b ; granularity 0x20 (L=1 => long mode)
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
43 db 0
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
44 .Data: equ $ - GDT64
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
45 dw 0
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
46 dw 0
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
47 db 0
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
48 db 10010000b ; access ; 0x90
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
49 db 00000000b ; granularity 0x00
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
50 db 0
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
51 .Pointer: ; GDT pointer
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
52 dw $ - GDT64 - 1 ; Limit
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
53 dq GDT64 ; Base
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
54
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
55 ; Start of loader code:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
56 global loader
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
57 loader:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
58
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
59 ; Check that the CPU supports long mode:
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
60 mov eax, 80000000h
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
61 cpuid
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
62 cmp eax, 80000000h
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
63 jbe no_long_mode
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
64 mov eax, 80000001h
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
65 cpuid
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
66 bt edx, 29
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
67 jnc no_long_mode
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
68 jmp long_mode
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
69
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
70 no_long_mode:
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
71 hlt
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
72
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
73 long_mode:
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
74
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
75 ; Prepare paging:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
76 ; PML4T - 0x1000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
77 ; PDPT - 0x2000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
78 ; PDT - 0x3000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
79 ; PT - 0x4000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
80
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
81 ; Clear the tables:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
82 mov edi, 0x1000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
83 mov cr3, edi ; CR3 is the page table address!
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
84 xor eax, eax
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
85 mov ecx, 4096
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
86 rep stosd
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
87 mov edi, cr3 ; restore edi
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
88
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
89 mov DWORD [edi], 0x2003 ; present and readwrite, points to first PDPT
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
90 add edi, 0x1000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
91 mov DWORD [edi], 0x3003 ; present and readwrite, points to first PDT
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
92 add edi, 0x1000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
93 mov DWORD [edi], 0x4003 ; present and readwrite, points to first PT
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
94 add edi, 0x1000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
95
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
96 ; identity map the first two megabytes:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
97 mov ebx, 0x00000003
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
98 mov ecx, 512
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
99 ; Fill all PT entries at 0x4000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
100 SetEntry:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
101 mov DWORD [edi], ebx
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
102 add ebx, 0x1000
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
103 add edi, 8
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
104 loop SetEntry
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
105
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
106 ; Enable paging:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
107 mov eax, cr4
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
108 or eax, 1 << 5 ; PAE-bit is bit 5
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
109 mov cr4, eax
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
110
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
111 ; Load the GDT:
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
112 lgdt [GDT64.Pointer]
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
113
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
114 ; Set LM-bit (Long Mode bit):
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
115 mov ecx, 0xC0000080
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
116 rdmsr
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
117 or eax, 0x100 ; Set bit 8 (LM-bit)
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
118 wrmsr
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
119
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
120 ; Enable paging:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
121 mov eax, cr0
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
122 or eax, 0x80000000 ; Set bit 31 (PG-bit)
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
123 mov cr0, eax
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
124
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
125
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
126 ; Jump to 64 bits kernel:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
127 jmp GDT64.Code:Realm64
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
128
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
129 bits 64
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
130
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
131 ; realm64
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
132 Realm64:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
133
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
134 ; Clear segment registers:
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
135 xor ax, ax
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
136 mov ds, ax
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
137 mov es, ax
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
138 mov ss, ax
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
139 mov fs, ax
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
140 mov gs, ax
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
141
18
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
142 ; Reoad the GDT:
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
143 lgdt [GDT64.Pointer]
6129643f5c34 Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents: 12
diff changeset
144
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
145 ; Done!
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
146
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
147 ; Setup stack pointer:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
148 mov rsp, stackEnd
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
149 ; Put a B upper left corner
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
150 mov al, 66 ; 'B'
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
151 mov [0xb8000], al
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
152
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
153 ; Jump to code that is glued after this file
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
154 jmp einde
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
155
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
156 align 16
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
157 dataEnd:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
158 ; reserve bytes for stack:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
159 stackBegin:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
160 resb 1024
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
161 stackEnd:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
162
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
163 einde:
12
fcdae30b2782 Fixup of variable argument things
windel
parents: 9
diff changeset
164 # XCHG BX, BX ; bochs breakpoint
9
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
165
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
166 # Call kernel:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
167 extern kmain
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
168 call kmain
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
169 # Should we ever return, remain in endless loop:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
170 cli
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
171 hang:
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
172 hlt
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
173 jmp hang
92ace1ca50a8 64 bits kernel without interrupts but with printf in C
windel
parents:
diff changeset
174