How to use the Local Descriptor Table
How to use the Local Descriptor Table
I am having doubts on how I should use the LDT and the LLDT instruction. I don't know if this is correct or not but here is my level of understanding about the subject. LLDT should be fed a segment selector into the GDT. The processor then looks into the GDT for the values that should be given to the LDTR. What Intel Manuals don't point out is what values should be put into the GDT and in what format? does the first WORD represent the length of the LDT or should it be a DWORD? any help is greatly appreciated.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
These are my LDT's properties:
Base Physical Address: 0x0010AE8C
Length in Bytes : 0x00000800
The function that I have coded puts the below values for the LDT's segment descriptor in the GDT:
DWORD#0 = 0xAE8C0800
DWORD#1 = 0x00409210
The segment selector that (for now) is chosen for the LDT in the GDT is 24. Then I try to do:
And right there, BAM! I get a GPF. Can someone tell me what I might be doing wrong?
The error that is reported by Bochs is:
Base Physical Address: 0x0010AE8C
Length in Bytes : 0x00000800
The function that I have coded puts the below values for the LDT's segment descriptor in the GDT:
DWORD#0 = 0xAE8C0800
DWORD#1 = 0x00409210
The segment selector that (for now) is chosen for the LDT in the GDT is 24. Then I try to do:
Code: Select all
LLDT [24]
The error that is reported by Bochs is:
Code: Select all
00002963012e[CPU0 ] fetch_raw_descriptor: GDT: index (ff57)1fea > limit (800)
Last edited by XCHG on Mon Apr 23, 2007 12:14 am, edited 1 time in total.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
I assume 24 is decimal, 0x18 in hex.
Try:
(Intel syntax)
I think you're trying to load it with the value of whatever's stored at memory address 0x00000018.
Regards,
John.
Try:
(Intel syntax)
Code: Select all
mov ax, 0x18
lldt ax
Regards,
John.
could you post the 'full' source because the error you explained got nothing to do widt LDT but GDT so me is confused.
i think you are right that you need the segment selector so it should be
lldt $24 or lldt $0x18
i think you are right that you need the segment selector so it should be
lldt $24 or lldt $0x18
Author of COBOS
Okay I changed the LLDT invocation to:
While the AX holds the segment selector of the LDT in the GDT and I am getting at least a more relevant error:
I'm sorry that the code is not yet fully commented. I normally don't comment codes that do not work.
What I am doing in this code is that I first zero all entries in the LDT, check its length for accuracy (divisible by 8 and etc). I then start searching in the GDT for the first empty slot. After having found it, I keep its index (0..x) in EDX. Then I put the LDT's segment descriptor in the found spot in the GDT. Retrieve EDX again and multiply it by 8 to get the actual segment selector of the LDT in the GDT.
For clarity, I should point this out. I have defined a LDTR like this:
So the first DWORD is the length and the second is the base address of the LDT.
Any help would be appreciated.
Code: Select all
LLDT AX
Code: Select all
00002963067e[CPU0 ] LLDT: doesn't point to an LDT descriptor!
What I am doing in this code is that I first zero all entries in the LDT, check its length for accuracy (divisible by 8 and etc). I then start searching in the GDT for the first empty slot. After having found it, I keep its index (0..x) in EDX. Then I put the LDT's segment descriptor in the found spot in the GDT. Retrieve EDX again and multiply it by 8 to get the actual segment selector of the LDT in the GDT.
Code: Select all
__InitializeLDT:
; Boolean __InitializeLDT (void* GDTR, void* LDTR); StdCall;
PUSH ECX
PUSH EDX
PUSH EDI
PUSH EBP
MOV EBP , ESP
XOR EAX , EAX
MOV EBP , ESP
MOV EDI , DWORD PTR [EBP + 0x18] ; LDTR
MOV ECX , DWORD PTR [EDI]
TEST ECX , ECX
JNZ .Continue1
JMP .EP
; The length should be divisible by 8
.Continue1
TEST ECX , 0x00000007
JZ .Continue2
JMP .EP
.Continue2:
PUSHFD
CLD
SHR ECX , 0x00000003
MOV EDI , DWORD PTR [EDI + 0x04]
REP STOSD
POPFD
; Now set the LDT Segment Descriptor in the Global Descriptor Table
MOV EDI , DWORD PTR [EBP + 0x14] ; GDTR
MOV ECX , DWORD PTR [EDI]
AND ECX , 0x0000FFFF
JZ .EP
TEST ECX , 0x00000007
JNZ .EP
SHR ECX , 0x00000003
MOV EDI , DWORD PTR [EDI + 0x02]
XOR EDX , EDX
.FindFirstEmptyGDTEntry:
MOV EAX , DWORD PTR [EDI]
OR EAX , DWORD PTR [EDI + 0x08]
JNZ .FindNextGDTEntry
; We have found the empty GDT entry
; Now read the LDT entry from LDTR and put it into the current Segment Descriptor into the GDT
PUSH EDX
MOV ECX , DWORD PTR [EBP + 0x18]
; EDI = The Pointer to the empty slot in the GDT
; ECX = The pointer to the LDTR parameter
; First set the base and the limit of the LDT 31:0 in the GDT, DWORD#0
MOV EAX , DWORD PTR [ECX] ; Limit
MOV EDX , DWORD PTR [ECX + 0x04] ; Base Address
AND EAX , 0x0000FFFF
SHL EDX , 0x00000010
OR EAX , EDX
MOV DWORD PTR [EDI] , EAX
; Now set the DWORD#1 of the GDT
; Base 31:24
MOV EAX , DWORD PTR [ECX + 0x04]
MOV EDX , EAX
SHR EDX , 0x00000010
AND EDX , 0x000000FF
AND EAX , 0xFF000000
OR EAX , EDX ; EAX = Base:31:24 and Base:23:16
; Segment Limit 19:16 in DWORD#1
MOV EDX , DWORD PTR [ECX]
AND EDX , 0x000F0000
OR EDX , 0x00409200
OR EAX , EDX
MOV DWORD PTR [EDI + 0x04], EAX
POP EDX
MOV EAX , EDX
SHL EAX , 0x00000003
LLDT AX
JMP .EP
.FindNextGDTEntry:
ADD EDI , 0x00000008
INC EDX
DEC ECX
JNZ .FindFirstEmptyGDTEntry
XOR EAX , EAX
.EP:
POP EBP
POP EDI
POP EDX
POP ECX
RET 0x08
Code: Select all
LDTR:
DD (LDT_END - LDT)
DD LDT
Any help would be appreciated.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
Holly Golly, I was setting the "S" bit of the second DWORD of the segment descriptor of the LDT in the GDT. So the LDT was becoming a Code/Data segment. I changed this:
To this:
And everything seems to be working fine. If that was the real problem then I must be a diungus because jnc100 actually pointed that out.
Code: Select all
; Segment Limit 19:16 in DWORD#1
MOV EDX , DWORD PTR [ECX]
AND EDX , 0x000F0000
OR EDX , 0x00409200
OR EAX , EDX
MOV DWORD PTR [EDI + 0x04], EAX
Code: Select all
; Segment Limit 19:16 in DWORD#1
MOV EDX , DWORD PTR [ECX]
AND EDX , 0x000F0000
OR EDX , 0x00408200
OR EAX , EDX
MOV DWORD PTR [EDI + 0x04], EAX
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.