comparison cos/kernel/goto64.asm @ 20:b1fed2171e1a

Now working with 2 MB pages
author windel
date Mon, 28 Nov 2011 20:54:40 +0100
parents 6129643f5c34
children 5dd47d6eebac
comparison
equal deleted inserted replaced
19:f454e3c592dd 20:b1fed2171e1a
3 ; 3 ;
4 ; See http://wiki.osdev.org/User:Stephanvanschaik/Setting_Up_Long_Mode 4 ; See http://wiki.osdev.org/User:Stephanvanschaik/Setting_Up_Long_Mode
5 ; Loader assembly to load the 64 bits kernel just after this file. 5 ; Loader assembly to load the 64 bits kernel just after this file.
6 6
7 ; Assume that we are loaded at 1M (0x100000) 7 ; Assume that we are loaded at 1M (0x100000)
8 ;org 0x100000 ; this only works with flat bin output, not with elf64 output. 8
9 9 ; This file sets up long mode and creates paging tables.
10 bits 32 ; Start in 32 bits mode. 10 ; Use 2 mbyte pages. Is this more efficient?
11
12 ; Intended memory map (copied from pure64), at the end of this file:
13 ; 0x0 : IDT, 256 entries
14 ; 0x1000 - 0x2000 : PML4 (Page map level 4)
15 ; 0x2000 - 0x3000 : PDPT (page directory pointer table)
16 ; 0x3000 - 0x4000 : PDT (page directory table)
17 ; 0x4000 - 0x5000 : PT (page table)
18 ; 0x5000 - 0xA000 : Stack
19
20 bits 32 ; Start in 32 bits mode, as loaded by GRUB
21
11 ; Multiboot header: 22 ; Multiboot header:
12 ; Settings for multiboot header 23 ; Settings for multiboot header
13 PAGE_ALIGN equ 1 << 0 24 PAGE_ALIGN equ 1 << 0
14 MEM_INFO equ 1 << 1 25 MEM_INFO equ 1 << 1
15 KLUDGE equ 1 << 16 26 KLUDGE equ 1 << 16
28 dd 0x100000 ; load_addr: load address, the address to start loading 39 dd 0x100000 ; load_addr: load address, the address to start loading
29 dd 0x0 ; load_end_addr: zero indicates to load whole file 40 dd 0x0 ; load_end_addr: zero indicates to load whole file
30 dd 0x0 ; bss_end_addr: zero indicates no bss segment present 41 dd 0x0 ; bss_end_addr: zero indicates no bss segment present
31 dd loader ; entry_addr: jump to here 42 dd loader ; entry_addr: jump to here
32 43
44 ; 32 bits temporary GDT:
45 align 16
46 gdt32:
47 dw 0x0000, 0x0000, 0x0000, 0x0000 ; Null desciptor
48 dw 0xFFFF, 0x0000, 0x9A00, 0x00CF ; 32-bit code desciptor
49 dw 0xFFFF, 0x0000, 0x9200, 0x008F ; 32-bit data desciptor
50 gdt32_end:
51
52 ; 32 bits gdt pointer:
53 align 16
54 gdt32pointer: ; Global Descriptors Table Register
55 dw gdt32_end - gdt32 - 1 ; limit of GDT (size minus one)
56 dq gdt32 ; linear address of GDT
57
33 ; GDT, three entries: one for code, one for data 58 ; GDT, three entries: one for code, one for data
34 GDT64: 59 align 16
35 .Null: equ $ - GDT64 60 gdt64:
61 .Null: equ $ - gdt64
36 dq 0 62 dq 0
37 .Code: equ $ - GDT64 63 .Code: equ $ - gdt64
38 dw 0 ; Segment limit 15-0 64 dw 0 ; Segment limit 15-0
39 dw 0 ; Base 15 - 0 65 dw 0 ; Base 15 - 0
40 db 0 ; Base 23 - 16 66 db 0 ; Base 23 - 16
41 db 10011000b ; access 0x98 (P=1 => Present) 67 db 10011000b ; access 0x98 (P=1 => Present)
42 db 00100000b ; granularity 0x20 (L=1 => long mode) 68 db 00100000b ; granularity 0x20 (L=1 => long mode)
43 db 0 69 db 0
44 .Data: equ $ - GDT64 70 .Data: equ $ - gdt64
45 dw 0 71 dw 0
46 dw 0 72 dw 0
47 db 0 73 db 0
48 db 10010000b ; access ; 0x90 74 db 10010000b ; access ; 0x90
49 db 00000000b ; granularity 0x00 75 db 00000000b ; granularity 0x00
50 db 0 76 db 0
51 .Pointer: ; GDT pointer 77 gdt64end:
52 dw $ - GDT64 - 1 ; Limit 78
53 dq GDT64 ; Base 79 ;SYS64_NULL_SEL equ $-gdt64 ; Null Segment
80 ; dq 0x0000000000000000
81 ; SYS64_CODE_SEL equ $-gdt64 ; Code segment, read/execute, nonconforming
82 ; dq 0x0020980000000000 ; 0x00209A0000000000
83 ; SYS64_DATA_SEL equ $-gdt64 ; Data segment, read/write, expand down
84 ; dq 0x0000900000000000 ; 0x0020920000000000
85 ; gdt64_end:
86
87 gdt64pointer: ; GDT pointer
88 dw gdt64end - gdt64 - 1 ; Limit (size)
89 dq gdt64 ; Base
54 90
55 ; Start of loader code: 91 ; Start of loader code:
56 global loader
57 loader: 92 loader:
58 93
59 ; Check that the CPU supports long mode: 94 ; Check that the CPU supports long mode:
60 mov eax, 80000000h 95 mov eax, 80000000h
61 cpuid 96 cpuid
63 jbe no_long_mode 98 jbe no_long_mode
64 mov eax, 80000001h 99 mov eax, 80000001h
65 cpuid 100 cpuid
66 bt edx, 29 101 bt edx, 29
67 jnc no_long_mode 102 jnc no_long_mode
68 jmp long_mode 103 jmp cpu_has_long_mode
69 104
70 no_long_mode: 105 no_long_mode:
71 hlt 106 hlt
72 107
73 long_mode: 108 cpu_has_long_mode:
74 109
75 ; Prepare paging: 110 lgdt [gdt32pointer] ; Reload a valid temporary 32 bits GDT, overload GRUB gdt.
76 ; PML4T - 0x1000 111 mov ax, 0x10
77 ; PDPT - 0x2000 112 mov ds, ax
78 ; PDT - 0x3000 113 mov es, ax
79 ; PT - 0x4000 114 mov fs, ax
80 115 mov gs, ax
81 ; Clear the tables: 116 mov ss, ax
117 jmp 8:start32 ; make sure CS is loaded.
118 start32:
119
120 cld ; clear direction?
121
122 ; Clear the paging tables 0x1000, 0x2000, 0x3000 and 0x4000:
82 mov edi, 0x1000 123 mov edi, 0x1000
83 mov cr3, edi ; CR3 is the page table address!
84 xor eax, eax 124 xor eax, eax
85 mov ecx, 4096 125 mov ecx, 4096
86 rep stosd 126 rep stosd
87 mov edi, cr3 ; restore edi 127
88 128 ; Create PML4 table:
89 mov DWORD [edi], 0x2003 ; present and readwrite, points to first PDPT 129 mov edi, 0x1000
90 add edi, 0x1000 130 mov eax, 0x2003
91 mov DWORD [edi], 0x3003 ; present and readwrite, points to first PDT 131 stosd
92 add edi, 0x1000 132
93 mov DWORD [edi], 0x4003 ; present and readwrite, points to first PT 133 ; Create PDP (page directory pointer) table:
94 add edi, 0x1000 134 mov edi, 0x2000
95 135 mov eax, 0x3003 ; PDPT entry, present and read/write
96 ; identity map the first two megabytes: 136 stosd
97 mov ebx, 0x00000003 137
98 mov ecx, 512 138 ; Create PD (page directory) table
99 ; Fill all PT entries at 0x4000 139 mov edi, 0x3000
100 SetEntry: 140 ; First entry:
101 mov DWORD [edi], ebx 141 mov eax, 0x8F ; PD entry, present (bit 0), read write (bit 1) and bit 7, page size=2MB
102 add ebx, 0x1000 142 stosd
103 add edi, 8 143 xor eax, eax
104 loop SetEntry 144 stosd
105 145
106 ; Enable paging: 146 ; Second entry:
147 mov eax, 0x20008f
148 stosd
149 xor eax, eax
150 stosd
151
152 ; Third entry:
153 mov eax, 0x40008f
154 stosd
155 xor eax, eax
156 stosd
157 ; 6 MB mapped in total now.
158
159 mov edi, 0x1000 ; Set load address
160 mov cr3, edi ; CR3 is the PML4 base address!
161
162 ; Enable address extension:
107 mov eax, cr4 163 mov eax, cr4
108 or eax, 1 << 5 ; PAE-bit is bit 5 164 or eax, 1 << 5 ; PAE-bit is bit 5
109 mov cr4, eax 165 mov cr4, eax
110 166
111 ; Load the GDT: 167 ; Load the GDT:
112 lgdt [GDT64.Pointer] 168 lgdt [gdt64pointer]
113 169
114 ; Set LM-bit (Long Mode bit): 170 ; Set LM-bit (Long Mode bit):
115 mov ecx, 0xC0000080 171 mov ecx, 0xC0000080
116 rdmsr 172 rdmsr
117 or eax, 0x100 ; Set bit 8 (LM-bit) 173 or eax, 0x100 ; Set bit 8 (LM-bit)
120 ; Enable paging: 176 ; Enable paging:
121 mov eax, cr0 177 mov eax, cr0
122 or eax, 0x80000000 ; Set bit 31 (PG-bit) 178 or eax, 0x80000000 ; Set bit 31 (PG-bit)
123 mov cr0, eax 179 mov cr0, eax
124 180
125
126 ; Jump to 64 bits kernel: 181 ; Jump to 64 bits kernel:
127 jmp GDT64.Code:Realm64 182 jmp gdt64.Code:Realm64
128 183
129 bits 64 184 bits 64
130 185 align 16
131 ; realm64 186
132 Realm64: 187 Realm64:
133 188
134 ; Clear segment registers: 189 ; Clear segment registers:
135 xor ax, ax 190 xor ax, ax
136 mov ds, ax 191 mov ds, ax
137 mov es, ax 192 mov es, ax
138 mov ss, ax 193 mov ss, ax
139 mov fs, ax 194 mov fs, ax
140 mov gs, ax 195 mov gs, ax
141 196
142 ; Reoad the GDT: 197 lgdt [gdt64pointer] ; Reload GDT in 64 bits mode
143 lgdt [GDT64.Pointer] 198
144 199 mov rsp, 0xA000 ; Setup stack pointer.
145 ; Done! 200
146
147 ; Setup stack pointer:
148 mov rsp, stackEnd
149 ; Put a B upper left corner
150 mov al, 66 ; 'B'
151 mov [0xb8000], al
152
153 ; Jump to code that is glued after this file
154 jmp einde
155
156 align 16
157 dataEnd:
158 ; reserve bytes for stack:
159 stackBegin:
160 resb 1024
161 stackEnd:
162
163 einde:
164 # XCHG BX, BX ; bochs breakpoint 201 # XCHG BX, BX ; bochs breakpoint
165 202
166 # Call kernel:
167 extern kmain 203 extern kmain
168 call kmain 204 call kmain ; Call kernel in C-code
205
169 # Should we ever return, remain in endless loop: 206 # Should we ever return, remain in endless loop:
170 cli 207 cli
171 hang: 208 hang:
172 hlt 209 hlt
173 jmp hang 210 jmp hang