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