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;* start.asm 13;* 14;* Abstract: 15;* 16;------------------------------------------------------------------------------ 17 18 .model small 19 .stack 20 .486p 21 .code 22 23FAT_DIRECTORY_ENTRY_SIZE EQU 020h 24FAT_DIRECTORY_ENTRY_SHIFT EQU 5 25BLOCK_SIZE EQU 0200h 26BLOCK_MASK EQU 01ffh 27BLOCK_SHIFT EQU 9 28 29 org 0h 30Ia32Jump: 31 jmp BootSectorEntryPoint ; JMP inst - 3 bytes 32 nop 33 34OemId db "INTEL " ; OemId - 8 bytes 35 36SectorSize dw 0 ; Sector Size - 16 bits 37SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits 38ReservedSectors dw 0 ; Reserved Sectors - 16 bits 39NoFats db 0 ; Number of FATs - 8 bits 40RootEntries dw 0 ; Root Entries - 16 bits 41Sectors dw 0 ; Number of Sectors - 16 bits 42Media db 0 ; Media - 8 bits - ignored 43SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits 44SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored 45Heads dw 0 ; Heads - 16 bits - ignored 46HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored 47LargeSectors dd 0 ; Large Sectors - 32 bits 48PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored 49CurrentHead db 0 ; Current Head - 8 bits 50Signature db 0 ; Signature - 8 bits - ignored 51VolId db " " ; Volume Serial Number- 4 bytes 52FatLabel db " " ; Label - 11 bytes 53SystemId db "FAT12 " ; SystemId - 8 bytes 54 55BootSectorEntryPoint: 56 ASSUME ds:@code 57 ASSUME ss:@code 58 ; ds = 1000, es = 2000 + x (size of first cluster >> 4) 59 ; cx = Start Cluster of EfiLdr 60 ; dx = Start Cluster of Efivar.bin 61 62; Re use the BPB data stored in Boot Sector 63 mov bp,07c00h 64 65 push cx 66; Read Efivar.bin 67; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already 68 mov ax,01900h 69 mov es,ax 70 test dx,dx 71 jnz CheckVarStoreSize 72 73 mov al,1 74NoVarStore: 75 push es 76; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl 77 mov byte ptr es:[4],al 78 jmp SaveVolumeId 79 80CheckVarStoreSize: 81 mov di,dx 82 cmp dword ptr ds:[di+2], 04000h 83 mov al,2 84 jne NoVarStore 85 86LoadVarStore: 87 mov al,0 88 mov byte ptr es:[4],al 89 mov cx,word ptr[di] 90; ES:DI = 1500:0 91 xor di,di 92 push es 93 mov ax,01500h 94 mov es,ax 95 call ReadFile 96SaveVolumeId: 97 pop es 98 mov ax,word ptr [bp+VolId] 99 mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId 100 mov ax,word ptr [bp+VolId+2] 101 mov word ptr es:[2],ax 102 103; Read Efildr 104 pop cx 105; cx = Start Cluster of Efildr -> BS.com has filled already 106; ES:DI = 2000:0, first cluster will be read again 107 xor di,di ; di = 0 108 mov ax,02000h 109 mov es,ax 110 call ReadFile 111 mov ax,cs 112 mov word ptr cs:[JumpSegment],ax 113 114JumpFarInstruction: 115 db 0eah 116JumpOffset: 117 dw 0200h 118JumpSegment: 119 dw 2000h 120 121 122 123; **************************************************************************** 124; ReadFile 125; 126; Arguments: 127; CX = Start Cluster of File 128; ES:DI = Buffer to store file content read from disk 129; 130; Return: 131; (ES << 4 + DI) = end of file content Buffer 132; 133; **************************************************************************** 134ReadFile: 135; si = NumberOfClusters 136; cx = ClusterNumber 137; dx = CachedFatSectorNumber 138; ds:0000 = CacheFatSectorBuffer 139; es:di = Buffer to load file 140; bx = NextClusterNumber 141 pusha 142 mov si,1 ; NumberOfClusters = 1 143 push cx ; Push Start Cluster onto stack 144 mov dx,0fffh ; CachedFatSectorNumber = 0xfff 145FatChainLoop: 146 mov ax,cx ; ax = ClusterNumber 147 and ax,0ff8h ; ax = ax & 0xff8 148 cmp ax,0ff8h ; See if this is the last cluster 149 je FoundLastCluster ; Jump if last cluster found 150 mov ax,cx ; ax = ClusterNumber 151 shl ax,1 ; ax = ClusterNumber * 2 152 add ax,cx ; ax = ClusterNumber * 2 + ClusterNumber = ClusterNumber * 3 153 shr ax,1 ; FatOffset = ClusterNumber*3 / 2 154 push si ; Save si 155 mov si,ax ; si = FatOffset 156 shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT 157 add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET) 158 and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK 159 cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber 160 je SkipFatRead 161 mov bx,2 162 push es 163 push ds 164 pop es 165 call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI 166 pop es 167 mov dx,ax ; CachedFatSectorNumber = FatSectorNumber 168SkipFatRead: 169 mov bx,word ptr [si] ; bx = NextClusterNumber 170 mov ax,cx ; ax = ClusterNumber 171 and ax,1 ; See if this is an odd cluster number 172 je EvenFatEntry 173 shr bx,4 ; NextClusterNumber = NextClusterNumber >> 4 174EvenFatEntry: 175 and bx,0fffh ; Strip upper 4 bits of NextClusterNumber 176 pop si ; Restore si 177 dec bx ; bx = NextClusterNumber - 1 178 cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber 179 jne ReadClusters 180 inc bx ; bx = NextClusterNumber 181 inc si ; NumberOfClusters++ 182 mov cx,bx ; ClusterNumber = NextClusterNumber 183 jmp FatChainLoop 184ReadClusters: 185 inc bx 186 pop ax ; ax = StartCluster 187 push bx ; StartCluster = NextClusterNumber 188 mov cx,bx ; ClusterNumber = NextClusterNumber 189 sub ax,2 ; ax = StartCluster - 2 190 xor bh,bh 191 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster 192 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster 193 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster 194 push ax ; save start sector 195 mov ax,si ; ax = NumberOfClusters 196 mul bx ; ax = NumberOfClusters * SectorsPerCluster 197 mov bx,ax ; bx = Number of Sectors 198 pop ax ; ax = Start Sector 199 call ReadBlocks 200 mov si,1 ; NumberOfClusters = 1 201 jmp FatChainLoop 202FoundLastCluster: 203 pop cx 204 popa 205 ret 206 207 208; **************************************************************************** 209; ReadBlocks - Reads a set of blocks from a block device 210; 211; AX = Start LBA 212; BX = Number of Blocks to Read 213; ES:DI = Buffer to store sectors read from disk 214; **************************************************************************** 215 216; cx = Blocks 217; bx = NumberOfBlocks 218; si = StartLBA 219 220ReadBlocks: 221 pusha 222 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA 223 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA 224 mov esi,eax ; esi = Start LBA 225 mov cx,bx ; cx = Number of blocks to read 226ReadCylinderLoop: 227 mov bp,07bfch ; bp = 0x7bfc 228 mov eax,esi ; eax = Start LBA 229 xor edx,edx ; edx = 0 230 movzx ebx,word ptr [bp] ; bx = MaxSector 231 div ebx ; ax = StartLBA / MaxSector 232 inc dx ; dx = (StartLBA % MaxSector) + 1 233 234 mov bx,word ptr [bp] ; bx = MaxSector 235 sub bx,dx ; bx = MaxSector - Sector 236 inc bx ; bx = MaxSector - Sector + 1 237 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1) 238 jg LimitTransfer 239 mov bx,cx ; bx = Blocks 240LimitTransfer: 241 push ax ; save ax 242 mov ax,es ; ax = es 243 shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system 244 and ax,07fh ; ax = Number of blocks into current seg 245 add ax,bx ; ax = End Block number of transfer 246 cmp ax,080h ; See if it crosses a 64K boundry 247 jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry 248 sub ax,080h ; ax = Number of blocks past 64K boundry 249 sub bx,ax ; Decrease transfer size by block overage 250NotCrossing64KBoundry: 251 pop ax ; restore ax 252 253 push cx 254 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector 255 xor dx,dx ; dx = 0 256 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder 257 ; dx = ax % (MaxHead + 1) = Head 258 259 push bx ; Save number of blocks to transfer 260 mov dh,dl ; dh = Head 261 mov bp,07c00h ; bp = 0x7c00 262 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number 263 mov ch,al ; ch = Cylinder 264 mov al,bl ; al = Blocks 265 mov ah,2 ; ah = Function 2 266 mov bx,di ; es:bx = Buffer address 267 int 013h 268 jc DiskError 269 pop bx 270 pop cx 271 movzx ebx,bx 272 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks 273 sub cx,bx ; Blocks = Blocks - NumberOfBlocks 274 mov ax,es 275 shl bx,(BLOCK_SHIFT-4) 276 add ax,bx 277 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE 278 cmp cx,0 279 jne ReadCylinderLoop 280 popa 281 ret 282 283DiskError: 284 push cs 285 pop ds 286 lea si, [ErrorString] 287 mov cx, 7 288 jmp PrintStringAndHalt 289 290PrintStringAndHalt: 291 mov ax,0b800h 292 mov es,ax 293 mov di,160 294 rep movsw 295Halt: 296 jmp Halt 297 298ErrorString: 299 db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch 300 301 org 01fah 302LBAOffsetForBootSector: 303 dd 0h 304 305 org 01feh 306 dw 0aa55h 307 308;****************************************************************************** 309;****************************************************************************** 310;****************************************************************************** 311 312DELAY_PORT equ 0edh ; Port to use for 1uS delay 313KBD_CONTROL_PORT equ 060h ; 8042 control port 314KBD_STATUS_PORT equ 064h ; 8042 status port 315WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port 316ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20 317 318 org 200h 319 jmp start 320Em64String: 321 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 322 323start: 324 mov ax,cs 325 mov ds,ax 326 mov es,ax 327 mov ss,ax 328 mov sp,MyStack 329 330; mov ax,0b800h 331; mov es,ax 332; mov byte ptr es:[160],'a' 333; mov ax,cs 334; mov es,ax 335 336 mov ebx,0 337 lea edi,MemoryMap 338MemMapLoop: 339 mov eax,0e820h 340 mov ecx,20 341 mov edx,'SMAP' 342 int 15h 343 jc MemMapDone 344 add edi,20 345 cmp ebx,0 346 je MemMapDone 347 jmp MemMapLoop 348MemMapDone: 349 lea eax,MemoryMap 350 sub edi,eax ; Get the address of the memory map 351 mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map 352 353 xor ebx,ebx 354 mov bx,cs ; BX=segment 355 shl ebx,4 ; BX="linear" address of segment base 356 lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt 357 mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr 358 lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt 359 mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr 360 lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map 361 362 add ebx,01000h ; Source of EFI32 363 mov dword ptr [JUMP+2],ebx 364 add ebx,01000h 365 mov esi,ebx ; Source of EFILDR32 366 367; mov ax,0b800h 368; mov es,ax 369; mov byte ptr es:[162],'b' 370; mov ax,cs 371; mov es,ax 372 373; 374; Enable A20 Gate 375; 376 377 mov ax,2401h ; Enable A20 Gate 378 int 15h 379 jnc A20GateEnabled ; Jump if it suceeded 380 381; 382; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually. 383; 384 385 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 386 jnz Timeout8042 ; Jump if the 8042 timed out 387 out DELAY_PORT,ax ; Delay 1 uS 388 mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port 389 out KBD_STATUS_PORT,al ; Send command to the 8042 390 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 391 jnz Timeout8042 ; Jump if the 8042 timed out 392 mov al,ENABLE_A20_CMD ; gate address bit 20 on 393 out KBD_CONTROL_PORT,al ; Send command to thre 8042 394 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 395 mov cx,25 ; Delay 25 uS for the command to complete on the 8042 396Delay25uS: 397 out DELAY_PORT,ax ; Delay 1 uS 398 loop Delay25uS 399Timeout8042: 400 401 402A20GateEnabled: 403 mov bx,0008h ; Flat data descriptor 404; 405; DISABLE INTERRUPTS - Entering Protected Mode 406; 407 408 cli 409 410; mov ax,0b800h 411; mov es,ax 412; mov byte ptr es:[164],'c' 413; mov ax,cs 414; mov es,ax 415 416 db 66h 417 lgdt fword ptr [gdtr] 418 db 66h 419 lidt fword ptr [idtr] 420 421 mov eax,cr0 422 or al,1 423 mov cr0,eax 424JUMP: 425; jmp far 0010:00020000 426 db 066h 427 db 0eah 428 dd 000020000h 429 dw 00010h 430 431Empty8042InputBuffer: 432 mov cx,0 433Empty8042Loop: 434 out DELAY_PORT,ax ; Delay 1us 435 in al,KBD_STATUS_PORT ; Read the 8042 Status Port 436 and al,02h ; Check the Input Buffer Full Flag 437 loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS 438 ret 439 440;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 441; data 442;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 443 444 align 02h 445 446gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit 447 dd 0 ; (GDT base gets set above) 448;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 449; global descriptor table (GDT) 450;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 451 452 align 02h 453 454public GDT_BASE 455GDT_BASE: 456; null descriptor 457NULL_SEL equ $-GDT_BASE 458 dw 0 ; limit 15:0 459 dw 0 ; base 15:0 460 db 0 ; base 23:16 461 db 0 ; type 462 db 0 ; limit 19:16, flags 463 db 0 ; base 31:24 464 465; linear data segment descriptor 466LINEAR_SEL equ $-GDT_BASE 467 dw 0FFFFh ; limit 0xFFFFF 468 dw 0 ; base 0 469 db 0 470 db 092h ; present, ring 0, data, expand-up, writable 471 db 0CFh ; page-granular, 32-bit 472 db 0 473 474; linear code segment descriptor 475LINEAR_CODE_SEL equ $-GDT_BASE 476 dw 0FFFFh ; limit 0xFFFFF 477 dw 0 ; base 0 478 db 0 479 db 09Ah ; present, ring 0, data, expand-up, writable 480 db 0CFh ; page-granular, 32-bit 481 db 0 482 483; system data segment descriptor 484SYS_DATA_SEL equ $-GDT_BASE 485 dw 0FFFFh ; limit 0xFFFFF 486 dw 0 ; base 0 487 db 0 488 db 092h ; present, ring 0, data, expand-up, writable 489 db 0CFh ; page-granular, 32-bit 490 db 0 491 492; system code segment descriptor 493SYS_CODE_SEL equ $-GDT_BASE 494 dw 0FFFFh ; limit 0xFFFFF 495 dw 0 ; base 0 496 db 0 497 db 09Ah ; present, ring 0, data, expand-up, writable 498 db 0CFh ; page-granular, 32-bit 499 db 0 500 501; spare segment descriptor 502SPARE3_SEL equ $-GDT_BASE 503 dw 0 ; limit 0xFFFFF 504 dw 0 ; base 0 505 db 0 506 db 0 ; present, ring 0, data, expand-up, writable 507 db 0 ; page-granular, 32-bit 508 db 0 509 510; spare segment descriptor 511SPARE4_SEL equ $-GDT_BASE 512 dw 0 ; limit 0xFFFFF 513 dw 0 ; base 0 514 db 0 515 db 0 ; present, ring 0, data, expand-up, writable 516 db 0 ; page-granular, 32-bit 517 db 0 518 519; spare segment descriptor 520SPARE5_SEL equ $-GDT_BASE 521 dw 0 ; limit 0xFFFFF 522 dw 0 ; base 0 523 db 0 524 db 0 ; present, ring 0, data, expand-up, writable 525 db 0 ; page-granular, 32-bit 526 db 0 527 528GDT_END: 529 530 align 02h 531 532 533 534idtr dw IDT_END - IDT_BASE - 1 ; IDT limit 535 dd 0 ; (IDT base gets set above) 536;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 537; interrupt descriptor table (IDT) 538; 539; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ 540; mappings. This implementation only uses the system timer and all other 541; IRQs will remain masked. The descriptors for vectors 33+ are provided 542; for convenience. 543;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 544 545;idt_tag db "IDT",0 546 align 02h 547 548public IDT_BASE 549IDT_BASE: 550; divide by zero (INT 0) 551DIV_ZERO_SEL equ $-IDT_BASE 552 dw 0 ; offset 15:0 553 dw SYS_CODE_SEL ; selector 15:0 554 db 0 ; 0 for interrupt gate 555 db 0eh OR 80h ; type = 386 interrupt gate, present 556 dw 0 ; offset 31:16 557 558; debug exception (INT 1) 559DEBUG_EXCEPT_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; NMI (INT 2) 567NMI_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; soft breakpoint (INT 3) 575BREAKPOINT_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; overflow (INT 4) 583OVERFLOW_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; bounds check (INT 5) 591BOUNDS_CHECK_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; invalid opcode (INT 6) 599INVALID_OPCODE_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; device not available (INT 7) 607DEV_NOT_AVAIL_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; double fault (INT 8) 615DOUBLE_FAULT_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; Coprocessor segment overrun - reserved (INT 9) 623RSVD_INTR_SEL1 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; invalid TSS (INT 0ah) 631INVALID_TSS_SEL 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; segment not present (INT 0bh) 639SEG_NOT_PRESENT_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; stack fault (INT 0ch) 647STACK_FAULT_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; general protection (INT 0dh) 655GP_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; page fault (INT 0eh) 663PAGE_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; Intel reserved - do not use (INT 0fh) 671RSVD_INTR_SEL2 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; floating point error (INT 10h) 679FLT_POINT_ERR_SEL 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; alignment check (INT 11h) 687ALIGNMENT_CHECK_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 ; (10001110)type = 386 interrupt gate, present 692 dw 0 ; offset 31:16 693 694; machine check (INT 12h) 695MACHINE_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; SIMD floating-point exception (INT 13h) 703SIMD_EXCEPTION_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; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail 711 db (85 * 8) dup(0) 712 713; IRQ 0 (System timer) - (INT 68h) 714IRQ0_SEL equ $-IDT_BASE 715 dw 0 ; offset 15:0 716 dw SYS_CODE_SEL ; selector 15:0 717 db 0 ; 0 for interrupt gate 718 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 719 dw 0 ; offset 31:16 720 721; IRQ 1 (8042 Keyboard controller) - (INT 69h) 722IRQ1_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; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah) 730IRQ2_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; IRQ 3 (COM 2) - (INT 6bh) 738IRQ3_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 4 (COM 1) - (INT 6ch) 746IRQ4_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 5 (LPT 2) - (INT 6dh) 754IRQ5_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 6 (Floppy controller) - (INT 6eh) 762IRQ6_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 7 (LPT 1) - (INT 6fh) 770IRQ7_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 8 (RTC Alarm) - (INT 70h) 778IRQ8_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 9 - (INT 71h) 786IRQ9_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 10 - (INT 72h) 794IRQ10_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 11 - (INT 73h) 802IRQ11_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 12 (PS/2 mouse) - (INT 74h) 810IRQ12_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 13 (Floating point error) - (INT 75h) 818IRQ13_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 14 (Secondary IDE) - (INT 76h) 826IRQ14_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 15 (Primary IDE) - (INT 77h) 834IRQ15_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 841IDT_END: 842 843 align 02h 844 845MemoryMapSize dd 0 846MemoryMap dd 0,0,0,0,0,0,0,0 847 dd 0,0,0,0,0,0,0,0 848 dd 0,0,0,0,0,0,0,0 849 dd 0,0,0,0,0,0,0,0 850 dd 0,0,0,0,0,0,0,0 851 dd 0,0,0,0,0,0,0,0 852 dd 0,0,0,0,0,0,0,0 853 dd 0,0,0,0,0,0,0,0 854 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 877 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 878 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 879 880 org 0fe0h 881MyStack: 882 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh 883 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a 884 ; known low address (20f00) so it can be set up by PlMapIrqToVect in 885 ; 8259.c 886 887 int 8 888 iret 889 890 int 9 891 iret 892 893 int 10 894 iret 895 896 int 11 897 iret 898 899 int 12 900 iret 901 902 int 13 903 iret 904 905 int 14 906 iret 907 908 int 15 909 iret 910 911 912 org 0ffeh 913BlockSignature: 914 dw 0aa55h 915 916 end 917