Porting Duet module from EDKI to EDKII
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5076 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
921
DuetPkg/BootSector/start.asm
Normal file
921
DuetPkg/BootSector/start.asm
Normal file
@@ -0,0 +1,921 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* start.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
VolId db " " ; Volume Serial Number- 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT12 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
; ds = 1000, es = 2000 + x (size of first cluster >> 4)
|
||||
; cx = Start Cluster of EfiLdr
|
||||
; dx = Start Cluster of Efivar.bin
|
||||
|
||||
; Re use the BPB data stored in Boot Sector
|
||||
mov bp,07c00h
|
||||
|
||||
push cx
|
||||
; Read Efivar.bin
|
||||
; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
|
||||
mov ax,01900h
|
||||
mov es,ax
|
||||
test dx,dx
|
||||
jnz CheckVarStoreSize
|
||||
|
||||
mov al,1
|
||||
NoVarStore:
|
||||
push es
|
||||
; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
|
||||
mov byte ptr es:[4],al
|
||||
jmp SaveVolumeId
|
||||
|
||||
CheckVarStoreSize:
|
||||
mov di,dx
|
||||
cmp dword ptr ds:[di+2], 04000h
|
||||
mov al,2
|
||||
jne NoVarStore
|
||||
|
||||
LoadVarStore:
|
||||
mov al,0
|
||||
mov byte ptr es:[4],al
|
||||
mov cx,word ptr[di]
|
||||
; ES:DI = 1500:0
|
||||
xor di,di
|
||||
push es
|
||||
mov ax,01500h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
SaveVolumeId:
|
||||
pop es
|
||||
mov ax,word ptr [bp+VolId]
|
||||
mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
|
||||
mov ax,word ptr [bp+VolId+2]
|
||||
mov word ptr es:[2],ax
|
||||
|
||||
; Read Efildr
|
||||
pop cx
|
||||
; cx = Start Cluster of Efildr -> BS.com has filled already
|
||||
; ES:DI = 2000:0, first cluster will be read again
|
||||
xor di,di ; di = 0
|
||||
mov ax,02000h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
mov ax,cs
|
||||
mov word ptr cs:[JumpSegment],ax
|
||||
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0200h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadFile
|
||||
;
|
||||
; Arguments:
|
||||
; CX = Start Cluster of File
|
||||
; ES:DI = Buffer to store file content read from disk
|
||||
;
|
||||
; Return:
|
||||
; (ES << 4 + DI) = end of file content Buffer
|
||||
;
|
||||
; ****************************************************************************
|
||||
ReadFile:
|
||||
; si = NumberOfClusters
|
||||
; cx = ClusterNumber
|
||||
; dx = CachedFatSectorNumber
|
||||
; ds:0000 = CacheFatSectorBuffer
|
||||
; es:di = Buffer to load file
|
||||
; bx = NextClusterNumber
|
||||
pusha
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
push cx ; Push Start Cluster onto stack
|
||||
mov dx,0fffh ; CachedFatSectorNumber = 0xfff
|
||||
FatChainLoop:
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,0ff8h ; ax = ax & 0xff8
|
||||
cmp ax,0ff8h ; See if this is the last cluster
|
||||
je FoundLastCluster ; Jump if last cluster found
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
shl ax,1 ; ax = ClusterNumber * 2
|
||||
add ax,cx ; ax = ClusterNumber * 2 + ClusterNumber = ClusterNumber * 3
|
||||
shr ax,1 ; FatOffset = ClusterNumber*3 / 2
|
||||
push si ; Save si
|
||||
mov si,ax ; si = FatOffset
|
||||
shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
|
||||
and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
|
||||
cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
|
||||
je SkipFatRead
|
||||
mov bx,2
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
|
||||
pop es
|
||||
mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
|
||||
SkipFatRead:
|
||||
mov bx,word ptr [si] ; bx = NextClusterNumber
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,1 ; See if this is an odd cluster number
|
||||
je EvenFatEntry
|
||||
shr bx,4 ; NextClusterNumber = NextClusterNumber >> 4
|
||||
EvenFatEntry:
|
||||
and bx,0fffh ; Strip upper 4 bits of NextClusterNumber
|
||||
pop si ; Restore si
|
||||
dec bx ; bx = NextClusterNumber - 1
|
||||
cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
|
||||
jne ReadClusters
|
||||
inc bx ; bx = NextClusterNumber
|
||||
inc si ; NumberOfClusters++
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
jmp FatChainLoop
|
||||
ReadClusters:
|
||||
inc bx
|
||||
pop ax ; ax = StartCluster
|
||||
push bx ; StartCluster = NextClusterNumber
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ax ; save start sector
|
||||
mov ax,si ; ax = NumberOfClusters
|
||||
mul bx ; ax = NumberOfClusters * SectorsPerCluster
|
||||
mov bx,ax ; bx = Number of Sectors
|
||||
pop ax ; ax = Start Sector
|
||||
call ReadBlocks
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
jmp FatChainLoop
|
||||
FoundLastCluster:
|
||||
pop cx
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
|
||||
mov bx,word ptr [bp] ; bx = MaxSector
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push ax ; save ax
|
||||
mov ax,es ; ax = es
|
||||
shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
|
||||
and ax,07fh ; ax = Number of blocks into current seg
|
||||
add ax,bx ; ax = End Block number of transfer
|
||||
cmp ax,080h ; See if it crosses a 64K boundry
|
||||
jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
|
||||
sub ax,080h ; ax = Number of blocks past 64K boundry
|
||||
sub bx,ax ; Decrease transfer size by block overage
|
||||
NotCrossing64KBoundry:
|
||||
pop ax ; restore ax
|
||||
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
push cs
|
||||
pop ds
|
||||
lea si, [ErrorString]
|
||||
mov cx, 7
|
||||
jmp PrintStringAndHalt
|
||||
|
||||
PrintStringAndHalt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov di,160
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
ErrorString:
|
||||
db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
org 01feh
|
||||
dw 0aa55h
|
||||
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
|
||||
DELAY_PORT equ 0edh ; Port to use for 1uS delay
|
||||
KBD_CONTROL_PORT equ 060h ; 8042 control port
|
||||
KBD_STATUS_PORT equ 064h ; 8042 status port
|
||||
WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
|
||||
ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
|
||||
|
||||
org 200h
|
||||
jmp start
|
||||
Em64String:
|
||||
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
|
||||
|
||||
start:
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,MyStack
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[160],'a'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
mov ebx,0
|
||||
lea edi,MemoryMap
|
||||
MemMapLoop:
|
||||
mov eax,0e820h
|
||||
mov ecx,20
|
||||
mov edx,'SMAP'
|
||||
int 15h
|
||||
jc MemMapDone
|
||||
add edi,20
|
||||
cmp ebx,0
|
||||
je MemMapDone
|
||||
jmp MemMapLoop
|
||||
MemMapDone:
|
||||
lea eax,MemoryMap
|
||||
sub edi,eax ; Get the address of the memory map
|
||||
mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
|
||||
|
||||
xor ebx,ebx
|
||||
mov bx,cs ; BX=segment
|
||||
shl ebx,4 ; BX="linear" address of segment base
|
||||
lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
|
||||
|
||||
add ebx,01000h ; Source of EFI32
|
||||
mov dword ptr [JUMP+2],ebx
|
||||
add ebx,01000h
|
||||
mov esi,ebx ; Source of EFILDR32
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[162],'b'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; Enable A20 Gate
|
||||
;
|
||||
|
||||
mov ax,2401h ; Enable A20 Gate
|
||||
int 15h
|
||||
jnc A20GateEnabled ; Jump if it suceeded
|
||||
|
||||
;
|
||||
; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
|
||||
;
|
||||
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
|
||||
out KBD_STATUS_PORT,al ; Send command to the 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
mov al,ENABLE_A20_CMD ; gate address bit 20 on
|
||||
out KBD_CONTROL_PORT,al ; Send command to thre 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
|
||||
Delay25uS:
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
loop Delay25uS
|
||||
Timeout8042:
|
||||
|
||||
|
||||
A20GateEnabled:
|
||||
|
||||
;
|
||||
; DISABLE INTERRUPTS - Entering Protected Mode
|
||||
;
|
||||
|
||||
cli
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[164],'c'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
db 66h
|
||||
lgdt fword ptr [gdtr]
|
||||
db 66h
|
||||
lidt fword ptr [idtr]
|
||||
|
||||
mov eax,cr0
|
||||
or al,1
|
||||
mov cr0,eax
|
||||
|
||||
mov eax,0008h ; Flat data descriptor
|
||||
mov ebp,000400000h ; Destination of EFILDR32
|
||||
mov ebx,000070000h ; Length of copy
|
||||
|
||||
JUMP:
|
||||
; jmp far 0010:00020000
|
||||
db 066h
|
||||
db 0eah
|
||||
dd 000020000h
|
||||
dw 00010h
|
||||
|
||||
Empty8042InputBuffer:
|
||||
mov cx,0
|
||||
Empty8042Loop:
|
||||
out DELAY_PORT,ax ; Delay 1us
|
||||
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
|
||||
and al,02h ; Check the Input Buffer Full Flag
|
||||
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; interrupt descriptor table (IDT)
|
||||
;
|
||||
; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
|
||||
; mappings. This implementation only uses the system timer and all other
|
||||
; IRQs will remain masked. The descriptors for vectors 33+ are provided
|
||||
; for convenience.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
||||
db (85 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
MemoryMapSize dd 0
|
||||
MemoryMap dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
org 0fe0h
|
||||
MyStack:
|
||||
; below is the pieces of the IVT that is used to redirect INT 68h - 6fh
|
||||
; back to INT 08h - 0fh when in real mode... It is 'org'ed to a
|
||||
; known low address (20f00) so it can be set up by PlMapIrqToVect in
|
||||
; 8259.c
|
||||
|
||||
int 8
|
||||
iret
|
||||
|
||||
int 9
|
||||
iret
|
||||
|
||||
int 10
|
||||
iret
|
||||
|
||||
int 11
|
||||
iret
|
||||
|
||||
int 12
|
||||
iret
|
||||
|
||||
int 13
|
||||
iret
|
||||
|
||||
int 14
|
||||
iret
|
||||
|
||||
int 15
|
||||
iret
|
||||
|
||||
|
||||
org 0ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
Reference in New Issue
Block a user