1 ;kernel.asm 2 ;Author: Josh Holtrop 3 ;Modified: 10/30/03 4 5 %define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space 6 %define GDT_V GDT_P+0xC0000000 7 %define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space 8 %define IDT_V IDT_P+0xC0000000 9 %define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD) 10 %define PDBR_V PDBR_P+0xC0000000 11 %define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb 12 %define LOPT_V LOPT_P+0xC0000000 13 %define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address 14 %define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel 15 16 [global start] 17 [extern _isr] 18 [extern _k_init] 19 20 bits 32 21 22 ;This is where the kernel begins execution 23 ;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0. 24 ;We must enable paging with the first 4mb mapped 1:1 virtual:physical 25 ; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical. 26 ;Then we can start using our "real" gdt, then unmap the lower 4mb. 27 start: 28 00000000 FA cli ;if they weren't already off 29 30 00000001 31C0 xor eax, eax 31 00000003 BF004010C0 mov edi, PDBR_V 32 00000008 B900040000 mov ecx, 1024 ;clear the PDBR 33 0000000D F3AB rep stosd 34 0000000F C705004010C0035010- mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present) 35 00000018 00 36 00000019 C705004C10C0035010- mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present) 37 00000022 00 38 39 00000023 BF005010C0 mov edi, LOPT_V 40 00000028 B900040000 mov ecx, 1024 41 0000002D B803000000 mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags) 42 fill_lopt_loop: ;fill the page table 43 00000032 AB stosd 44 00000033 0500100000 add eax, 4096 ;increment next phsyical address by 4kb 45 00000038 E2F8 loop fill_lopt_loop 46 47 0000003A B800401000 mov eax, PDBR_P 48 0000003F 0F22D8 mov cr3, eax ;store the Page Directory Base Address 49 00000042 0F20C0 mov eax, cr0 50 00000045 0D00000080 or eax, 0x80000000 ;set page enable bit 51 0000004A 0F22C0 mov cr0, eax ;now paging is active! 52 53 54 0000004D BF000010C0 mov edi, GDT_V 55 00000052 BE[D4000000] mov esi, gdt 56 00000057 B948000000 mov ecx, gdt_end-gdt 57 copy_gdt: 58 0000005C AC lodsb 59 0000005D AA stosb 60 0000005E E2FC loop copy_gdt 61 62 00000060 BF002010C0 mov edi, IDT_V ;destination 63 00000065 BE[22010000] mov esi, isr_0 ;address of isr0 64 0000006A BA0B000000 mov edx, isr_1-isr_0 ;distance between isr labels 65 0000006F B932000000 mov ecx, 50 ;number of isrlabels 66 fill_idt: 67 00000074 89F3 mov ebx, esi 68 00000076 6689F0 mov ax, si 69 00000079 66AB stosw ;0 offset 15:0 70 0000007B 66B80800 mov ax, KERNEL_CODE 71 0000007F 66AB stosw ;2 selector 15:0 72 00000081 66B8008E mov ax, 0x8E00 73 00000085 66AB stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0] 74 00000087 C1EE10 shr esi, 16 75 0000008A 6689F0 mov ax, si 76 0000008D 66AB stosw ;6 offset 31:16 77 0000008F 89DE mov esi, ebx 78 00000091 01D6 add esi, edx 79 00000093 E2DF loop fill_idt 80 00000095 66C705842110C000EE mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges 81 82 0000009E 0F0115[CE000000] lgdt [gdtr] ;load gdt 83 000000A5 EA[AC000000]0800 jmp KERNEL_CODE:newgdtcontinue 84 newgdtcontinue: 85 000000AC 66B81000 mov ax, KERNEL_DATA 86 000000B0 8EC0 mov es, ax 87 000000B2 8ED8 mov ds, ax 88 000000B4 8EE8 mov gs, ax 89 000000B6 8EE0 mov fs, ax 90 000000B8 8ED0 mov ss, ax 91 000000BA BCFCFF1FC0 mov esp, 0xc01ffffc ;stack just under 3gb+2mb, moves downward 92 000000BF 0F011D[1C010000] lidt [idtr] ;load idt 93 94 000000C6 E8(00000000) call _k_init 95 haltit: 96 000000CB F4 hlt ;halt processor when k_init is done 97 000000CC EBFD jmp haltit ;shouldn't get here... 98 99 %include "gdt.inc" 100 <1> ;gdt.inc 101 <1> ;Author: Josh Holtrop 102 <1> ;for HOS 103 <1> ;Modified: 10/30/03 104 <1> 105 <1> gdtr: 106 000000CE 4700 <1> dw gdt_end-gdt-1 107 000000D0 00001000 <1> dd GDT_P 108 <1> gdt: 109 000000D4 00000000 <1> dd 0 110 000000D8 00000000 <1> dd 0 111 <1> KERNEL_CODE equ $-gdt 112 000000DC FFFF <1> dw 0xffff ;limit 15:0 113 000000DE 0000 <1> dw 0x0000 ;base 15:0 114 000000E0 00 <1> db 0x00 ;base 23:16 115 000000E1 9A <1> db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 116 000000E2 CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16 117 000000E3 00 <1> db 0x00 ;base 31:24 118 <1> KERNEL_DATA equ $-gdt 119 000000E4 FFFF <1> dw 0xffff ;limit 15:0 120 000000E6 0000 <1> dw 0x0000 ;base 15:0 121 000000E8 00 <1> db 0x00 ;base 23:16 122 000000E9 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 123 000000EA CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16 124 000000EB 00 <1> db 0x00 ;base 31:24 125 <1> VESA_CODE equ $-gdt 126 000000EC FFFF <1> dw 0xffff ;limit 15:0 127 000000EE 0000 <1> dw 0x0000 ;base 15:0 128 000000F0 00 <1> db 0x00 ;base 23:16 129 000000F1 9A <1> db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 130 000000F2 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16 131 000000F3 00 <1> db 0x00 ;base 31:24 132 <1> VESA_DATA equ $-gdt 133 000000F4 FFFF <1> dw 0xffff ;limit 15:0 134 000000F6 0000 <1> dw 0x0000 ;base 15:0 135 000000F8 00 <1> db 0x00 ;base 23:16 136 000000F9 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 137 000000FA 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16 138 000000FB 00 <1> db 0x00 ;base 31:24 139 <1> VIDEO_TEXT equ $-gdt 140 000000FC FF7F <1> dw 0x7FFF ;limit 15:0 141 000000FE 0080 <1> dw 0x8000 ;base 15:0 142 00000100 0B <1> db 0x0B ;base 23:16 143 00000101 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 144 00000102 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16 145 00000103 00 <1> db 0x00 ;base 31:24 146 <1> VIDEO_GRAPHICS equ $-gdt 147 00000104 FFFF <1> dw 0xFFFF ;limit 15:0 148 00000106 0000 <1> dw 0x0000 ;base 15:0 149 00000108 0A <1> db 0x0A ;base 23:16 150 00000109 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 151 0000010A 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16 152 0000010B 00 <1> db 0x00 ;base 31:24 153 <1> USER_CODE equ $-gdt 154 0000010C FFFF <1> dw 0xffff ;limit 15:0 155 0000010E 0000 <1> dw 0x0000 ;base 15:0 156 00000110 00 <1> db 0x00 ;base 23:16 157 00000111 FA <1> db 0xFA ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 158 00000112 CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16 159 00000113 00 <1> db 0x00 ;base 31:24 160 <1> USER_DATA equ $-gdt 161 00000114 FFFF <1> dw 0xffff ;limit 15:0 162 00000116 0000 <1> dw 0x0000 ;base 15:0 163 00000118 00 <1> db 0x00 ;base 23:16 164 00000119 F2 <1> db 0xF2 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) 165 0000011A CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16 166 0000011B 00 <1> db 0x00 ;base 31:24 167 <1> gdt_end: 168 <1> 169 <1> 170 <1> 171 %include "idt.inc" 172 <1> ;idt.inc 173 <1> ;Author: Josh Holtrop 174 <1> ;for HOS 175 <1> ;Modified: 10/30/03 176 <1> 177 <1> idtr: 178 0000011C 8F01 <1> dw 50*8-1 ;size of idt 179 0000011E 00201000 <1> dd IDT_P ;address of idt 180 <1> 181 <1> 182 <1> %macro isr_label 1 183 <1> isr_%1: 184 <1> push eax 185 <1> mov eax, %1 186 <1> jmp isr_main 187 <1> %endmacro 188 <1> 189 <1> isr_label 0 190 <2> isr_%1: 191 00000122 50 <2> push eax 192 00000123 B800000000 <2> mov eax, %1 193 00000128 E91B020000 <2> jmp isr_main 194 <1> isr_label 1 195 <2> isr_%1: 196 0000012D 50 <2> push eax 197 0000012E B801000000 <2> mov eax, %1 198 00000133 E910020000 <2> jmp isr_main 199 <1> isr_label 2 200 <2> isr_%1: 201 00000138 50 <2> push eax 202 00000139 B802000000 <2> mov eax, %1 203 0000013E E905020000 <2> jmp isr_main 204 <1> isr_label 3 205 <2> isr_%1: 206 00000143 50 <2> push eax 207 00000144 B803000000 <2> mov eax, %1 208 00000149 E9FA010000 <2> jmp isr_main 209 <1> isr_label 4 210 <2> isr_%1: 211 0000014E 50 <2> push eax 212 0000014F B804000000 <2> mov eax, %1 213 00000154 E9EF010000 <2> jmp isr_main 214 <1> isr_label 5 215 <2> isr_%1: 216 00000159 50 <2> push eax 217 0000015A B805000000 <2> mov eax, %1 218 0000015F E9E4010000 <2> jmp isr_main 219 <1> isr_label 6 220 <2> isr_%1: 221 00000164 50 <2> push eax 222 00000165 B806000000 <2> mov eax, %1 223 0000016A E9D9010000 <2> jmp isr_main 224 <1> isr_label 7 225 <2> isr_%1: 226 0000016F 50 <2> push eax 227 00000170 B807000000 <2> mov eax, %1 228 00000175 E9CE010000 <2> jmp isr_main 229 <1> isr_label 8 230 <2> isr_%1: 231 0000017A 50 <2> push eax 232 0000017B B808000000 <2> mov eax, %1 233 00000180 E9C3010000 <2> jmp isr_main 234 <1> isr_label 9 235 <2> isr_%1: 236 00000185 50 <2> push eax 237 00000186 B809000000 <2> mov eax, %1 238 0000018B E9B8010000 <2> jmp isr_main 239 <1> isr_label 10 240 <2> isr_%1: 241 00000190 50 <2> push eax 242 00000191 B80A000000 <2> mov eax, %1 243 00000196 E9AD010000 <2> jmp isr_main 244 <1> isr_label 11 245 <2> isr_%1: 246 0000019B 50 <2> push eax 247 0000019C B80B000000 <2> mov eax, %1 248 000001A1 E9A2010000 <2> jmp isr_main 249 <1> isr_label 12 250 <2> isr_%1: 251 000001A6 50 <2> push eax 252 000001A7 B80C000000 <2> mov eax, %1 253 000001AC E997010000 <2> jmp isr_main 254 <1> isr_label 13 255 <2> isr_%1: 256 000001B1 50 <2> push eax 257 000001B2 B80D000000 <2> mov eax, %1 258 000001B7 E98C010000 <2> jmp isr_main 259 <1> isr_label 14 260 <2> isr_%1: 261 000001BC 50 <2> push eax 262 000001BD B80E000000 <2> mov eax, %1 263 000001C2 E981010000 <2> jmp isr_main 264 <1> isr_label 15 265 <2> isr_%1: 266 000001C7 50 <2> push eax 267 000001C8 B80F000000 <2> mov eax, %1 268 000001CD E976010000 <2> jmp isr_main 269 <1> isr_label 16 270 <2> isr_%1: 271 000001D2 50 <2> push eax 272 000001D3 B810000000 <2> mov eax, %1 273 000001D8 E96B010000 <2> jmp isr_main 274 <1> isr_label 17 275 <2> isr_%1: 276 000001DD 50 <2> push eax 277 000001DE B811000000 <2> mov eax, %1 278 000001E3 E960010000 <2> jmp isr_main 279 <1> isr_label 18 280 <2> isr_%1: 281 000001E8 50 <2> push eax 282 000001E9 B812000000 <2> mov eax, %1 283 000001EE E955010000 <2> jmp isr_main 284 <1> isr_label 19 285 <2> isr_%1: 286 000001F3 50 <2> push eax 287 000001F4 B813000000 <2> mov eax, %1 288 000001F9 E94A010000 <2> jmp isr_main 289 <1> isr_label 20 290 <2> isr_%1: 291 000001FE 50 <2> push eax 292 000001FF B814000000 <2> mov eax, %1 293 00000204 E93F010000 <2> jmp isr_main 294 <1> isr_label 21 295 <2> isr_%1: 296 00000209 50 <2> push eax 297 0000020A B815000000 <2> mov eax, %1 298 0000020F E934010000 <2> jmp isr_main 299 <1> isr_label 22 300 <2> isr_%1: 301 00000214 50 <2> push eax 302 00000215 B816000000 <2> mov eax, %1 303 0000021A E929010000 <2> jmp isr_main 304 <1> isr_label 23 305 <2> isr_%1: 306 0000021F 50 <2> push eax 307 00000220 B817000000 <2> mov eax, %1 308 00000225 E91E010000 <2> jmp isr_main 309 <1> isr_label 24 310 <2> isr_%1: 311 0000022A 50 <2> push eax 312 0000022B B818000000 <2> mov eax, %1 313 00000230 E913010000 <2> jmp isr_main 314 <1> isr_label 25 315 <2> isr_%1: 316 00000235 50 <2> push eax 317 00000236 B819000000 <2> mov eax, %1 318 0000023B E908010000 <2> jmp isr_main 319 <1> isr_label 26 320 <2> isr_%1: 321 00000240 50 <2> push eax 322 00000241 B81A000000 <2> mov eax, %1 323 00000246 E9FD000000 <2> jmp isr_main 324 <1> isr_label 27 325 <2> isr_%1: 326 0000024B 50 <2> push eax 327 0000024C B81B000000 <2> mov eax, %1 328 00000251 E9F2000000 <2> jmp isr_main 329 <1> isr_label 28 330 <2> isr_%1: 331 00000256 50 <2> push eax 332 00000257 B81C000000 <2> mov eax, %1 333 0000025C E9E7000000 <2> jmp isr_main 334 <1> isr_label 29 335 <2> isr_%1: 336 00000261 50 <2> push eax 337 00000262 B81D000000 <2> mov eax, %1 338 00000267 E9DC000000 <2> jmp isr_main 339 <1> isr_label 30 340 <2> isr_%1: 341 0000026C 50 <2> push eax 342 0000026D B81E000000 <2> mov eax, %1 343 00000272 E9D1000000 <2> jmp isr_main 344 <1> isr_label 31 345 <2> isr_%1: 346 00000277 50 <2> push eax 347 00000278 B81F000000 <2> mov eax, %1 348 0000027D E9C6000000 <2> jmp isr_main 349 <1> isr_label 32 350 <2> isr_%1: 351 00000282 50 <2> push eax 352 00000283 B820000000 <2> mov eax, %1 353 00000288 E9BB000000 <2> jmp isr_main 354 <1> isr_label 33 355 <2> isr_%1: 356 0000028D 50 <2> push eax 357 0000028E B821000000 <2> mov eax, %1 358 00000293 E9B0000000 <2> jmp isr_main 359 <1> isr_label 34 360 <2> isr_%1: 361 00000298 50 <2> push eax 362 00000299 B822000000 <2> mov eax, %1 363 0000029E E9A5000000 <2> jmp isr_main 364 <1> isr_label 35 365 <2> isr_%1: 366 000002A3 50 <2> push eax 367 000002A4 B823000000 <2> mov eax, %1 368 000002A9 E99A000000 <2> jmp isr_main 369 <1> isr_label 36 370 <2> isr_%1: 371 000002AE 50 <2> push eax 372 000002AF B824000000 <2> mov eax, %1 373 000002B4 E98F000000 <2> jmp isr_main 374 <1> isr_label 37 375 <2> isr_%1: 376 000002B9 50 <2> push eax 377 000002BA B825000000 <2> mov eax, %1 378 000002BF E984000000 <2> jmp isr_main 379 <1> isr_label 38 380 <2> isr_%1: 381 000002C4 50 <2> push eax 382 000002C5 B826000000 <2> mov eax, %1 383 000002CA E979000000 <2> jmp isr_main 384 <1> isr_label 39 385 <2> isr_%1: 386 000002CF 50 <2> push eax 387 000002D0 B827000000 <2> mov eax, %1 388 000002D5 E96E000000 <2> jmp isr_main 389 <1> isr_label 40 390 <2> isr_%1: 391 000002DA 50 <2> push eax 392 000002DB B828000000 <2> mov eax, %1 393 000002E0 E963000000 <2> jmp isr_main 394 <1> isr_label 41 395 <2> isr_%1: 396 000002E5 50 <2> push eax 397 000002E6 B829000000 <2> mov eax, %1 398 000002EB E958000000 <2> jmp isr_main 399 <1> isr_label 42 400 <2> isr_%1: 401 000002F0 50 <2> push eax 402 000002F1 B82A000000 <2> mov eax, %1 403 000002F6 E94D000000 <2> jmp isr_main 404 <1> isr_label 43 405 <2> isr_%1: 406 000002FB 50 <2> push eax 407 000002FC B82B000000 <2> mov eax, %1 408 00000301 E942000000 <2> jmp isr_main 409 <1> isr_label 44 410 <2> isr_%1: 411 00000306 50 <2> push eax 412 00000307 B82C000000 <2> mov eax, %1 413 0000030C E937000000 <2> jmp isr_main 414 <1> isr_label 45 415 <2> isr_%1: 416 00000311 50 <2> push eax 417 00000312 B82D000000 <2> mov eax, %1 418 00000317 E92C000000 <2> jmp isr_main 419 <1> isr_label 46 420 <2> isr_%1: 421 0000031C 50 <2> push eax 422 0000031D B82E000000 <2> mov eax, %1 423 00000322 E921000000 <2> jmp isr_main 424 <1> isr_label 47 425 <2> isr_%1: 426 00000327 50 <2> push eax 427 00000328 B82F000000 <2> mov eax, %1 428 0000032D E916000000 <2> jmp isr_main 429 <1> isr_label 48 430 <2> isr_%1: 431 00000332 50 <2> push eax 432 00000333 B830000000 <2> mov eax, %1 433 00000338 E90B000000 <2> jmp isr_main 434 <1> isr_label 49 435 <2> isr_%1: 436 0000033D 50 <2> push eax 437 0000033E B831000000 <2> mov eax, %1 438 00000343 E900000000 <2> jmp isr_main 439 <1> 440 <1> isr_main: 441 00000348 60 <1> pusha 442 00000349 1E <1> push ds 443 0000034A 06 <1> push es 444 <1> 445 0000034B 50 <1> push eax 446 <1> 447 0000034C E8(00000000) <1> call _isr 448 <1> 449 00000351 58 <1> pop eax 450 <1> 451 00000352 07 <1> pop es 452 00000353 1F <1> pop ds 453 00000354 61 <1> popa 454 00000355 58 <1> pop eax 455 <1> 456 00000356 CF <1> iret 457 <1> 458 <1> 459 <1> 460 <1> 461 <1> 462 <1> 463 <1> 464 465