Page 1 of 1

protected mode confusion

Posted: Tue Mar 14, 2006 12:00 am
by the=Geek
My bootloader sets up segments in the gdt (code, data and linear) and then runs my kernel program. But I have found a couple of problems which have confused me:

When I want to print to screen i have to use the linear (unreal) selector to access video memory. The data selector doesn't work even though the data segment begins at physical address 0. Why is this? Isn't it just doing mov [0:B8000], ax or whatever?

Secondly, I decided I wanted my kernel to add entries to the gdt after it was loaded by the bootloader so that in addition to the three segments mentioned above, there would be three more (user_code, user_data and tss). But when I switch to the user_data selector and write to the first address in the user_data segment I receive a general protection exception.

If I add the same entries into the gdt in the bootloader then I can access the memory fine from in the kernel.

Here are the segment descriptor thingies:
codeseg db 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x9A, 0xC0, 0x00
dataseg db 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x92, 0xC0, 0x00
unreal db 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0x4F, 0x00

tss_seg db 0x1F, 0x00, 0x00, 0x00, 0x00, 0x89, 0xC0, 0x01
user_code db 0xFF, 0x0F, 0x00, 0x00, 0x02, 0xFA, 0xC0, 0x01
user_data db 0xFF, 0x0F, 0x00, 0x00, 0x02, 0xF2, 0xC0, 0x01

Cheers!
Gareth

Re: protected mode confusion

Posted: Tue Mar 14, 2006 12:00 am
by Da_Maestro
Have you made sure that the first selector is a null selector? Selector 0 must always be a null selector

Use selector 1 for your code, 2 for data and so on.

Re: protected mode confusion

Posted: Tue Mar 14, 2006 12:00 am
by obandu
Protected mode works a bit differently.
For address xxxx:00000 - where xxxx represents the segment selector and 00000 represents the offset;

In real mode the selector is a segment base address while in pmode, the selector is a GDT entry. In your example above, the data segment is segment 2 so you should MOV [02:b8000], eax to put something from eax into video memory.

Re: protected mode confusion

Posted: Wed Mar 15, 2006 12:00 am
by the=Geek
Thanks for the replies!

I have used a null selector (sorry, I should probably included it in my post).

Perhaps I should explain the mov [0:B8000], ax bit a little better...

If I am using linear (unreal) mode then I can access video memory fine using mov [0:B8000], ax etc but if I try to access it using protected mode and my data selector it doesn't work...
mov ax, 0x10
mov es, ax
mov edi, 0xB8000
xor ax,ax
mov [es:edi], ax

But my data segment beings at physical address 0 so when I do the above code isn't it equivolent to mov [0:B8000], ax? I hope this explains my problem better. Or I could put it another way.. how do I access video memory from protected mode?

Cheers Gareth

Re: protected mode confusion

Posted: Wed Mar 15, 2006 12:00 am
by JAAman
if your GDT is set up properly, this should work

if i understand your values correctly, you have 2 unusual settings (though neither should be your problem):
1) your UMode selector has G=0? meaning you still cannot access above 1MB (actually you cannot access as much as you could under RMode, though you can access it as a single segment) -- also you have default size = 32bit? this is also unusual -- and may affect your code in unexpected ways (and could also be CPU dependant ways)

2) your PMode segments (both) limit is restricted to 256MB (with G=1) -- while this may not be a problem (and may have been intentional), it is unusual, so i thought i would point it out


i cannot seam to find any other problem

Re: protected mode confusion

Posted: Wed Mar 15, 2006 12:00 am
by the=Geek
Cheers for reading.

So if my data segment descriptor base is 0 then that means my data segment begins at physical address 0 and that means that [ds:B8000] should give me access to video memory. If this is correct then I guess I must be doing something else wrong.

I worked out what was wrong with the gdt when I added to it in protected mode tho. I forgot I had to extend the length of gdt field in the gdtr register to accomodate the three new entries gdt_len+3*8

Thanks again.

Re: protected mode confusion

Posted: Fri Mar 17, 2006 12:00 am
by Phibred
Instead of having the +3 you might want to predeclare that memory and use 2 end variables one for the first gdt and one for your second, it makes like easier if you ever want to do this again :P

Re: protected mode confusion

Posted: Mon Mar 20, 2006 12:00 am
by the=Geek
Cheers for the help.

I figured out what I was doing wrong.

I was adding entries to the gdt from my kernel but forgetting to increase the length of the gdt in the gdtr register using lgdt (_8(|) doh!