User:Johnburger/Demo/User/LDT

From OSDev Wiki
Jump to navigation Jump to search

The LDT cannot be hard-coded at assembly time: there are lots of them, and they need to be built directly in memory by the Executive. But the User code needs to know the values of the different segment Selectors, so a common definition is useful.

You'll also see that the Stack sizes are defined here. Multiple stacks? Yes. A requirement of Protected Mode programming is that User mode programs cannot affect the system - and if a rogue program nearly runs out of stack, the system won't have enough room to perform its critical functions, like servicing interrupts.

So every time the system needs to do a Supervisor mode operation, it switches to its own stack, as defined in the current TSS. In fact, up to four Stacks can be defined: one for each Privilege Level Ring. This Demonstrator only uses Rings 0 and 3 though.

Finally, the source has an assemble-time sanity check in it, to confirm a system-wide inviolate: I need both the Global and all Local Descriptor Tables to have an Alias to themselves, and I need them all to be at the same Selector index: DT.Alias. That way I can access them in other system code easily.

Demo/User/LDT.inc

;
; User/LDT.inc
;

; This defines the LDT that the User program needs.

                SEGMENT         User.LDT  START=0  ALIGN=16  NOBITS

                USE32

User.Stack3.Size EQU            0010h           ; Doesn't need much at all!
User.Stack0.Size EQU            0200h           ; Needs a bit more...

User.LDT:
User.LDT.Alloc  RESB            LDT.Alloc_size
User.LDT.Alias  RESB            x86.Desc_size
User.LDT.Stack0 RESB            x86.Desc_size
User.LDT.Stack3 RESB            x86.Desc_size
User.LDT.Data   RESB            x86.Desc_size
User.LDT.Code   RESB            x86.Desc_size

%if (User.LDT.Alias-User.LDT) != DT.Alias
%error "Invalid User LDT alias"
%endif