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;* start16.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 "FAT16 " ; 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,0fff8h ; ax = ax & 0xfff8 148 cmp ax,0fff8h ; 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 ; FatOffset = ClusterNumber * 2 152 push si ; Save si 153 mov si,ax ; si = FatOffset 154 shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT 155 add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET) 156 and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK 157 cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber 158 je SkipFatRead 159 mov bx,2 160 push es 161 push ds 162 pop es 163 call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI 164 pop es 165 mov dx,ax ; CachedFatSectorNumber = FatSectorNumber 166SkipFatRead: 167 mov bx,word ptr [si] ; bx = NextClusterNumber 168 mov ax,cx ; ax = ClusterNumber 169 pop si ; Restore si 170 dec bx ; bx = NextClusterNumber - 1 171 cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber 172 jne ReadClusters 173 inc bx ; bx = NextClusterNumber 174 inc si ; NumberOfClusters++ 175 mov cx,bx ; ClusterNumber = NextClusterNumber 176 jmp FatChainLoop 177ReadClusters: 178 inc bx 179 pop ax ; ax = StartCluster 180 push bx ; StartCluster = NextClusterNumber 181 mov cx,bx ; ClusterNumber = NextClusterNumber 182 sub ax,2 ; ax = StartCluster - 2 183 xor bh,bh 184 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster 185 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster 186 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster 187 push ax ; save start sector 188 mov ax,si ; ax = NumberOfClusters 189 mul bx ; ax = NumberOfClusters * SectorsPerCluster 190 mov bx,ax ; bx = Number of Sectors 191 pop ax ; ax = Start Sector 192 call ReadBlocks 193 mov si,1 ; NumberOfClusters = 1 194 jmp FatChainLoop 195FoundLastCluster: 196 pop cx 197 popa 198 ret 199 200 201; **************************************************************************** 202; ReadBlocks - Reads a set of blocks from a block device 203; 204; AX = Start LBA 205; BX = Number of Blocks to Read 206; ES:DI = Buffer to store sectors read from disk 207; **************************************************************************** 208 209; cx = Blocks 210; bx = NumberOfBlocks 211; si = StartLBA 212 213ReadBlocks: 214 pusha 215 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA 216 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA 217 mov esi,eax ; esi = Start LBA 218 mov cx,bx ; cx = Number of blocks to read 219ReadCylinderLoop: 220 mov bp,07bfch ; bp = 0x7bfc 221 mov eax,esi ; eax = Start LBA 222 xor edx,edx ; edx = 0 223 movzx ebx,word ptr [bp] ; bx = MaxSector 224 div ebx ; ax = StartLBA / MaxSector 225 inc dx ; dx = (StartLBA % MaxSector) + 1 226 227 mov bx,word ptr [bp] ; bx = MaxSector 228 sub bx,dx ; bx = MaxSector - Sector 229 inc bx ; bx = MaxSector - Sector + 1 230 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1) 231 jg LimitTransfer 232 mov bx,cx ; bx = Blocks 233LimitTransfer: 234 push ax ; save ax 235 mov ax,es ; ax = es 236 shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system 237 and ax,07fh ; ax = Number of blocks into current seg 238 add ax,bx ; ax = End Block number of transfer 239 cmp ax,080h ; See if it crosses a 64K boundry 240 jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry 241 sub ax,080h ; ax = Number of blocks past 64K boundry 242 sub bx,ax ; Decrease transfer size by block overage 243NotCrossing64KBoundry: 244 pop ax ; restore ax 245 246 push cx 247 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector 248 xor dx,dx ; dx = 0 249 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder 250 ; dx = ax % (MaxHead + 1) = Head 251 252 push bx ; Save number of blocks to transfer 253 mov dh,dl ; dh = Head 254 mov bp,07c00h ; bp = 0x7c00 255 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number 256 mov ch,al ; ch = Cylinder 257 mov al,bl ; al = Blocks 258 mov ah,2 ; ah = Function 2 259 mov bx,di ; es:bx = Buffer address 260 int 013h 261 jc DiskError 262 pop bx 263 pop cx 264 movzx ebx,bx 265 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks 266 sub cx,bx ; Blocks = Blocks - NumberOfBlocks 267 mov ax,es 268 shl bx,(BLOCK_SHIFT-4) 269 add ax,bx 270 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE 271 cmp cx,0 272 jne ReadCylinderLoop 273 popa 274 ret 275 276DiskError: 277 push cs 278 pop ds 279 lea si, [ErrorString] 280 mov cx, 7 281 jmp PrintStringAndHalt 282 283PrintStringAndHalt: 284 mov ax,0b800h 285 mov es,ax 286 mov di,160 287 rep movsw 288Halt: 289 jmp Halt 290 291ErrorString: 292 db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch 293 294 org 01fah 295LBAOffsetForBootSector: 296 dd 0h 297 298 org 01feh 299 dw 0aa55h 300 301;****************************************************************************** 302;****************************************************************************** 303;****************************************************************************** 304 305DELAY_PORT equ 0edh ; Port to use for 1uS delay 306KBD_CONTROL_PORT equ 060h ; 8042 control port 307KBD_STATUS_PORT equ 064h ; 8042 status port 308WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port 309ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20 310 311 org 200h 312 jmp start 313Em64String: 314 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 315 316start: 317 mov ax,cs 318 mov ds,ax 319 mov es,ax 320 mov ss,ax 321 mov sp,MyStack 322 323; mov ax,0b800h 324; mov es,ax 325; mov byte ptr es:[160],'a' 326; mov ax,cs 327; mov es,ax 328 329 mov ebx,0 330 lea edi,MemoryMap 331MemMapLoop: 332 mov eax,0e820h 333 mov ecx,20 334 mov edx,'SMAP' 335 int 15h 336 jc MemMapDone 337 add edi,20 338 cmp ebx,0 339 je MemMapDone 340 jmp MemMapLoop 341MemMapDone: 342 lea eax,MemoryMap 343 sub edi,eax ; Get the address of the memory map 344 mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map 345 346 xor ebx,ebx 347 mov bx,cs ; BX=segment 348 shl ebx,4 ; BX="linear" address of segment base 349 lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt 350 mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr 351 lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt 352 mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr 353 lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map 354 355 add ebx,01000h ; Source of EFI32 356 mov dword ptr [JUMP+2],ebx 357 add ebx,01000h 358 mov esi,ebx ; Source of EFILDR32 359 360; mov ax,0b800h 361; mov es,ax 362; mov byte ptr es:[162],'b' 363; mov ax,cs 364; mov es,ax 365 366; 367; Enable A20 Gate 368; 369 370 mov ax,2401h ; Enable A20 Gate 371 int 15h 372 jnc A20GateEnabled ; Jump if it suceeded 373 374; 375; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually. 376; 377 378 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 379 jnz Timeout8042 ; Jump if the 8042 timed out 380 out DELAY_PORT,ax ; Delay 1 uS 381 mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port 382 out KBD_STATUS_PORT,al ; Send command to the 8042 383 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 384 jnz Timeout8042 ; Jump if the 8042 timed out 385 mov al,ENABLE_A20_CMD ; gate address bit 20 on 386 out KBD_CONTROL_PORT,al ; Send command to thre 8042 387 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller 388 mov cx,25 ; Delay 25 uS for the command to complete on the 8042 389Delay25uS: 390 out DELAY_PORT,ax ; Delay 1 uS 391 loop Delay25uS 392Timeout8042: 393 394 395A20GateEnabled: 396 mov bx,0008h ; Flat data descriptor 397; 398; DISABLE INTERRUPTS - Entering Protected Mode 399; 400 401 cli 402 403; mov ax,0b800h 404; mov es,ax 405; mov byte ptr es:[164],'c' 406; mov ax,cs 407; mov es,ax 408 409 db 66h 410 lgdt fword ptr [gdtr] 411 db 66h 412 lidt fword ptr [idtr] 413 414 mov eax,cr0 415 or al,1 416 mov cr0,eax 417JUMP: 418; jmp far 0010:00020000 419 db 066h 420 db 0eah 421 dd 000020000h 422 dw 00010h 423 424Empty8042InputBuffer: 425 mov cx,0 426Empty8042Loop: 427 out DELAY_PORT,ax ; Delay 1us 428 in al,KBD_STATUS_PORT ; Read the 8042 Status Port 429 and al,02h ; Check the Input Buffer Full Flag 430 loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS 431 ret 432 433;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 434; data 435;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 436 437 align 02h 438 439gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit 440 dd 0 ; (GDT base gets set above) 441;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 442; global descriptor table (GDT) 443;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 444 445 align 02h 446 447public GDT_BASE 448GDT_BASE: 449; null descriptor 450NULL_SEL equ $-GDT_BASE 451 dw 0 ; limit 15:0 452 dw 0 ; base 15:0 453 db 0 ; base 23:16 454 db 0 ; type 455 db 0 ; limit 19:16, flags 456 db 0 ; base 31:24 457 458; linear data segment descriptor 459LINEAR_SEL equ $-GDT_BASE 460 dw 0FFFFh ; limit 0xFFFFF 461 dw 0 ; base 0 462 db 0 463 db 092h ; present, ring 0, data, expand-up, writable 464 db 0CFh ; page-granular, 32-bit 465 db 0 466 467; linear code segment descriptor 468LINEAR_CODE_SEL equ $-GDT_BASE 469 dw 0FFFFh ; limit 0xFFFFF 470 dw 0 ; base 0 471 db 0 472 db 09Ah ; present, ring 0, data, expand-up, writable 473 db 0CFh ; page-granular, 32-bit 474 db 0 475 476; system data segment descriptor 477SYS_DATA_SEL equ $-GDT_BASE 478 dw 0FFFFh ; limit 0xFFFFF 479 dw 0 ; base 0 480 db 0 481 db 092h ; present, ring 0, data, expand-up, writable 482 db 0CFh ; page-granular, 32-bit 483 db 0 484 485; system code segment descriptor 486SYS_CODE_SEL equ $-GDT_BASE 487 dw 0FFFFh ; limit 0xFFFFF 488 dw 0 ; base 0 489 db 0 490 db 09Ah ; present, ring 0, data, expand-up, writable 491 db 0CFh ; page-granular, 32-bit 492 db 0 493 494; spare segment descriptor 495SPARE3_SEL equ $-GDT_BASE 496 dw 0 ; limit 0xFFFFF 497 dw 0 ; base 0 498 db 0 499 db 0 ; present, ring 0, data, expand-up, writable 500 db 0 ; page-granular, 32-bit 501 db 0 502 503; spare segment descriptor 504SPARE4_SEL equ $-GDT_BASE 505 dw 0 ; limit 0xFFFFF 506 dw 0 ; base 0 507 db 0 508 db 0 ; present, ring 0, data, expand-up, writable 509 db 0 ; page-granular, 32-bit 510 db 0 511 512; spare segment descriptor 513SPARE5_SEL equ $-GDT_BASE 514 dw 0 ; limit 0xFFFFF 515 dw 0 ; base 0 516 db 0 517 db 0 ; present, ring 0, data, expand-up, writable 518 db 0 ; page-granular, 32-bit 519 db 0 520 521GDT_END: 522 523 align 02h 524 525 526 527idtr dw IDT_END - IDT_BASE - 1 ; IDT limit 528 dd 0 ; (IDT base gets set above) 529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 530; interrupt descriptor table (IDT) 531; 532; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ 533; mappings. This implementation only uses the system timer and all other 534; IRQs will remain masked. The descriptors for vectors 33+ are provided 535; for convenience. 536;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 537 538;idt_tag db "IDT",0 539 align 02h 540 541public IDT_BASE 542IDT_BASE: 543; divide by zero (INT 0) 544DIV_ZERO_SEL equ $-IDT_BASE 545 dw 0 ; offset 15:0 546 dw SYS_CODE_SEL ; selector 15:0 547 db 0 ; 0 for interrupt gate 548 db 0eh OR 80h ; type = 386 interrupt gate, present 549 dw 0 ; offset 31:16 550 551; debug exception (INT 1) 552DEBUG_EXCEPT_SEL equ $-IDT_BASE 553 dw 0 ; offset 15:0 554 dw SYS_CODE_SEL ; selector 15:0 555 db 0 ; 0 for interrupt gate 556 db 0eh OR 80h ; type = 386 interrupt gate, present 557 dw 0 ; offset 31:16 558 559; NMI (INT 2) 560NMI_SEL equ $-IDT_BASE 561 dw 0 ; offset 15:0 562 dw SYS_CODE_SEL ; selector 15:0 563 db 0 ; 0 for interrupt gate 564 db 0eh OR 80h ; type = 386 interrupt gate, present 565 dw 0 ; offset 31:16 566 567; soft breakpoint (INT 3) 568BREAKPOINT_SEL equ $-IDT_BASE 569 dw 0 ; offset 15:0 570 dw SYS_CODE_SEL ; selector 15:0 571 db 0 ; 0 for interrupt gate 572 db 0eh OR 80h ; type = 386 interrupt gate, present 573 dw 0 ; offset 31:16 574 575; overflow (INT 4) 576OVERFLOW_SEL equ $-IDT_BASE 577 dw 0 ; offset 15:0 578 dw SYS_CODE_SEL ; selector 15:0 579 db 0 ; 0 for interrupt gate 580 db 0eh OR 80h ; type = 386 interrupt gate, present 581 dw 0 ; offset 31:16 582 583; bounds check (INT 5) 584BOUNDS_CHECK_SEL equ $-IDT_BASE 585 dw 0 ; offset 15:0 586 dw SYS_CODE_SEL ; selector 15:0 587 db 0 ; 0 for interrupt gate 588 db 0eh OR 80h ; type = 386 interrupt gate, present 589 dw 0 ; offset 31:16 590 591; invalid opcode (INT 6) 592INVALID_OPCODE_SEL equ $-IDT_BASE 593 dw 0 ; offset 15:0 594 dw SYS_CODE_SEL ; selector 15:0 595 db 0 ; 0 for interrupt gate 596 db 0eh OR 80h ; type = 386 interrupt gate, present 597 dw 0 ; offset 31:16 598 599; device not available (INT 7) 600DEV_NOT_AVAIL_SEL equ $-IDT_BASE 601 dw 0 ; offset 15:0 602 dw SYS_CODE_SEL ; selector 15:0 603 db 0 ; 0 for interrupt gate 604 db 0eh OR 80h ; type = 386 interrupt gate, present 605 dw 0 ; offset 31:16 606 607; double fault (INT 8) 608DOUBLE_FAULT_SEL equ $-IDT_BASE 609 dw 0 ; offset 15:0 610 dw SYS_CODE_SEL ; selector 15:0 611 db 0 ; 0 for interrupt gate 612 db 0eh OR 80h ; type = 386 interrupt gate, present 613 dw 0 ; offset 31:16 614 615; Coprocessor segment overrun - reserved (INT 9) 616RSVD_INTR_SEL1 equ $-IDT_BASE 617 dw 0 ; offset 15:0 618 dw SYS_CODE_SEL ; selector 15:0 619 db 0 ; 0 for interrupt gate 620 db 0eh OR 80h ; type = 386 interrupt gate, present 621 dw 0 ; offset 31:16 622 623; invalid TSS (INT 0ah) 624INVALID_TSS_SEL equ $-IDT_BASE 625 dw 0 ; offset 15:0 626 dw SYS_CODE_SEL ; selector 15:0 627 db 0 ; 0 for interrupt gate 628 db 0eh OR 80h ; type = 386 interrupt gate, present 629 dw 0 ; offset 31:16 630 631; segment not present (INT 0bh) 632SEG_NOT_PRESENT_SEL equ $-IDT_BASE 633 dw 0 ; offset 15:0 634 dw SYS_CODE_SEL ; selector 15:0 635 db 0 ; 0 for interrupt gate 636 db 0eh OR 80h ; type = 386 interrupt gate, present 637 dw 0 ; offset 31:16 638 639; stack fault (INT 0ch) 640STACK_FAULT_SEL equ $-IDT_BASE 641 dw 0 ; offset 15:0 642 dw SYS_CODE_SEL ; selector 15:0 643 db 0 ; 0 for interrupt gate 644 db 0eh OR 80h ; type = 386 interrupt gate, present 645 dw 0 ; offset 31:16 646 647; general protection (INT 0dh) 648GP_FAULT_SEL equ $-IDT_BASE 649 dw 0 ; offset 15:0 650 dw SYS_CODE_SEL ; selector 15:0 651 db 0 ; 0 for interrupt gate 652 db 0eh OR 80h ; type = 386 interrupt gate, present 653 dw 0 ; offset 31:16 654 655; page fault (INT 0eh) 656PAGE_FAULT_SEL equ $-IDT_BASE 657 dw 0 ; offset 15:0 658 dw SYS_CODE_SEL ; selector 15:0 659 db 0 ; 0 for interrupt gate 660 db 0eh OR 80h ; type = 386 interrupt gate, present 661 dw 0 ; offset 31:16 662 663; Intel reserved - do not use (INT 0fh) 664RSVD_INTR_SEL2 equ $-IDT_BASE 665 dw 0 ; offset 15:0 666 dw SYS_CODE_SEL ; selector 15:0 667 db 0 ; 0 for interrupt gate 668 db 0eh OR 80h ; type = 386 interrupt gate, present 669 dw 0 ; offset 31:16 670 671; floating point error (INT 10h) 672FLT_POINT_ERR_SEL equ $-IDT_BASE 673 dw 0 ; offset 15:0 674 dw SYS_CODE_SEL ; selector 15:0 675 db 0 ; 0 for interrupt gate 676 db 0eh OR 80h ; type = 386 interrupt gate, present 677 dw 0 ; offset 31:16 678 679; alignment check (INT 11h) 680ALIGNMENT_CHECK_SEL equ $-IDT_BASE 681 dw 0 ; offset 15:0 682 dw SYS_CODE_SEL ; selector 15:0 683 db 0 ; 0 for interrupt gate 684 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 685 dw 0 ; offset 31:16 686 687; machine check (INT 12h) 688MACHINE_CHECK_SEL equ $-IDT_BASE 689 dw 0 ; offset 15:0 690 dw SYS_CODE_SEL ; selector 15:0 691 db 0 ; 0 for interrupt gate 692 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 693 dw 0 ; offset 31:16 694 695; SIMD floating-point exception (INT 13h) 696SIMD_EXCEPTION_SEL equ $-IDT_BASE 697 dw 0 ; offset 15:0 698 dw SYS_CODE_SEL ; selector 15:0 699 db 0 ; 0 for interrupt gate 700 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 701 dw 0 ; offset 31:16 702 703; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail 704 db (85 * 8) dup(0) 705 706; IRQ 0 (System timer) - (INT 68h) 707IRQ0_SEL equ $-IDT_BASE 708 dw 0 ; offset 15:0 709 dw SYS_CODE_SEL ; selector 15:0 710 db 0 ; 0 for interrupt gate 711 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 712 dw 0 ; offset 31:16 713 714; IRQ 1 (8042 Keyboard controller) - (INT 69h) 715IRQ1_SEL equ $-IDT_BASE 716 dw 0 ; offset 15:0 717 dw SYS_CODE_SEL ; selector 15:0 718 db 0 ; 0 for interrupt gate 719 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 720 dw 0 ; offset 31:16 721 722; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah) 723IRQ2_SEL equ $-IDT_BASE 724 dw 0 ; offset 15:0 725 dw SYS_CODE_SEL ; selector 15:0 726 db 0 ; 0 for interrupt gate 727 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 728 dw 0 ; offset 31:16 729 730; IRQ 3 (COM 2) - (INT 6bh) 731IRQ3_SEL equ $-IDT_BASE 732 dw 0 ; offset 15:0 733 dw SYS_CODE_SEL ; selector 15:0 734 db 0 ; 0 for interrupt gate 735 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 736 dw 0 ; offset 31:16 737 738; IRQ 4 (COM 1) - (INT 6ch) 739IRQ4_SEL equ $-IDT_BASE 740 dw 0 ; offset 15:0 741 dw SYS_CODE_SEL ; selector 15:0 742 db 0 ; 0 for interrupt gate 743 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 744 dw 0 ; offset 31:16 745 746; IRQ 5 (LPT 2) - (INT 6dh) 747IRQ5_SEL equ $-IDT_BASE 748 dw 0 ; offset 15:0 749 dw SYS_CODE_SEL ; selector 15:0 750 db 0 ; 0 for interrupt gate 751 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 752 dw 0 ; offset 31:16 753 754; IRQ 6 (Floppy controller) - (INT 6eh) 755IRQ6_SEL equ $-IDT_BASE 756 dw 0 ; offset 15:0 757 dw SYS_CODE_SEL ; selector 15:0 758 db 0 ; 0 for interrupt gate 759 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 760 dw 0 ; offset 31:16 761 762; IRQ 7 (LPT 1) - (INT 6fh) 763IRQ7_SEL equ $-IDT_BASE 764 dw 0 ; offset 15:0 765 dw SYS_CODE_SEL ; selector 15:0 766 db 0 ; 0 for interrupt gate 767 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 768 dw 0 ; offset 31:16 769 770; IRQ 8 (RTC Alarm) - (INT 70h) 771IRQ8_SEL equ $-IDT_BASE 772 dw 0 ; offset 15:0 773 dw SYS_CODE_SEL ; selector 15:0 774 db 0 ; 0 for interrupt gate 775 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 776 dw 0 ; offset 31:16 777 778; IRQ 9 - (INT 71h) 779IRQ9_SEL equ $-IDT_BASE 780 dw 0 ; offset 15:0 781 dw SYS_CODE_SEL ; selector 15:0 782 db 0 ; 0 for interrupt gate 783 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 784 dw 0 ; offset 31:16 785 786; IRQ 10 - (INT 72h) 787IRQ10_SEL equ $-IDT_BASE 788 dw 0 ; offset 15:0 789 dw SYS_CODE_SEL ; selector 15:0 790 db 0 ; 0 for interrupt gate 791 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 792 dw 0 ; offset 31:16 793 794; IRQ 11 - (INT 73h) 795IRQ11_SEL equ $-IDT_BASE 796 dw 0 ; offset 15:0 797 dw SYS_CODE_SEL ; selector 15:0 798 db 0 ; 0 for interrupt gate 799 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 800 dw 0 ; offset 31:16 801 802; IRQ 12 (PS/2 mouse) - (INT 74h) 803IRQ12_SEL equ $-IDT_BASE 804 dw 0 ; offset 15:0 805 dw SYS_CODE_SEL ; selector 15:0 806 db 0 ; 0 for interrupt gate 807 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 808 dw 0 ; offset 31:16 809 810; IRQ 13 (Floating point error) - (INT 75h) 811IRQ13_SEL equ $-IDT_BASE 812 dw 0 ; offset 15:0 813 dw SYS_CODE_SEL ; selector 15:0 814 db 0 ; 0 for interrupt gate 815 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 816 dw 0 ; offset 31:16 817 818; IRQ 14 (Secondary IDE) - (INT 76h) 819IRQ14_SEL equ $-IDT_BASE 820 dw 0 ; offset 15:0 821 dw SYS_CODE_SEL ; selector 15:0 822 db 0 ; 0 for interrupt gate 823 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 824 dw 0 ; offset 31:16 825 826; IRQ 15 (Primary IDE) - (INT 77h) 827IRQ15_SEL equ $-IDT_BASE 828 dw 0 ; offset 15:0 829 dw SYS_CODE_SEL ; selector 15:0 830 db 0 ; 0 for interrupt gate 831 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present 832 dw 0 ; offset 31:16 833 834IDT_END: 835 836 align 02h 837 838MemoryMapSize dd 0 839MemoryMap dd 0,0,0,0,0,0,0,0 840 dd 0,0,0,0,0,0,0,0 841 dd 0,0,0,0,0,0,0,0 842 dd 0,0,0,0,0,0,0,0 843 dd 0,0,0,0,0,0,0,0 844 dd 0,0,0,0,0,0,0,0 845 dd 0,0,0,0,0,0,0,0 846 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 870 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 871 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 872 873 org 0fe0h 874MyStack: 875 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh 876 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a 877 ; known low address (20f00) so it can be set up by PlMapIrqToVect in 878 ; 8259.c 879 880 int 8 881 iret 882 883 int 9 884 iret 885 886 int 10 887 iret 888 889 int 11 890 iret 891 892 int 12 893 iret 894 895 int 13 896 iret 897 898 int 14 899 iret 900 901 int 15 902 iret 903 904 905 org 0ffeh 906BlockSignature: 907 dw 0aa55h 908 909 end 910