Page 1 of 1
Confused about a structure (segment descriptor)
Posted: Wed Aug 29, 2007 1:54 pm
by jerryleecooper
Hello, I try since yesterday to have a tss in my multitasking code so I can have protection (ring 3 => ring 0), but I get a protection fault when I do. I think I targeted the problem and it is that the busy bit in the tss segment descriptor is set. I tried do remove it, but there's still GP exceptions. That's when I tought that probably, my segmentdescriptor struct declaration was probably wrong. Take a look:
Code: Select all
typedef struct segmentdescriptor {
unsigned short limit1500;
unsigned short base1500;
unsigned char base2316;
unsigned type : 4;
unsigned desctype: 1;
unsigned dpl : 2;
unsigned present : 1;
unsigned avl : 1;
unsigned l : 1;
unsigned db : 1;
unsigned g : 1;
unsigned limit1916: 4;
unsigned char base3124;
} __attribute__ ((packed)) segmentdescriptor;
Is there's something wrong with it? If I follow the intel manual, the limit1916 field should be before avl, but if I do this, the Virtual PC machine does'nt like that.
Posted: Wed Aug 29, 2007 4:42 pm
by Combuster
Try running your kernel in Bochs - it will likely complain about unusual errors sources (like loading a tss). Use the resulting message to diagnose the reason of the #GP.
Posted: Wed Aug 29, 2007 6:11 pm
by Kevin McGuire
The structure looks correct, but I have never used bit fields much so I can not say that they are not being interpreted correctly.
Posted: Wed Aug 29, 2007 6:31 pm
by jerryleecooper
Thank oyu two for your replies . I changed the placement of the limit1916 field, to where it was supposed to be, and now I still get #GP fault and not "virtual machine error must close" from Virtual PC, so it's good.
Here's my refreshed structure:
Code: Select all
typedef struct segmentdescriptor {
unsigned short limit1500;
unsigned short base1500;
unsigned char base2316;
unsigned type : 4;
unsigned desctype: 1;
unsigned dpl : 2;
unsigned present : 1;
unsigned limit1916: 4;
unsigned avl : 1;
unsigned l : 1;
unsigned db : 1;
unsigned g : 1;
unsigned char base3124;
} __attribute__ ((packed)) segmentdescriptor;
I don't use bitfield generally, but if the feature exist, why not using it? And it makes the code, cleaner? Bitfields makes C a higher level language than requested, imho.
Now...
Code: Select all
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
Is this code right? Because I think Ive found the problem. It's about segment selectors. They have the segment, the TI bit, and the RPL, but I don't use that when adressing my segment registers. Do I need to? Because my code works correctly without.
Posted: Thu Aug 30, 2007 3:47 am
by JamesM
You must always use the RPL. So, if your descriptors are as follows (standard layout)
Code: Select all
0x00 : null descriptor
0x08 : kernel CS
0x10 : kernel DS/SS
0x18 : user CS
0x20 : user DS/SS
Then, you would reference them like this:
Code: Select all
0x00 : bleh, never reference it
0x08 : RPL=0
0x10: RPL=0
0x1b: RPL=3
0x23: RPL=3
.
Posted: Thu Aug 30, 2007 7:51 am
by jerryleecooper
Thank you. Ive set the selector given to ltr to 5<<3 and now it works. So I understand, the selector need to be an index, and not an index * 8. That was my error.
Posted: Thu Aug 30, 2007 2:37 pm
by jerryleecooper
Everythings is working right, now!
I can now implement the v8086 thing so I can get VBE and a graphical GUI. youppi!