Page 1 of 1

Intel Manual Questions

Posted: Fri Jun 08, 2007 11:02 am
by Lprogster
...

Thanks everyone,
Lster

Posted: Fri Jun 08, 2007 11:38 am
by jnc100
Lprogster wrote:1. What is the idea with #PF(0) and #PF(fault code)? What do they represent - I found the intel manual a bit unclear...
#PF is an exception, specifically the page fault exception (number 14). When an exception is triggered (jn pmode), the processor looks up the exception handler in the IDT. The exact mechanism is described in 3A:5.12.1. Certain exceptions, however, have what is called an error code. Specifically, these are numbers 8, 10, 11, 12, 13, 14 and 17.

When an exception with an error code is triggered, then the last thing pushed onto the stack is the error code (after the return EIP). Your exception handlers for the exceptions described above need to expect this error code to be there, the others need to assume it isn't there.

In the case of the page fault exception, the error code is used in conjunction with the cr2 register. The CR2 register contains the address that, in trying to be accessed, triggered the page fault. The error code describes whether the fault was by a PL3 or PL0 task, whether it was a read or a write and certain other bits. See 3A:5.15 - Interrupt 14.

#PF(0) means trigger a page fault, push 0x00000000 as the error code.

Lprogster wrote:2. LDTs aren't used generally any more are they? Are TSSs used in software task-switching?
Generally not, although some people do use them and I have no problem with that. Segmentation is pretty much obsolete in 64-bit long mode, however.

In software task switching you need a single TSS. When an interrupt or exception is triggered in PL3 (user mode) and the IDT points to a PL0 interrupt handler, then the processor needs to switch its stack from the user process one to one in PL0 for the interrupt handler. It gets the values for SS and ESP from the current TSS. The fields it gets them from are ss0 and esp0 respectively. See 3A:5.12.1 again.

To create a TSS you need to fill out the structure in memory (actually, you only need to set ss0 and esp0 for software task switching), create an entry in the gdt for it (hint, set the system segment flag - see 3A:3.5 - you need a '32-bit TSS (available)'. Then, move the segment selector for the TSS to ax and execute a 'LTR ax' command to set the current TSS.

Lprogster wrote:3. What is a conforming segment?
Only code segments can be conforming.

Non-conforming segments cannot be accessed directly from a less privileged segment (i.e. numerically higher - PL3 cannot access a PL0 non-conforming segment through a JMP or CALL) unless it is through a call gate, task gate or interrupt handler. On the other hand you can directly access a PL0 conforming code segment from PL3, although execution continues at CPL3.

You cannot, however, directly jump to either a conforming or non-conforming code segment at a lower privilege level, i.e. your kernel cannot JMP to PL3 code directly, you need to use another means, typically IRET.

See 3A:3.4.5.1.


Regards,
John.

Posted: Fri Jun 08, 2007 11:42 am
by frank
1. PF is just a page fault. It is called when the code that is running does something like accessing a not present page. You can look in 5-15 in the system programming guide for more information on the page fault. PF(0) is just the notation used to say that the error code for the page fault is 0 since all page faults push an error code on the stack.

2.a No I don't think that many people use LDTs anymore. Most people just set their GDTs to reference all memory and use paging for protection.

2.b One TSS is used per processor in software task switching. The only fields that need to be filled out usually are the ss0 and esp0 fields. These values are used when the processor switches from a less privileged code segment to a more privileged code segment though a call gate or interrupt for example.

3. This is all I can say about conforming code segments. I have never used them myself:
[quote]
Code segments can be either conforming or nonconforming. A transfer of execution
into a more-privileged conforming segment allows execution to continue at the
current privilege level. A transfer into a nonconforming segment at a different privilege
level results in a general-protection exception (#GP), unless a call gate or task
gate is used (see Section 4.8.1, “Direct Calls or Jumps to Code Segmentsâ€

Posted: Fri Jun 08, 2007 11:53 am
by Lprogster
Woohoo! I understand all of that (I think ;))!

Thank you guys, I _really_ appreciate,
Lster

Posted: Fri Jun 08, 2007 1:55 pm
by Lprogster
...

Thanks again,
Lster

Posted: Fri Jun 08, 2007 5:27 pm
by jnc100
Lprogster wrote:When using paging, are segments still used to determine the PL of the current application?
Yes, the user/supervisor bit in a page table entry merely defines access rights for that page - whether currently running code can access it depends on the CPL.

The CPL is almost always equal to the DPL of the current code segment. The only time when this is not the case is when a less privileged piece of code executes code in a higher privilege conforming code segment, when the CPL is not changed and therefore remains that of the less privileged segment.

Regards,
John.

Posted: Sat Jun 09, 2007 5:38 am
by Lprogster
...

Thank you again - loads,
Lster

Posted: Sat Jun 09, 2007 5:52 am
by jnc100
Lprogster wrote:1. (In 3.4.5.1) Could you explain the S flag - I found the intel manual a bit confusing here...
Segments are of two types, either code/data segments or system segments. If S is clear (unlike what I said above :oops:) then it is a system segment. If S is set it is a code or data segment.

System segments are described in 3A:3.5, they include TSS segments (of which you'll need one). Code/data segments are described in 3A:3.4.5.1 - just copy the type nibble from the docs for the particular segment you wish.

Lprogster wrote:2. (Also in 3.4.5.1) I really don't understand the D/ B flag. It appears that I should just set it (to 1) and forget about it - would this be OK or will I need to use it for more advance things?
The D/B flag tells the processor what type of code or data to expect in a segment. If you set it for a code segment, then it expects 32-bit code (e.g. references to ax actually refer to eax), such as the code produced by gcc. If it is clear for a code segment, then the processor expects 16-bit code such that references to ax do point to ax - if you want to use eax from a 16-bit pmode code segment you need to use a register size prefix, which is described (I think) at the start of the second volume (the assembly bit).

For a stack segment, setting D/B means that calls to push, pop and the like will increment/decrement ESP, whereas if it is clear, then they increment/decrement SP. D/B also has relevance for expand-down segments, but I doubt you use them.

Regards,
John.

Posted: Sat Jun 09, 2007 6:05 am
by Lprogster
Thanks again - you are very good at explanations :)...

Lster

Posted: Sat Jun 09, 2007 8:31 am
by Lprogster
I've read chapter 4 now up until 4.6.1...

Here are my questions:

...

Thank you,
Lster

Posted: Sat Jun 09, 2007 3:05 pm
by Combuster
The RPL is the first two bits of a segment register (except cs?). Does that mean there can be many different RPLs at once? (for example: ds = 11h and es = 12h.)
Close. A selectors RPL is made up by the lowest two bits of that selector value. This includes code selectors(yes you can use a CS with different values for RPL/CPL and DPL). Since a segment selector contains separate fields for descriptor index and RPL you can mix them at will. That includes having two selectors pointing to the same descriptor with different RPLs.
In addition to checking segment limits, the processor also checks descriptor table
limits. The GDTR and IDTR registers contain 16-bit limit values that the processor
uses to prevent programs from selecting a segment descriptors outside the respec-
tive descriptor tables. The LDTR and task registers contain 32-bit segment limit value
(read from the segment descriptors for the current LDT and TSS, respectively). The
processor uses these segment limits to prevent accesses beyond the bounds of the
current LDT and TSS. See Section 3.5.1, “Segment Descriptor Tables,â€

Posted: Sun Jun 10, 2007 1:43 am
by Lprogster
Thanks Combuster, all clear!

Lster