1 ;------------------------------------------------------------------------------ 2 ;* 3 ;* Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> 4 ;* This program and the accompanying materials 5 ;* are licensed and made available under the terms and conditions of the BSD License 6 ;* which accompanies this distribution. The full text of the license may be found at 7 ;* http://opensource.org/licenses/bsd-license.php 8 ;* 9 ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 ;* 12 ;* start32.asm 13 ;* 14 ;* Abstract: 15 ;* 16 ;------------------------------------------------------------------------------ 17 18 .model small 19 .stack 20 .486p 21 .code 22 23 FAT_DIRECTORY_ENTRY_SIZE EQU 020h 24 FAT_DIRECTORY_ENTRY_SHIFT EQU 5 25 BLOCK_SIZE EQU 0200h 26 BLOCK_MASK EQU 01ffh 27 BLOCK_SHIFT EQU 9 28 29 org 0h 30 Ia32Jump: 31 jmp BootSectorEntryPoint ; JMP inst - 3 bytes 32 nop 33 34 OemId db "INTEL " ; OemId - 8 bytes 35 SectorSize dw 0 ; Sector Size - 2 bytes 36 SectorsPerCluster db 0 ; Sector Per Cluster - 1 byte 37 ReservedSectors dw 0 ; Reserved Sectors - 2 bytes 38 NoFats db 0 ; Number of FATs - 1 byte 39 RootEntries dw 0 ; Root Entries - 2 bytes 40 Sectors dw 0 ; Number of Sectors - 2 bytes 41 Media db 0 ; Media - 1 byte 42 SectorsPerFat16 dw 0 ; Sectors Per FAT for FAT12/FAT16 - 2 byte 43 SectorsPerTrack dw 0 ; Sectors Per Track - 2 bytes 44 Heads dw 0 ; Heads - 2 bytes 45 HiddenSectors dd 0 ; Hidden Sectors - 4 bytes 46 LargeSectors dd 0 ; Large Sectors - 4 bytes 47 48 ;****************************************************************************** 49 ; 50 ;The structure for FAT32 starting at offset 36 of the boot sector. (At this point, 51 ;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.) 52 ; 53 ;****************************************************************************** 54 55 SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes 56 ExtFlags dw 0 ; Mirror Flag - 2 bytes 57 FSVersion dw 0 ; File System Version - 2 bytes 58 RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes 59 FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes 60 BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes 61 Reserved db 12 dup(0) ; Reserved Field - 12 bytes 62 PhysicalDrive db 0 ; Physical Drive Number - 1 byte 63 Reserved1 db 0 ; Reserved Field - 1 byte 64 Signature db 0 ; Extended Boot Signature - 1 byte 65 VolId db " " ; Volume Serial Number - 4 bytes 66 FatLabel db " " ; Volume Label - 11 bytes 67 FileSystemType db "FAT32 " ; File System Type - 8 bytes 68 69 BootSectorEntryPoint: 70 ASSUME ds:@code 71 ASSUME ss:@code 72 ; ds = 1000, es = 2000 + x (size of first cluster >> 4) 73 ; cx = Start Cluster of EfiLdr 74 ; dx = Start Cluster of Efivar.bin 75 76 ; Re use the BPB data stored in Boot Sector 77 mov bp,07c00h 78 79 80 push cx 81 ; Read Efivar.bin 82 ; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already 83 mov ax,01900h 84 mov es,ax 85 test dx,dx 86 jnz CheckVarStoreSize 87 88 mov al,1 89 NoVarStore: 90 push es 91 ; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl 92 mov byte ptr es:[4],al 93 jmp SaveVolumeId 94 95 CheckVarStoreSize: 96 mov di,dx 97 cmp dword ptr ds:[di+2], 04000h 98 mov al,2 99 jne NoVarStore 100 101 LoadVarStore: 102 mov al,0 103 mov byte ptr es:[4],al 104 mov cx,word ptr[di] 105 ; ES:DI = 1500:0 106 xor di,di 107 push es 108 mov ax,01500h 109 mov es,ax 110 call ReadFile 111 SaveVolumeId: 112 pop es 113 mov ax,word ptr [bp+VolId] 114 mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId 115 mov ax,word ptr [bp+VolId+2] 116 mov word ptr es:[2],ax 117 118 ; Read Efildr 119 pop cx 120 ; cx = Start Cluster of Efildr -> BS.com has filled already 121 ; ES:DI = 2000:0, first cluster will be read again 122 xor di,di ; di = 0 123 mov ax,02000h 124 mov es,ax 125 call ReadFile 126 mov ax,cs 127 mov word ptr cs:[JumpSegment],ax 128 JumpFarInstruction: 129 db 0eah 130 JumpOffset: 131 dw 0200h 132 JumpSegment: 133 dw 2000h 134 135 136 137 138 ; **************************************************************************** 139 ; ReadFile 140 ; 141 ; Arguments: 142 ; CX = Start Cluster of File 143 ; ES:DI = Buffer to store file content read from disk 144 ; 145 ; Return: 146 ; (ES << 4 + DI) = end of file content Buffer 147 ; 148 ; **************************************************************************** 149 ReadFile: 150 ; si = NumberOfClusters 151 ; cx = ClusterNumber 152 ; dx = CachedFatSectorNumber 153 ; ds:0000 = CacheFatSectorBuffer 154 ; es:di = Buffer to load file 155 ; bx = NextClusterNumber 156 pusha 157 mov si,1 ; NumberOfClusters = 1 158 push cx ; Push Start Cluster onto stack 159 mov dx,0fffh ; CachedFatSectorNumber = 0xfff 160 FatChainLoop: 161 mov ax,cx ; ax = ClusterNumber 162 and ax,0fff8h ; ax = ax & 0xfff8 163 cmp ax,0fff8h ; See if this is the last cluster 164 je FoundLastCluster ; Jump if last cluster found 165 mov ax,cx ; ax = ClusterNumber 166 shl ax,2 ; FatOffset = ClusterNumber * 4 167 push si ; Save si 168 mov si,ax ; si = FatOffset 169 shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT 170 add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET) 171 and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK 172 cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber 173 je SkipFatRead 174 mov bx,2 175 push es 176 push ds 177 pop es 178 call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI 179 pop es 180 mov dx,ax ; CachedFatSectorNumber = FatSectorNumber 181 SkipFatRead: 182 mov bx,word ptr [si] ; bx = NextClusterNumber 183 mov ax,cx ; ax = ClusterNumber 184 pop si ; Restore si 185 dec bx ; bx = NextClusterNumber - 1 186 cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber 187 jne ReadClusters 188 inc bx ; bx = NextClusterNumber 189 inc si ; NumberOfClusters++ 190 mov cx,bx ; ClusterNumber = NextClusterNumber 191 jmp FatChainLoop 192 ReadClusters: 193 inc bx 194 pop ax ; ax = StartCluster 195 push bx ; StartCluster = NextClusterNumber 196 mov cx,bx ; ClusterNumber = NextClusterNumber 197 sub ax,2 ; ax = StartCluster - 2 198 xor bh,bh 199 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster 200 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster 201 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster 202 push ax ; save start sector 203 mov ax,si ; ax = NumberOfClusters 204 mul bx ; ax = NumberOfClusters * SectorsPerCluster 205 mov bx,ax ; bx = Number of Sectors 206 pop ax ; ax = Start Sector 207 call ReadBlocks 208 mov si,1 ; NumberOfClusters = 1 209 jmp FatChainLoop 210 FoundLastCluster: 211 pop cx 212 popa 213 ret 214 215 216 ; **************************************************************************** 217 ; ReadBlocks - Reads a set of blocks from a block device 218 ; 219 ; AX = Start LBA 220 ; BX = Number of Blocks to Read 221 ; ES:DI = Buffer to store sectors read from disk 222 ; **************************************************************************** 223 224 ; cx = Blocks 225 ; bx = NumberOfBlocks 226 ; si = StartLBA 227 228 ReadBlocks: 229 pusha 230 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA 231 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA 232 mov esi,eax ; esi = Start LBA 233 mov cx,bx ; cx = Number of blocks to read 234 ReadCylinderLoop: 235 mov bp,07bfch ; bp = 0x7bfc 236 mov eax,esi ; eax = Start LBA 237 xor edx,edx ; edx = 0 238 movzx ebx,word ptr [bp] ; bx = MaxSector 239 div ebx ; ax = StartLBA / MaxSector 240 inc dx ; dx = (StartLBA % MaxSector) + 1 241 242 mov bx,word ptr [bp] ; bx = MaxSector 243 sub bx,dx ; bx = MaxSector - Sector 244 inc bx ; bx = MaxSector - Sector + 1 245 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1) 246 jg LimitTransfer 247 mov bx,cx ; bx = Blocks 248 LimitTransfer: 249 push ax ; save ax 250 mov ax,es ; ax = es 251 shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system 252 and ax,07fh ; ax = Number of blocks into current seg 253 add ax,bx ; ax = End Block number of transfer 254 cmp ax,080h ; See if it crosses a 64K boundry 255 jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry 256 sub ax,080h ; ax = Number of blocks past 64K boundry 257 sub bx,ax ; Decrease transfer size by block overage 258 NotCrossing64KBoundry: 259 pop ax ; restore ax 260 261 push cx 262 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector 263 xor dx,dx ; dx = 0 264 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder 265 ; dx = ax % (MaxHead + 1) = Head 266 267 push bx ; Save number of blocks to transfer 268 mov dh,dl ; dh = Head 269 mov bp,07c00h ; bp = 0x7c00 270 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number 271 mov ch,al ; ch = Cylinder 272 mov al,bl ; al = Blocks 273 mov ah,2 ; ah = Function 2 274 mov bx,di ; es:bx = Buffer address 275 int 013h 276 jc DiskError 277 pop bx 278 pop cx 279 movzx ebx,bx 280 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks 281 sub cx,bx ; Blocks = Blocks - NumberOfBlocks 282 mov ax,es 283 shl bx,(BLOCK_SHIFT-4) 284 add ax,bx 285 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE 286 cmp cx,0 287 jne ReadCylinderLoop 288 popa 289 ret 290 291 DiskError: 292 push cs 293 pop ds 294 lea si, [ErrorString] 295 mov cx, 7 296 jmp PrintStringAndHalt 297 298 PrintStringAndHalt: 299 mov ax,0b800h 300 mov es,ax 301 mov di,160 302 rep movsw 303 Halt: 304 jmp Halt 305 306 ErrorString: 307 db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch 308 309 org 01fah 310 LBAOffsetForBootSector: 311 dd 0h 312 313 org 01feh 314 dw 0aa55h 315 316 ;****************************************************************************** 317 ;****************************************************************************** 318 ;****************************************************************************** 319 320 DELAY_PORT equ 0edh ; Port to use for 1uS delay 321 KBD_CONTROL_PORT equ 060h ; 8042 control port 322 KBD_STATUS_PORT equ 064h ; 8042 status port 323 WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port 324 ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20 325 326 org 200h 327 jmp start 328 Em64String: 329 db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch 330 331 start: 332 mov ax,cs 333 mov ds,ax 334 mov es,ax 335 mov ss,ax 336 mov sp,MyStack 337 338 ; mov ax,0b800h 339 ; mov es,ax 340 ; mov byte ptr es:[160],'a' 341 ; mov ax,cs 342 ; mov es,ax 343 344 mov ebx,0 345 lea edi,MemoryMap 346 MemMapLoop: 347 mov eax,0e820h 348 mov ecx,20 349 mov edx,'SMAP' 350 int 15h 351 jc MemMapDone 352 add edi,20 353 cmp ebx,0 354 je MemMapDone 355 jmp MemMapLoop 356 MemMapDone: 357 lea eax,MemoryMap 358 sub edi,eax ; Get the address of the memory map 359 mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map 360 361 xor ebx,ebx 362 mov bx,cs ; BX=segment 363 shl ebx,4 ; BX="linear" address of segment base 364 lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt 365 mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr 366 lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt 367 mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr 368 lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map 369 370 add ebx,01000h ; Source of EFI32 371 mov dword ptr [JUMP+2],ebx 372 add ebx,01000h 373 mov esi,ebx ; Source of EFILDR32 374 375 ; mov ax,0b800h 376 ; mov es,ax 377 ; mov byte ptr es:[162],'b' 378 ; mov ax,cs 379 ; mov es,ax 380 381 ; 382 ; Enable A20 Gate 383 ; 384 385 mov ax,2401h ; Enable A20 Gate 386 int 15h 387 jnc A20GateEnabled ; Jump if it suceeded 388 389 ; 390 ; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually. 391 ; 392 393 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 394 jnz Timeout8042 ; Jump if the 8042 timed out 395 out DELAY_PORT,ax ; Delay 1 uS 396 mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port 397 out KBD_STATUS_PORT,al ; Send command to the 8042 398 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 399 jnz Timeout8042 ; Jump if the 8042 timed out 400 mov al,ENABLE_A20_CMD ; gate address bit 20 on 401 out KBD_CONTROL_PORT,al ; Send command to thre 8042 402 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 403 mov cx,25 ; Delay 25 uS for the command to complete on the 8042 404 Delay25uS: 405 out DELAY_PORT,ax ; Delay 1 uS 406 loop Delay25uS 407 Timeout8042: 408 409 410 A20GateEnabled: 411 mov bx,0008h ; Flat data descriptor 412 ; 413 ; DISABLE INTERRUPTS - Entering Protected Mode 414 ; 415 416 cli 417 418 ; mov ax,0b800h 419 ; mov es,ax 420 ; mov byte ptr es:[164],'c' 421 ; mov ax,cs 422 ; mov es,ax 423 424 db 66h 425 lgdt fword ptr [gdtr] 426 db 66h 427 lidt fword ptr [idtr] 428 429 mov eax,cr0 430 or al,1 431 mov cr0,eax 432 JUMP: 433 ; jmp far 0010:00020000 434 db 066h 435 db 0eah 436 dd 000020000h 437 dw 00010h 438 439 Empty8042InputBuffer: 440 mov cx,0 441 Empty8042Loop: 442 out DELAY_PORT,ax ; Delay 1us 443 in al,KBD_STATUS_PORT ; Read the 8042 Status Port 444 and al,02h ; Check the Input Buffer Full Flag 445 loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS 446 ret 447 448 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 449 ; data 450 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 451 452 align 02h 453 454 gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit 455 dd 0 ; (GDT base gets set above) 456 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 457 ; global descriptor table (GDT) 458 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 459 460 align 02h 461 462 public GDT_BASE 463 GDT_BASE: 464 ; null descriptor 465 NULL_SEL equ $-GDT_BASE 466 dw 0 ; limit 15:0 467 dw 0 ; base 15:0 468 db 0 ; base 23:16 469 db 0 ; type 470 db 0 ; limit 19:16, flags 471 db 0 ; base 31:24 472 473 ; linear data segment descriptor 474 LINEAR_SEL equ $-GDT_BASE 475 dw 0FFFFh ; limit 0xFFFFF 476 dw 0 ; base 0 477 db 0 478 db 092h ; present, ring 0, data, expand-up, writable 479 db 0CFh ; page-granular, 32-bit 480 db 0 481 482 ; linear code segment descriptor 483 LINEAR_CODE_SEL equ $-GDT_BASE 484 dw 0FFFFh ; limit 0xFFFFF 485 dw 0 ; base 0 486 db 0 487 db 09Ah ; present, ring 0, data, expand-up, writable 488 db 0CFh ; page-granular, 32-bit 489 db 0 490 491 ; system data segment descriptor 492 SYS_DATA_SEL equ $-GDT_BASE 493 dw 0FFFFh ; limit 0xFFFFF 494 dw 0 ; base 0 495 db 0 496 db 092h ; present, ring 0, data, expand-up, writable 497 db 0CFh ; page-granular, 32-bit 498 db 0 499 500 ; system code segment descriptor 501 SYS_CODE_SEL equ $-GDT_BASE 502 dw 0FFFFh ; limit 0xFFFFF 503 dw 0 ; base 0 504 db 0 505 db 09Ah ; present, ring 0, data, expand-up, writable 506 db 0CFh ; page-granular, 32-bit 507 db 0 508 509 ; spare segment descriptor 510 SPARE3_SEL equ $-GDT_BASE 511 dw 0 ; limit 0xFFFFF 512 dw 0 ; base 0 513 db 0 514 db 0 ; present, ring 0, data, expand-up, writable 515 db 0 ; page-granular, 32-bit 516 db 0 517 518 ; spare segment descriptor 519 SPARE4_SEL equ $-GDT_BASE 520 dw 0 ; limit 0xFFFFF 521 dw 0 ; base 0 522 db 0 523 db 0 ; present, ring 0, data, expand-up, writable 524 db 0 ; page-granular, 32-bit 525 db 0 526 527 ; spare segment descriptor 528 SPARE5_SEL equ $-GDT_BASE 529 dw 0 ; limit 0xFFFFF 530 dw 0 ; base 0 531 db 0 532 db 0 ; present, ring 0, data, expand-up, writable 533 db 0 ; page-granular, 32-bit 534 db 0 535 536 GDT_END: 537 538 align 02h 539 540 541 542 idtr dw IDT_END - IDT_BASE - 1 ; IDT limit 543 dd 0 ; (IDT base gets set above) 544 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 545 ; interrupt descriptor table (IDT) 546 ; 547 ; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ 548 ; mappings. This implementation only uses the system timer and all other 549 ; IRQs will remain masked. The descriptors for vectors 33+ are provided 550 ; for convenience. 551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 552 553 ;idt_tag db "IDT",0 554 align 02h 555 556 public IDT_BASE 557 IDT_BASE: 558 ; divide by zero (INT 0) 559 DIV_ZERO_SEL equ $-IDT_BASE 560 dw 0 ; offset 15:0 561 dw SYS_CODE_SEL ; selector 15:0 562 db 0 ; 0 for interrupt gate 563 db 0eh OR 80h ; type = 386 interrupt gate, present 564 dw 0 ; offset 31:16 565 566 ; debug exception (INT 1) 567 DEBUG_EXCEPT_SEL equ $-IDT_BASE 568 dw 0 ; offset 15:0 569 dw SYS_CODE_SEL ; selector 15:0 570 db 0 ; 0 for interrupt gate 571 db 0eh OR 80h ; type = 386 interrupt gate, present 572 dw 0 ; offset 31:16 573 574 ; NMI (INT 2) 575 NMI_SEL equ $-IDT_BASE 576 dw 0 ; offset 15:0 577 dw SYS_CODE_SEL ; selector 15:0 578 db 0 ; 0 for interrupt gate 579 db 0eh OR 80h ; type = 386 interrupt gate, present 580 dw 0 ; offset 31:16 581 582 ; soft breakpoint (INT 3) 583 BREAKPOINT_SEL equ $-IDT_BASE 584 dw 0 ; offset 15:0 585 dw SYS_CODE_SEL ; selector 15:0 586 db 0 ; 0 for interrupt gate 587 db 0eh OR 80h ; type = 386 interrupt gate, present 588 dw 0 ; offset 31:16 589 590 ; overflow (INT 4) 591 OVERFLOW_SEL equ $-IDT_BASE 592 dw 0 ; offset 15:0 593 dw SYS_CODE_SEL ; selector 15:0 594 db 0 ; 0 for interrupt gate 595 db 0eh OR 80h ; type = 386 interrupt gate, present 596 dw 0 ; offset 31:16 597 598 ; bounds check (INT 5) 599 BOUNDS_CHECK_SEL equ $-IDT_BASE 600 dw 0 ; offset 15:0 601 dw SYS_CODE_SEL ; selector 15:0 602 db 0 ; 0 for interrupt gate 603 db 0eh OR 80h ; type = 386 interrupt gate, present 604 dw 0 ; offset 31:16 605 606 ; invalid opcode (INT 6) 607 INVALID_OPCODE_SEL equ $-IDT_BASE 608 dw 0 ; offset 15:0 609 dw SYS_CODE_SEL ; selector 15:0 610 db 0 ; 0 for interrupt gate 611 db 0eh OR 80h ; type = 386 interrupt gate, present 612 dw 0 ; offset 31:16 613 614 ; device not available (INT 7) 615 DEV_NOT_AVAIL_SEL equ $-IDT_BASE 616 dw 0 ; offset 15:0 617 dw SYS_CODE_SEL ; selector 15:0 618 db 0 ; 0 for interrupt gate 619 db 0eh OR 80h ; type = 386 interrupt gate, present 620 dw 0 ; offset 31:16 621 622 ; double fault (INT 8) 623 DOUBLE_FAULT_SEL equ $-IDT_BASE 624 dw 0 ; offset 15:0 625 dw SYS_CODE_SEL ; selector 15:0 626 db 0 ; 0 for interrupt gate 627 db 0eh OR 80h ; type = 386 interrupt gate, present 628 dw 0 ; offset 31:16 629 630 ; Coprocessor segment overrun - reserved (INT 9) 631 RSVD_INTR_SEL1 equ $-IDT_BASE 632 dw 0 ; offset 15:0 633 dw SYS_CODE_SEL ; selector 15:0 634 db 0 ; 0 for interrupt gate 635 db 0eh OR 80h ; type = 386 interrupt gate, present 636 dw 0 ; offset 31:16 637 638 ; invalid TSS (INT 0ah) 639 INVALID_TSS_SEL equ $-IDT_BASE 640 dw 0 ; offset 15:0 641 dw SYS_CODE_SEL ; selector 15:0 642 db 0 ; 0 for interrupt gate 643 db 0eh OR 80h ; type = 386 interrupt gate, present 644 dw 0 ; offset 31:16 645 646 ; segment not present (INT 0bh) 647 SEG_NOT_PRESENT_SEL equ $-IDT_BASE 648 dw 0 ; offset 15:0 649 dw SYS_CODE_SEL ; selector 15:0 650 db 0 ; 0 for interrupt gate 651 db 0eh OR 80h ; type = 386 interrupt gate, present 652 dw 0 ; offset 31:16 653 654 ; stack fault (INT 0ch) 655 STACK_FAULT_SEL equ $-IDT_BASE 656 dw 0 ; offset 15:0 657 dw SYS_CODE_SEL ; selector 15:0 658 db 0 ; 0 for interrupt gate 659 db 0eh OR 80h ; type = 386 interrupt gate, present 660 dw 0 ; offset 31:16 661 662 ; general protection (INT 0dh) 663 GP_FAULT_SEL equ $-IDT_BASE 664 dw 0 ; offset 15:0 665 dw SYS_CODE_SEL ; selector 15:0 666 db 0 ; 0 for interrupt gate 667 db 0eh OR 80h ; type = 386 interrupt gate, present 668 dw 0 ; offset 31:16 669 670 ; page fault (INT 0eh) 671 PAGE_FAULT_SEL equ $-IDT_BASE 672 dw 0 ; offset 15:0 673 dw SYS_CODE_SEL ; selector 15:0 674 db 0 ; 0 for interrupt gate 675 db 0eh OR 80h ; type = 386 interrupt gate, present 676 dw 0 ; offset 31:16 677 678 ; Intel reserved - do not use (INT 0fh) 679 RSVD_INTR_SEL2 equ $-IDT_BASE 680 dw 0 ; offset 15:0 681 dw SYS_CODE_SEL ; selector 15:0 682 db 0 ; 0 for interrupt gate 683 db 0eh OR 80h ; type = 386 interrupt gate, present 684 dw 0 ; offset 31:16 685 686 ; floating point error (INT 10h) 687 FLT_POINT_ERR_SEL equ $-IDT_BASE 688 dw 0 ; offset 15:0 689 dw SYS_CODE_SEL ; selector 15:0 690 db 0 ; 0 for interrupt gate 691 db 0eh OR 80h ; type = 386 interrupt gate, present 692 dw 0 ; offset 31:16 693 694 ; alignment check (INT 11h) 695 ALIGNMENT_CHECK_SEL equ $-IDT_BASE 696 dw 0 ; offset 15:0 697 dw SYS_CODE_SEL ; selector 15:0 698 db 0 ; 0 for interrupt gate 699 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 700 dw 0 ; offset 31:16 701 702 ; machine check (INT 12h) 703 MACHINE_CHECK_SEL equ $-IDT_BASE 704 dw 0 ; offset 15:0 705 dw SYS_CODE_SEL ; selector 15:0 706 db 0 ; 0 for interrupt gate 707 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 708 dw 0 ; offset 31:16 709 710 ; SIMD floating-point exception (INT 13h) 711 SIMD_EXCEPTION_SEL equ $-IDT_BASE 712 dw 0 ; offset 15:0 713 dw SYS_CODE_SEL ; selector 15:0 714 db 0 ; 0 for interrupt gate 715 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 716 dw 0 ; offset 31:16 717 718 ; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail 719 db (85 * 8) dup(0) 720 721 ; IRQ 0 (System timer) - (INT 68h) 722 IRQ0_SEL equ $-IDT_BASE 723 dw 0 ; offset 15:0 724 dw SYS_CODE_SEL ; selector 15:0 725 db 0 ; 0 for interrupt gate 726 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 727 dw 0 ; offset 31:16 728 729 ; IRQ 1 (8042 Keyboard controller) - (INT 69h) 730 IRQ1_SEL equ $-IDT_BASE 731 dw 0 ; offset 15:0 732 dw SYS_CODE_SEL ; selector 15:0 733 db 0 ; 0 for interrupt gate 734 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 735 dw 0 ; offset 31:16 736 737 ; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah) 738 IRQ2_SEL equ $-IDT_BASE 739 dw 0 ; offset 15:0 740 dw SYS_CODE_SEL ; selector 15:0 741 db 0 ; 0 for interrupt gate 742 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 743 dw 0 ; offset 31:16 744 745 ; IRQ 3 (COM 2) - (INT 6bh) 746 IRQ3_SEL equ $-IDT_BASE 747 dw 0 ; offset 15:0 748 dw SYS_CODE_SEL ; selector 15:0 749 db 0 ; 0 for interrupt gate 750 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 751 dw 0 ; offset 31:16 752 753 ; IRQ 4 (COM 1) - (INT 6ch) 754 IRQ4_SEL equ $-IDT_BASE 755 dw 0 ; offset 15:0 756 dw SYS_CODE_SEL ; selector 15:0 757 db 0 ; 0 for interrupt gate 758 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 759 dw 0 ; offset 31:16 760 761 ; IRQ 5 (LPT 2) - (INT 6dh) 762 IRQ5_SEL equ $-IDT_BASE 763 dw 0 ; offset 15:0 764 dw SYS_CODE_SEL ; selector 15:0 765 db 0 ; 0 for interrupt gate 766 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 767 dw 0 ; offset 31:16 768 769 ; IRQ 6 (Floppy controller) - (INT 6eh) 770 IRQ6_SEL equ $-IDT_BASE 771 dw 0 ; offset 15:0 772 dw SYS_CODE_SEL ; selector 15:0 773 db 0 ; 0 for interrupt gate 774 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 775 dw 0 ; offset 31:16 776 777 ; IRQ 7 (LPT 1) - (INT 6fh) 778 IRQ7_SEL equ $-IDT_BASE 779 dw 0 ; offset 15:0 780 dw SYS_CODE_SEL ; selector 15:0 781 db 0 ; 0 for interrupt gate 782 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 783 dw 0 ; offset 31:16 784 785 ; IRQ 8 (RTC Alarm) - (INT 70h) 786 IRQ8_SEL equ $-IDT_BASE 787 dw 0 ; offset 15:0 788 dw SYS_CODE_SEL ; selector 15:0 789 db 0 ; 0 for interrupt gate 790 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 791 dw 0 ; offset 31:16 792 793 ; IRQ 9 - (INT 71h) 794 IRQ9_SEL equ $-IDT_BASE 795 dw 0 ; offset 15:0 796 dw SYS_CODE_SEL ; selector 15:0 797 db 0 ; 0 for interrupt gate 798 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 799 dw 0 ; offset 31:16 800 801 ; IRQ 10 - (INT 72h) 802 IRQ10_SEL equ $-IDT_BASE 803 dw 0 ; offset 15:0 804 dw SYS_CODE_SEL ; selector 15:0 805 db 0 ; 0 for interrupt gate 806 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 807 dw 0 ; offset 31:16 808 809 ; IRQ 11 - (INT 73h) 810 IRQ11_SEL equ $-IDT_BASE 811 dw 0 ; offset 15:0 812 dw SYS_CODE_SEL ; selector 15:0 813 db 0 ; 0 for interrupt gate 814 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 815 dw 0 ; offset 31:16 816 817 ; IRQ 12 (PS/2 mouse) - (INT 74h) 818 IRQ12_SEL equ $-IDT_BASE 819 dw 0 ; offset 15:0 820 dw SYS_CODE_SEL ; selector 15:0 821 db 0 ; 0 for interrupt gate 822 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 823 dw 0 ; offset 31:16 824 825 ; IRQ 13 (Floating point error) - (INT 75h) 826 IRQ13_SEL equ $-IDT_BASE 827 dw 0 ; offset 15:0 828 dw SYS_CODE_SEL ; selector 15:0 829 db 0 ; 0 for interrupt gate 830 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 831 dw 0 ; offset 31:16 832 833 ; IRQ 14 (Secondary IDE) - (INT 76h) 834 IRQ14_SEL equ $-IDT_BASE 835 dw 0 ; offset 15:0 836 dw SYS_CODE_SEL ; selector 15:0 837 db 0 ; 0 for interrupt gate 838 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 839 dw 0 ; offset 31:16 840 841 ; IRQ 15 (Primary IDE) - (INT 77h) 842 IRQ15_SEL equ $-IDT_BASE 843 dw 0 ; offset 15:0 844 dw SYS_CODE_SEL ; selector 15:0 845 db 0 ; 0 for interrupt gate 846 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 847 dw 0 ; offset 31:16 848 849 IDT_END: 850 851 align 02h 852 853 MemoryMapSize dd 0 854 MemoryMap dd 0,0,0,0,0,0,0,0 855 dd 0,0,0,0,0,0,0,0 856 dd 0,0,0,0,0,0,0,0 857 dd 0,0,0,0,0,0,0,0 858 dd 0,0,0,0,0,0,0,0 859 dd 0,0,0,0,0,0,0,0 860 dd 0,0,0,0,0,0,0,0 861 dd 0,0,0,0,0,0,0,0 862 dd 0,0,0,0,0,0,0,0 863 dd 0,0,0,0,0,0,0,0 864 dd 0,0,0,0,0,0,0,0 865 dd 0,0,0,0,0,0,0,0 866 dd 0,0,0,0,0,0,0,0 867 dd 0,0,0,0,0,0,0,0 868 dd 0,0,0,0,0,0,0,0 869 dd 0,0,0,0,0,0,0,0 870 dd 0,0,0,0,0,0,0,0 871 dd 0,0,0,0,0,0,0,0 872 dd 0,0,0,0,0,0,0,0 873 dd 0,0,0,0,0,0,0,0 874 dd 0,0,0,0,0,0,0,0 875 dd 0,0,0,0,0,0,0,0 876 dd 0,0,0,0,0,0,0,0 877 dd 0,0,0,0,0,0,0,0 878 dd 0,0,0,0,0,0,0,0 879 dd 0,0,0,0,0,0,0,0 880 dd 0,0,0,0,0,0,0,0 881 dd 0,0,0,0,0,0,0,0 882 dd 0,0,0,0,0,0,0,0 883 dd 0,0,0,0,0,0,0,0 884 885 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 886 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 887 888 org 0fe0h 889 MyStack: 890 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh 891 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a 892 ; known low address (20f00) so it can be set up by PlMapIrqToVect in 893 ; 8259.c 894 895 int 8 896 iret 897 898 int 9 899 iret 900 901 int 10 902 iret 903 904 int 11 905 iret 906 907 int 12 908 iret 909 910 int 13 911 iret 912 913 int 14 914 iret 915 916 int 15 917 iret 918 919 920 org 0ffeh 921 BlockSignature: 922 dw 0aa55h 923 924 end 925