User:Johnburger/Demo/Exec/GDT
< User:Johnburger | Demo
Jump to navigation
Jump to search
The GDT's first entry is defined to be unused, to allow a NULL
Segment selector to always cause a GPF. That makes for handy storage for an allocator - and I re-used the logic for LDTs, even though they don't have their first entry unused (I just mark it as non-present - oh, and an LDT, which is not legal inside an LDT!)
This GDT definition has entries for:
- The Descriptor Table Allocator storage (as described above);
- The GDT Alias (another expectation of the Descriptor Table Allocator code);
- Global Data, for access by global Code such as Interrupt handlers;
- The VGA text screen;
- The global Interrupt handling Code;
- The Executive's LDT.
Demo/Exec/GDT.inc
;
; Exec/GDT.inc
;
; The GDT is the only Descriptor Table that can store certain system tables,
; like Local Descriptor Tables and TSSes. If you think about it, that's because
; at Task Switch time, the GDT is the only place those entries will be guaranteed
; to be, regardless of which Task is currently running.
; That logic also applies to Code Segments for interrupt handlers.
; And those Interrupt handlers may need access to global Data, and the Screen...
; Everything else can be stored in each Task's Local Descriptor Table.
;
; That means that the Executive has nothing: no Code to run, no Stacks to use,
; and no Data to reference. To solve this, we give the Executive its own LDT.
SEGMENT GDT VSTART=0 ALIGN=16
USE32
; This macro makes it easy to have a one-line invocation of GDT.Alloc
; The parameters are: GDT Base, GDT Limit
%macro GDT.Vars 2
%00 ISTRUC GDT.Alloc
AT GDT.Alloc.Free, DW 0
AT GDT.Alloc.Limit, DW %2
AT GDT.Alloc.Pseudo.Base, DD %1
IEND
%endmacro
GDT.Alias.Base EQU GDT.Base
GDT.Alias.Limit EQU (GDT.Size-1) >> 12 ; Let's use Granular limits
GDT.Alias.Type EQU Type.Mem(Data, DPL0, RW)
GDT.Alias.Gran EQU Gran.Mem(Gran, Small)
GDT.Data.Base EQU Data.Base
GDT.Data.Limit EQU Data.Size - 1
GDT.Data.Type EQU Type.Mem(Data, DPL0, RW)
GDT.Data.Gran EQU Gran.Mem(Byte, Big)
GDT.VGA.Base EQU Dev.VGA.Base
GDT.VGA.Limit EQU VGA.Rows * VGA.Cols * 2 - 1
GDT.VGA.Type EQU Type.Mem(Data, DPL3, RW) ; Let anyone access it!
GDT.VGA.Gran EQU Gran.Mem(Byte, Big)
GDT.Ints.Base EQU Ints.Base
GDT.Ints.Limit EQU Ints.Limit
GDT.Ints.Type EQU Type.Mem(Code, DPL0, RW) ; Uses lookup tables
GDT.Ints.Gran EQU Gran.Mem(Byte, Def32)
GDT.Exec.LDT.Base EQU Exec.LDT.Base
GDT.Exec.LDT.Limit EQU Exec.LDT.Limit
GDT.Exec.LDT.Type EQU Type.Sys(LDT, DPL0, 286)
GDT.Exec.LDT.Gran EQU Gran.Mem(Byte, Small)
GDT:
GDT.NULL GDT.Vars GDT.Base, GDT.Limit
GDT.Alias Desc.Mem GDT.Alias.Base, GDT.Alias.Limit, GDT.Alias.Type, GDT.Alias.Gran
GDT.Data Desc.Mem GDT.Data.Base, GDT.Data.Limit, GDT.Data.Type, GDT.Data.Gran
GDT.VGA Desc.Mem GDT.VGA.Base, GDT.VGA.Limit, GDT.VGA.Type, GDT.VGA.Gran
GDT.Ints Desc.Mem GDT.Ints.Base, GDT.Ints.Limit, GDT.Ints.Type, GDT.Ints.Gran
GDT.Exec.LDT Desc.Mem GDT.Exec.LDT.Base, GDT.Exec.LDT.Limit, GDT.Exec.LDT.Type, GDT.Exec.LDT.Gran
GDT.Size EQU 8192 * x86.Desc_size
%if (GDT.Alias-GDT) != DT.Alias
%error "Invalid GDT alias"
%endif