User:Johnburger/Demo/Boot/IDT

From OSDev Wiki
Jump to navigation Jump to search

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