Call gates
Call gates
Hello,
I'm very confused about call gates. I read somewhere (in 'Intel - System Programming', I think) that call gates are divided into trap gates and interrupt gates. Since call gates are found in the GDT and the two others in the IDT and that GDT has nothing to do with IDT, then, how can this be possible?
Besides, I didn't find any helpful description of a call gate. They can be used to call procedures (like the interrupts), right? How can I modify a normal GDT segment so it can become a call gate?
thanks for any help.
I'm very confused about call gates. I read somewhere (in 'Intel - System Programming', I think) that call gates are divided into trap gates and interrupt gates. Since call gates are found in the GDT and the two others in the IDT and that GDT has nothing to do with IDT, then, how can this be possible?
Besides, I didn't find any helpful description of a call gate. They can be used to call procedures (like the interrupts), right? How can I modify a normal GDT segment so it can become a call gate?
thanks for any help.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Call gates
you do not modify a segment to become a gate: you define a gate that makes a user enter a segment.
You may think of gates as "redirectors". when one calls a gate, it actually get redirected towards what the gate defines.
Since gates provide all the information required to define an entry point, Intel designers found it smart to call the 'interrupt table' descriptors 'gates' aswell. Some gates make little sense out of the IDT (like the Interrupt gate, which is simply a trap that will clear the IF bit when entered and restore it when left, iirc)
Other kind of gates (notably the Task gate) may exist in both GDT, LDT and IDT.
You may think of gates as "redirectors". when one calls a gate, it actually get redirected towards what the gate defines.
Since gates provide all the information required to define an entry point, Intel designers found it smart to call the 'interrupt table' descriptors 'gates' aswell. Some gates make little sense out of the IDT (like the Interrupt gate, which is simply a trap that will clear the IF bit when entered and restore it when left, iirc)
Other kind of gates (notably the Task gate) may exist in both GDT, LDT and IDT.
Re:Call gates
Hello,
is there anything wrong with this call gate?
How do I call it? 'call 28h:0'?
is there anything wrong with this call gate?
Code: Select all
GDT:
;null segment
;code segment
;data segment
;video segment
CallGate01:
dw cg1 ;offset
dw 08h ;selector
db 0 ;
db 10001100b ;present (1), ring0 (00), type (01100)
dw 0 ;offset
GDTEnd:
cg1: ;call gate handler (does nothing)
iret
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Call gates
"call far 28h:0" could be preferred depending on your assembler. Note that a call gate does not return with "iret" but instead with "retf"
Re:Call gates
Hi,
Cheers,
Brendan
If the offset "cg1" is not within the first 64 Kb of memory it will be truncated (your assembler may/may not give a warning/error). If the call gate is to be used by CPL=3 code (a good assumption IMHO) then you'll want DPL=3. Also the code called by the call gate should use "RETF" to return rather than "IRETD".ManOfSteel wrote:Code: Select all
GDT: ;null segment ;code segment ;data segment ;video segment CallGate01: dw cg1 ;offset dw 08h ;selector db 0 ; db 10001100b ;present (1), ring0 (00), type (01100) dw 0 ;offset GDTEnd: cg1: ;call gate handler (does nothing) iret
Code: Select all
GDT:
;null segment 0x0000
;code segment 0x0008
;data segment 0x0010
;video segment 0x0018
CallGate01: ; 0x0020
dw (cg1 & 0xFFFF) ;offset low word
dw 08h ;selector
db 0 ;stack parameters to copy
db 11101100b ;present (1), DPL (03), type (01100)
dw (cg1 >> 16) ;offset high word
GDTEnd:
cg1: ;call gate handler (does nothing)
retf
Yes, well almost - "call 20h:0"How do I call it? 'call 28h:0'?
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Call gates
Hello and thanks for your replies, but after a lot of tries, my call gate is still not working. Bochs crashes (illegal opertion) before running any piece of code.
I used Bochs 1.4.1 and 2.1 and it is not working better with any one.
The illegal operation (with Bochs 1.4.1 only):
Bochs 1.4.1 output:
I used Bochs 1.4.1 and 2.1 and it is not working better with any one.
The illegal operation (with Bochs 1.4.1 only):
Code: Select all
BOCHS caused an invalid page fault in module BOCHS.EXE at 0187:0043d132.
Registers:
EAX=00bafd20 CS=0187 EIP=0043d132 EFLGS=00010246
EBX=00aa0000 SS=018f ESP=00bafc94 EBP=00bafcf8
ECX=549d01e5 DS=018f ESI=81766e60 FS=4ee7
EDX=00000000 ES=018f EDI=00000000 GS=0000
Bytes at CS:EIP:
8a 11 89 55 e8 8b 45 08 83 c0 01 89 45 08 8b 4d
Stack dump:
00bafca0 0046b739 00000020 00bafcb0 0046b20a 004adc60 00000000 00bafcc8 00401986 004adc60 00000002 00cd07f0 00000065 00bafce8 00401da3 00000019
Code: Select all
00000000000i[MEM0 ] 8.00MB
00000000000i[MEM0 ] rom at 0xf0000/65536 ('../BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/32769 ('../VGABIOS-elpin-2.40')
00000000000i[CMOS ] Setting initial clock to: Thu May 13 09:53:15 2004
00000000000i[FDD ] fd0: '1.44' ro=0, h=2,t=80,spt=18
00000000000i[SB16 ] midi=0, wave=0, log=0, dmatimer=0
00000000000i[VGA ] interval=30000
00000000000i[VGA ] VBE Bochs Display Extension Enabled
00000000000i[KBD ] will paste characters every 1000 keyboard ticks
00000004012i[BIOS ] rombios.c,v 1.42.2.1 2002/05/15 13:41:03 cbothamy Exp $
00000006521i[VGA ] char map select: #1=0 / #2=0 (unused)
00000156932e[HD ] device set to 0 which does not exist
00000158492e[HD ] device set to 1 which does not exist
00000160052e[HD ] device set to 0 which does not exist
00000162496e[HD ] device set to 1 which does not exist
00000163456e[HD ] device set to 0 which does not exist
00000164493e[HD ] device set to 1 which does not exist
00000165092e[HD ] device set to 0 which does not exist
00000165696e[HD ] device set to 0 which does not exist
00000166896e[HD ] device set to 1 which does not exist
00000168115e[HD ] device set to 1 which does not exist
00000168717e[HD ] device set to 0 which does not exist
00000171200e[HD ] device set to 1 which does not exist
00000172160e[HD ] device set to 0 which does not exist
00000173197e[HD ] device set to 1 which does not exist
00000173796e[HD ] device set to 0 which does not exist
00000176592e[HD ] device set to 1 which does not exist
00000177552e[HD ] device set to 0 which does not exist
00000178589e[HD ] device set to 1 which does not exist
00000179188e[HD ] device set to 0 which does not exist
00000216075i[FDD ] partial read() on floppy image returns 328/512
00000217085e[CPU ] prefetch: running in bogus memory
Re:Call gates
My GDT, which contains the call gate, is directly followed by the call gate handler:
I jump to the call gate like this:
Brendan, I didn't really understand what you meant by these:
PS: sorry for pasting too much information here.
Code: Select all
GDTDESCR:
GDTLimit dw GDTEnd-GDT-1
GDTBase dd GDT
GDT:
GDTNull:
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
GDTCode:
db 0ffh
db 0ffh
db 00h
db 00h
db 00h
db 10011011b
db 11011111b
db 00h
GDTData:
db 0ffh
db 0ffh
db 00h
db 00h
db 00h
db 10010011b
db 11011111b
db 00h
GDTVideo:
db 9fh
db 0fh
db 00h
db 80h
db 0bh
db 92h
db 00h
db 00h
CallGate01:
dw cg1
dw 08h
db 0
db 10001100b
dw 0
GDTEnd:
cg1:
retf
Code: Select all
call 20h:0
Code: Select all
dw (cg1 & 0xFFFF) ;offset low word
...
dw (cg1 >> 16) ;offset high word
In fact, I'm using it with ring zero code. I will not use it only to jump to different-DPL-code but as interrupts (yeah, I know, I can do it with interrupt gates).If the call gate is to be used by CPL=3 code (a good assumption IMHO) then you'll want DPL=3.
PS: sorry for pasting too much information here.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Call gates
What brendan mean is that a 'dw' can only hold 16 bits of your potentially-32-bits offset (cg1). A 32 bits value can be split in two 16 bits values using lo=full & 0xFFFF (masking out the higher bits) and hi=full >> 16 (right-shifting the full value).ManOfSteel wrote: Brendan, I didn't really understand what you meant by these:Code: Select all
dw (cg1 & 0xFFFF) ;offset low word ... dw (cg1 >> 16) ;offset high word
The problem is that, in most situations, such things doesn't work because the exact value of the symbol 'cg1' is unknown to the assembler (which must leave a part of the job to the linker) and that linkable objects usually cannot tell "this is the lowest 16 bits of a 32 bits offset, the highest 16 bits are there... look ..."
So you have to leave the two fields unfilled and perform the computations yourself at runtime, before you use the callgate (of course)
Re:Call gates
And how is that done? Is it possible to take the 32 bits offset and split it into two 16 bits offset? Can it be done using shr and shl or something else?So you have to leave the two fields unfilled and perform the computations yourself at runtime, before you use the callgate (of course)
Re:Call gates
Hi,
Cheers,
Brendan
Yes:ManOfSteel wrote: And how is that done? Is it possible to take the 32 bits offset and split it into two 16 bits offset? Can it be done using shr and shl or something else?
Code: Select all
;Set kernel process call gate offset
mov ebx,[KERNspace+HEADEREND]
mov [GDTaddress+SELPROCAPI],bx
shr ebx,16
mov [GDTaddress+SELPROCAPI+6],bx
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Call gates
What am I doing wrong again?
This is before setting up the GDT (lgdt)...
...and This is my call gate
This is before setting up the GDT (lgdt)...
Code: Select all
mov ebx,[cg1]
mov [cg1low],bx
shr ebx,16
mov [cg1high],bx
Code: Select all
CallGate01:
dw cg1low
dw 08h
db 0
db 10001100b
dw cg1high
GDTEnd:
cg1:
retf
cg1low dw 0
cg1high dw 0
Re:Call gates
Hi,
Hope that helps...
Cheers,
Brendan
Try this:ManOfSteel wrote: What am I doing wrong again?
Code: Select all
mov ebx,cg1
mov [CallGate01],bx
shr ebx,16
mov [CallGate01+6],bx
...and This is the call gate:
CallGate01:
dw 0 ;Offset low word (set dynamically)
dw 08h ;Code segment
db 0
db 11101100b ;present (1), ring3 (11), type (01100)
dw 0 ;Offset high word (set dynamically)
GDTEnd:
cg1:
retf
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.