Page 1 of 1
Call Gates mechanism
Posted: Tue Dec 26, 2006 4:34 pm
by INF1n1t
This is confusing, really! I've searched through the forum, but there are over 20 pages for this and I can't find something usefull. I think I can understand the call gate mechanism, but I want to ask something here:
Each call gate descriptor is only for one procedure. I think like that, because
1. We take the SELECTOR value from the call gate instruction (for example 33h).
2. We go to the GATE DESCRIPTOR, which is 33h.
3. We take the SELECTOR value from there and go to the CODE SEGMENT DESCRIPTOR with the same value. From there we take the BASE address. We go back to the GATE DESCRIPTOR, take the OFFSET value. Combine it with the BASE address and we're all happy - we have the entry point of the procedure..
So, I'm saying here, that if we have a different procedure, with different entry point, we should use different call gate! Please, tell me I'm right!
Posted: Tue Dec 26, 2006 4:46 pm
by Combuster
The simple answer: Yes
The complex answer: I don't know - that depends on the context
If you use one call descriptor for each system call, you might run out of GDT space. Bigger problem is when you want to add function calls at runtime which would require reallocating GDTs and the accompanying mess. Hence some people use one call gate, and use one passed parameter to select a function.
Posted: Tue Dec 26, 2006 4:50 pm
by INF1n1t
Combuster wrote:The simple answer: Yes
The complex answer: I don't know - that depends on the context
If you use one call descriptor for each system call, you might run out of GDT space. Bigger problem is when you want to add function calls at runtime which would require reallocating GDTs and the accompanying mess. Hence some people use one call gate, and use one passed parameter to select a function.
10x for the quick answer, but I still don't get it! We are ignoring the offset part from the CALL instruction. We are using only the selector for the GATE DESCRIPTOR. I still can't understand how can I pass parameter to select a function, where should I pass the parameter?
I'm sorry for the stupid questions here, but I'm reading the bad Intel Manual these days and I'm really confused!
Oh, I see a way to use a parameter: we take the BASE ADDRESS and OFFSET from the GATE and CODE DESCRIPTORS and then we add something to them to form the final address. Is it right?
Posted: Tue Dec 26, 2006 5:18 pm
by Combuster
INF1n1t wrote: 10x for the quick answer, but I still don't get it! We are ignoring the offset part from the CALL instruction. We are using only the selector for the GATE DESCRIPTOR. I still can't understand how can I pass parameter to select a function, where should I pass the parameter?
I'm sorry for the stupid questions here, but I'm reading the bad Intel Manual these days and I'm really confused!
Hmm I dont think Intel's Big Book of Patterns is that much of mysticism... I popped it up, found the appropriate chapter, and was able to figure what was going on in under a minute.
What a call gate does is allow entry to a higher-privileged level. The supplied address is ignored, because if we could enter the kernel at any point we wanted, we could for instance directly execute shutdown code.
Now, when a call gate is accessed, the parameters field is read. If a task switch occurs (that is, when switching to a higher privilege segment that is nonconforming), that amount of parameters is copied from the original stack to the new stack. That means that you can push the function number as you would with a standard C function. Alternatively, you could pass it in a register. In the called function you can read the passed argument and use that to branch to the desired function.
You can look at my documentation
here to see how such a scheme looks like. (I use a register calling convention, but you can replace the registers with arguments on the stack if you so desire...)
As a sidenote, Should you ever want to support sysenter/sysexit or related instructions, you are stuck with supplying a function number as you cant "choose" the target for these instructions.
Oh, I see a way to use a parameter: we take the BASE ADDRESS and OFFSET from the GATE and CODE DESCRIPTORS and then we add something to them to form the final address. Is it right?
Sortof. the given code selector will be loaded, so its base will take effect. the IP will directly come from the gate descriptor. The net effect is that execution starts at offset+base in the virtual address space. Note that base=0 is pretty much standard, and a different setup is difficult to manage.
Posted: Wed Dec 27, 2006 2:41 am
by INF1n1t
Oh, I think you explain much better than the manual there, I will give a link to it here:
http://www.baldwin.cx/386htm/s06_03.htm
If, this is the manual of course, because I think the pdf book was different, but they said it is easier to read.
Now I understand the call gates mechanism, thank you for your patience and answers
BTW, I like the way you've documented your os...
Posted: Wed Dec 27, 2006 4:21 am
by Combuster
Uh o...k... That doc is stuffed with bad details and typo's. I suggest you do not read that.
Now I understand the call gates mechanism, thank you for your patience and answers
You're welcome
BTW, I like the way you've documented your os...
Yea, i need it in order to not get driven crazy managing a project of over 500 files.
Posted: Wed Dec 27, 2006 4:23 pm
by INF1n1t
One last thing, I would say to the other beginners like me, that I've just understood yesterday:
Do yourself a favor and read the true Intel Documentation (Volume 3)...don't read documents like the one I gave on my previous post. And I would say, if anybody read this - don't continue! There are errors in the graphics, the text is wrong sometimes...everything is shitty there!
Posted: Wed Dec 27, 2006 10:44 pm
by Brendan
Hi,
INF1n1t wrote:One last thing, I would say to the other beginners like me, that I've just understood yesterday:
Do yourself a favor and read the true Intel Documentation (Volume 3)...don't read documents like the one I gave on my previous post. And I would say, if anybody read this - don't continue! There are errors in the graphics, the text is wrong sometimes...everything is shitty there!
I haven't compared each line or anything, but to me the document you linked to looks like a straight "cut & paste" of Intel's 80386 manual (with the original ASCII art converted to pictures). The true Intel documentation is almost identical (if you read it with "DOS edit" or something that uses a monospaced font and gets the line drawing characters right).
IMHO the 80386 manual is good for beginners (e.g. someone who's written applications in C, but has no experience with assembly and system programming) - the latest manuals are full of extensions and additional complexity, and can be overwhelming.
I'd recommend starting with the 80386 manual, and then reading the latest manual (and then using the latest manual as a reference while writing your OS)....
BTW I put my (hardcopy) Intel manuals and AMD manuals together in a stack. Not including optimization guides (as I don't have hard copies of those) and realising that my Intel manuals aren't the latest (no virtualisation or long mode), I measured it as 270 mm tall.
Cheers,
Brendan
Posted: Thu Dec 28, 2006 12:56 am
by INF1n1t
Really, I'm now reading the latest Intel Manual and it's not the same like the other document. And as I said, there are mistakes in the illustrations...so either it's not a straight copy -> paste, or the intel manual was not corrected and edited before publishing!
Posted: Thu Dec 28, 2006 1:47 am
by Brendan
Hi,
INF1n1t wrote:Really, I'm now reading the latest Intel Manual and it's not the same like the other document. And as I said, there are mistakes in the illustrations...so either it's not a straight copy -> paste, or the intel manual was not corrected and edited before publishing!
Intel's 80386 Programmer's Reference Manual was first published in 1986 - a lot has changed in the last 20 years, including switching to PDF as the document format (the original 80386 manual is a text file!). Of course this means changes to the documentation
and changes to the CPU itself...
For reference, the original 80386 documentation can be downloaded
here. It isn't available from Intel's web site anymore - AFAIK they got rid of anything 80486 or older, except for the documentation for embedded 80386 and 80486 which isn't as obsolete).
The thing is, if you were converting a large text file into a set of HTML files, how would you do it? I'd split the text file into one text file per chapter, add a header and footer (html tags), then change the file names from *.txt to *.html. After that I'd worry about formatting, converting the ASCII art (cropping screen shots of the ASCII art viewed by DOS edit) and cross-linking. Alternatively I'd consider writing a conversion utility to do most of the cross-linking. In any case it's mostly impossible to introduce typing errors, etc during the conversion (no-one would be silly enough to manually type every sentence)...
Also, don't forget that there are errors in the latest documentation (as there are in any large piece of work).
BTW if you've got some nice new manuals, don't be afraid to write notes everywhere! It might feel strange taking a pen and writing all over brand new books, but I'll guarantee you'll be glad you did....
Cheers,
Brendan
Posted: Thu Dec 28, 2006 12:27 pm
by INF1n1t
Brendan wrote:Hi,
INF1n1t wrote:Really, I'm now reading the latest Intel Manual and it's not the same like the other document. And as I said, there are mistakes in the illustrations...so either it's not a straight copy -> paste, or the intel manual was not corrected and edited before publishing!
Intel's 80386 Programmer's Reference Manual was first published in 1986 - a lot has changed in the last 20 years, including switching to PDF as the document format (the original 80386 manual is a text file!). Of course this means changes to the documentation
and changes to the CPU itself...
For reference, the original 80386 documentation can be downloaded
here. It isn't available from Intel's web site anymore - AFAIK they got rid of anything 80486 or older, except for the documentation for embedded 80386 and 80486 which isn't as obsolete).
The thing is, if you were converting a large text file into a set of HTML files, how would you do it? I'd split the text file into one text file per chapter, add a header and footer (html tags), then change the file names from *.txt to *.html. After that I'd worry about formatting, converting the ASCII art (cropping screen shots of the ASCII art viewed by DOS edit) and cross-linking. Alternatively I'd consider writing a conversion utility to do most of the cross-linking. In any case it's mostly impossible to introduce typing errors, etc during the conversion (no-one would be silly enough to manually type every sentence)...
Also, don't forget that there are errors in the latest documentation (as there are in any large piece of work).
Yes, I must admit you're right here. No one's perfect
BTW if you've got some nice new manuals, don't be afraid to write notes everywhere! It might feel strange taking a pen and writing all over brand new books, but I'll guarantee you'll be glad you did....
Um, I'm printing the Intel Manual right now (just some chapters like the 'Protected Memory Management' and the 'Protection' chapter), so I don't care...sometimes I put sticky notes with a glue there
Posted: Sat Dec 30, 2006 1:28 am
by rexlunae
Sorry if this is non-sequitor, but...
I've always thought the call gate mechanism was a perfect example of the kind of cruft the x86 architecture would be better off without. The ability to copy stuff from one stack to the other could be nice, but it isn't as if you could just use any old compiled language to generate the necessary code, not unless that compiler is segmentation-aware, and generally your kernel is going to be able to access the memory and register contents of the calling task anyway.
It seems to me just simpler to handle system calls with interrupts, or better yet the sysenter/sysleave or syscall/sysret mechanisms. Interrupt gates are something you have to deal with anyway, so using them for system calls is easy. Call gates are a whole separate species of GDT inhabitants to worry about. sysenter and syscall bypass the segmentation mechanism entirely, which is a nice speed and simplicity bonus.
Posted: Sat Dec 30, 2006 1:32 am
by Tyler
rexlunae wrote:Sorry if this is non-sequitor, but...
I've always thought the call gate mechanism was a perfect example of the kind of cruft the x86 architecture would be better off without. The ability to copy stuff from one stack to the other could be nice, but it isn't as if you could just use any old compiled language to generate the necessary code, not unless that compiler is segmentation-aware, and generally your kernel is going to be able to access the memory and register contents of the calling task anyway.
It seems to me just simpler to handle system calls with interrupts, or better yet the sysenter/sysleave or syscall/sysret mechanisms. Interrupt gates are something you have to deal with anyway, so using them for system calls is easy. Call gates are a whole separate species of GDT inhabitants to worry about. sysenter and syscall bypass the segmentation mechanism entirely, which is a nice speed and simplicity bonus.
Variety is the spice of life my friend. And though i can't be bothered thinking up a list now, there are reasons for evey method possible and some reason to use them. At least there are alternatives to the Call Gate mechanism.
Posted: Sat Dec 30, 2006 1:53 am
by Candy
Brendan wrote:Also, don't forget that there are errors in the latest documentation (as there are in any large piece of work).
BTW if you've got some nice new manuals, don't be afraid to write notes everywhere! It might feel strange taking a pen and writing all over brand new books, but I'll guarantee you'll be glad you did....
As with any learning book, use the book to note things that are:
- Incorrect (with pen)
- You don't understand (with pencil)
- Written incomprehensibly (notes, with pen)
Can't say how much I agree with this.
Posted: Sat Dec 30, 2006 2:04 am
by Brendan
Hi,
Tyler wrote:Variety is the spice of life my friend. And though i can't be bothered thinking up a list now, there are reasons for evey method possible and some reason to use them. At least there are alternatives to the Call Gate mechanism.
Call Gates - can be used to pass parameters on the stack (but only the same number of parameters for each call gate). Takes 6 bytes of code (in 32-bit protected mode), so probably not so good if you're optimizing code for size. Can be used by code running at any privilege level.
Software Interrupts - no stack based parameters. Slightly slower than call gates (but only slightly, and it depends on which CPU). Takes 2 bytes of code. Can be used by code running at any privilege level.
Exceptions - no stack based parameters. Usually slower than software interrupts due to the hassle of figuring out the cause of the exception. Can be even better for code size (for example, using the breakpoint exception so that the kernel can be called with a single-byte "int3" instruction). Can be used by code running at any privilege level.
SYSCALL/SYSENTER - theoretically faster as the CPU does less work, but I'm not too sure how much faster overall, as the caller needs to preset values in registers beforehand (e.g. return EIP) and depending on the OS design some of the work skipped by the CPU might need to be done manually. Unfortunately for 32-bit OSs SYSCALL and/or SYSENTER anre't supported on all CPUs (including the newest Intel CPUs). There's similar compatability problems for 32-bit code running under a 64-bit OS (in this case Intel support 64-bit SYSCALL for 64-bit code, but not 32-bit SYSCALL for 32-bit code). Both SYSCALL and SYSENTER are 2 byte instructions. AFAIK SYSCALL can be used to pass parameters on the stack (SYSENTER can't). Can't be used by code running at any privilege level (only CPL=3 code can use SYSCALL or SYSENTER without problems).
Cheers,
Brendan