User:Johnburger/Demo/Boot/IDT
The IDT to use in Protected Mode is defined in the source code, and loaded as part of the Protected Mode image. Note, though, that only the first 50 entries are defined, leaving 206 zero. That's a lot of wasted space! So rather than code the full IDT, I only code the first 50, and get the Real Mode code to relocate it to the desired position - and zero out the rest of the Table.
Memory Map
After this code, the Memory Map will look like this:
Address | Usage |
---|---|
0000_0000h
|
Interrupt Vector Table |
0000_0400h
|
BIOS Data Area |
0000_0500h
|
Available |
0000_0600h
|
Master Boot Record (MBR) *
|
0000_0800h
|
Moved IDT-to-be |
0000_1000h
|
Loaded Protected Mode code |
0000_2070h
|
Available |
0000_7C00h
|
SS:SP Stack Top
|
0000_7C00h
|
BIOS-loaded Boot Sector |
0000_7E00h
|
Available |
0009_F???h **
|
Extended BIOS Data Area |
000A_0000h
|
Adapter / ROM Area |
000B_8000h
|
Text Video Memory |
000F_0000h
|
BIOS ROM |
0010_0000h
|
High Memory ***
|
*
The MBR only exists here if the PC has booted from a Hard Drive.
**
An INT 12h will help identify this value.
***
Note that this memory is only accessible in Protected Mode - except for the first 64 kiB (less 16 bytes), which you can access with a Segment Register set to 0FFFFh
as long as the A20 Gate is off. By the way: DON'T DO THIS!
Demo/Boot/IDT.inc
;
; Boot/IDT.inc
;
; This system's IDT is not fully populated - only the first 48 of 256 entries
; are used. Originally, I generated the IDT at run-time, but that used up a LOT
; of the boot sector. Since the IDT is not important until Protected Mode,
; loading it as part of the image makes sense, and is effectively free of
; run-time overhead (we're loading everything else anyway).
;
; But the result was 1,664 bytes of zeroes stored in the disk image. So this is
; the compromise: the used part of the IDT is stored in the image, then this
; code moves the IDT to its final resting home, zeroing out the unused part.
Boot.IDT:
; First, turn off hardware interrupts
MOV AL,0FFh
OUT Dev.PIC.A.Mask,AL
OUT Dev.PIC.B.Mask,AL
MOV AX,IDT.Start >> 4 ; Start segment
MOV DS,AX
MOV AX,IDT.Base >> 4 ; Destination segment
MOV ES,AX
CLD ; Work forwards
MOV CX,(IDT.Limit + 1) / 4 ; Num DWORDs to move
XOR SI,SI ; From the beginning
XOR DI,DI ; Of both segments
REP MOVSD ; Do it
XOR EAX,EAX ; Now zero the rest of it
MOV CX,(IDT.Max - (IDT.Limit + 1)) / 4
REP STOSD ; Do it