"Protected Mode" tutorial question

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator:Moderators

Post Reply
scorpion007
Posts:7
Joined:Sun Nov 18, 2007 9:32 am
"Protected Mode" tutorial question

Post by scorpion007 » Thu Jan 24, 2008 7:57 am

Hi,

I am wondering, in the aforementioned tutorial, why you

Code: Select all

jmp	0x8:Stage2
.

I am interested in the segment offset value, 0x8. I understand you explain that to be the offset in the GDT, but I had a look at the intel manual Vol 3A, Section 3.4.2, that the segment selector is actually a packed 16 bit value containing a few fields, not just a simple offset value.

It says the first 2 bits are the Requested Privilege level, the next is the Table Indicator flag, and only then, are the last 13 bits the index into the GDT/LDT.

So shouldn't the correct value to use be:

0100 0000 binary, or
0x0040 ?

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Post by Andyhhp » Thu Jan 24, 2008 10:17 pm

I am not totally sure but I believe that this is why.

When you specify a selector, the CPU/MMU does some checks. First it makes sure that you are not using an instruction that is more privileged than your current Ring Level. The Table flag may be something to do with paging/virtual memory (I'm not sure - I think I slept through that OS lecture). Then it masks out the selector index and looked up that entry in the relevant descriptor table.

I'm perfectly welcome to being corrected by someone who wasn't using OS lectures to sleep as much as I was :oops:

Andrew
Image

User avatar
Mike
Site Admin
Posts:465
Joined:Sat Oct 20, 2007 7:58 pm
Contact:

Post by Mike » Fri Jan 25, 2008 12:34 am

Intel Manual Vol 3A, Section 3.4.2 wrote: Index(Bits 3 through 15) — Selects one of 8192 descriptors in the GDT or LDT. The processor multiplies the index value by 8 (the number of bytes in a segment descriptor) and adds the result to the base address of the GDT or LDT (from the GDTR or LDTR register, respectively).
Looking at the selector number 0x8, we must remember that this value will be placed in the format of a segment selector of the format:

Code: Select all

Bits 0..1: Requested Privilege Level (RPL)
Bit 2: Descriptor table type
Bits 3...15: Index number into table
In our jmp 0x8:codesel instruction, we are going to store 0x8 in the above format like this..

Code: Select all

1000 =

00000000000001 0 00
-- Index --    -- descriptor table type and rpl--
Remember the cpu multiplies the index by 8. This is because the lower 3 bits are for processor use.

So, lets do that...

Code: Select all

00000000000001b * 8 decimal = 8, or 1000 binary.
...So, now we have this in our selector:

Code: Select all

00000000001000 0 00
-- Index --    -- descriptor table type and rpl--
Notice the index is still 8? It uses this index value to offset into the descriptor specified by the table type (Which depends on the current state of the cpu)

You will find the above true for any selector from 0 through 8192, as 8192 is max allows selectors in a table.

I hope this answers your question.
Lead Programmer for BrokenThorn Entertainment, Co.
Website: http://www.brokenthorn.com
Email: webmaster@brokenthorn.com

scorpion007
Posts:7
Joined:Sun Nov 18, 2007 9:32 am

Post by scorpion007 » Sat Jan 26, 2008 4:10 am

Ah, that makes perfect sense! Thanks.

The reason why it makes perfect sense is that each entry is exactly 8 bytes long, so there's no point in wasting space by allowing non-multiple of 8 indices.

Each index (bit 3-15) is basically a scaled index into the table, I just didn't realise the processor performed this scaling for me. Must've overlooked that detail.

So
index 0 => the null descriptor (offset 0)
index 1 => the first real descriptor (offset 8)
index 2 => the second descriptor (offset 16)
...
index N => the Nth descriptor (offset 8*N)

Makes sense :) Thanks.

Post Reply