Intel Manual Questions

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Intel Manual Questions

Post by Lprogster »

...

Thanks everyone,
Lster
Last edited by Lprogster on Tue Oct 23, 2007 11:05 am, edited 1 time in total.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post 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.
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post 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â€
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

Woohoo! I understand all of that (I think ;))!

Thank you guys, I _really_ appreciate,
Lster
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

...

Thanks again,
Lster
Last edited by Lprogster on Tue Oct 23, 2007 11:05 am, edited 1 time in total.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post 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.
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

...

Thank you again - loads,
Lster
Last edited by Lprogster on Tue Oct 23, 2007 11:05 am, edited 2 times in total.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post 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.
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

Thanks again - you are very good at explanations :)...

Lster
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

I've read chapter 4 now up until 4.6.1...

Here are my questions:

...

Thank you,
Lster
Last edited by Lprogster on Mon Aug 27, 2007 10:50 am, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post 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,â€
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

Thanks Combuster, all clear!

Lster
Post Reply