Page 1 of 1

TSS problems

Posted: Fri Aug 30, 2002 11:20 am
by K.J.
I'm working on getting TSS task switching working in my OS, but am having a problem...

I relocate my GDT so that it starts at 0x500:
[tt]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; relocate the GDT to 0x500
mov esi, gdt
mov edi, 0x500
mov ecx, (gdt_end-gdt)
cld
rep movsd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

lgdt [gdt_ptr]
[/tt]
My GDT looks like this(in the .data section):
[tt]
gdt: ;our descriptors
; NULL descriptor
dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24

[global _LINEAR_DATA_SEL]
_LINEAR_DATA_SEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 92h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
[global _LINEAR_CODE_SEL]
_LINEAR_CODE_SEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 9Ah ; present,ring 0,code,non-conforming,readable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
[global _TSS_ENTRY_0]
_TSS_ENTRY_0 equ $-gdt
desc TSS_START, TSS_SIZE, D_TSS
[global _TSS_ENTRY_1]
_TSS_ENTRY_1 equ $-gdt
desc TSS_START+TSS_SIZE, TSS_SIZE, D_TSS

gdt_end:

gdt_ptr:
dw gdt_end - gdt - 1
dd 0x500
[/tt]
TSS_START is 0x200000 and TSS_SIZE is 0x108.
I use a stucture and a pointer to access the actual TSS data:
[tt]
#pragma pack (push, 1) // this aligns the TSSes to a byte boundary(aligning to a page boundary isn't needed)

// TSS for 386 or higher
struct TSS {
unsigned int link;
unsigned long esp0;
unsigned int ss0;
unsigned long esp1;
unsigned int ss1;
unsigned long esp2;
unsigned int ss2;
unsigned long cr3;
unsigned int eip;
unsigned int eflags;
unsigned int eax;
unsigned int ecx;
unsigned int edx;
unsigned int ebx;
unsigned int esp;
unsigned int ebp;
unsigned int esi;
unsigned int edi;
unsigned int es;
unsigned int cs;
unsigned int ss;
unsigned int ds;
unsigned int fs;
unsigned int gs;
unsigned int ldtr;
unsigned int trace;
unsigned int io_map_addr;
};

#pragma pack (pop) // sets us back to the way we were

struct TSS *our_tsses = (struct TSS *) 0x200000;
[/tt]
I setup 2 TSSes(the very first one stays zeroed 'cause I don't use it):
[tt]
our_tsses[1].cs = read_cs();
our_tsses[1].ss = our_tsses[1].ds = our_tsses[1].es = read_ds();
our_tsses[1].cr3 = 0x9C000;
our_tsses[1].esp = read_esp();
our_tsses[1].eip = (unsigned long)&task_1;

our_tsses[2].cs = read_cs();
our_tsses[2].ss = our_tsses[2].ds = our_tsses[2].es = read_ds();
our_tsses[2].cr3 = 0x9C000;
our_tsses[2].esp = read_esp();
our_tsses[2].eip = (unsigned long)&task_2;
[/tt]
Then, I also have a make descriptor C function and a stucture for descriptors. They may be found here and here.
I replace the last descriptor so it points to the 3rd TSS(our_tsses[2]) so that I can see if it truely works. It doesn't :( My code for doing this looks like this:
[tt]
DESCRIPTOR *tss_1_descriptor = (DESCRIPTOR *) 0x500;
make_descriptor(&tss_1_descriptor[4], &our_tsses[2], sizeof(our_tsses[2]), D_TSS);
[/tt]
This doesn't work though. When I do a jump to the TSS desciptor(_TSS_ENTRY_1) after modifying(or trying to modify) that descriptor I get a system fault. That does not happen if I don't modify the TSS descriptor. The entire source code may be found here:
http://osdev.neopages.net/downloads/kj/cvs/

if needed.

Thanks in advance,
K.J.

Re:TSS problems

Posted: Fri Aug 30, 2002 1:28 pm
by Pype.Clicker
your pointers arithmetics (0x9c000, 0x20000, 0x500, etc.) seems a bit confusing to me ...

Did you ensure your TSS were Available ? what fault do you exactly receive ?

Re:TSS problems

Posted: Fri Aug 30, 2002 10:23 pm
by Warmaster199
I have a question: For assembler functions, I understand that eax/ax is the return value for a function... If so, in file rwRegs.asm, what is the point of the shr instruction? I know that it shifts right 16 spaces, replacing the low word of edx with the high word of edx... but what's the point if eax is the return value??

Code: Select all

_read_ds:
   mov eax, ds
   mov edx, eax
   shr edx, 16
                retn
??? Maybe it's just a placeholder, but tell me it's purpose, because to me it looks like the function should stop at:

Code: Select all

_read_cs:
   mov eax, cs
   retn

Re:TSS problems

Posted: Fri Aug 30, 2002 11:24 pm
by K.J.
Warmaster199: Hrmm... I based those functions off some I found laying around on the 'net. I took out everything but the mov eax, ... stuff, and they still work. Didn't make a change in my TSS prob, but it sized down my code a few bytes. :)

The exact fault code is 13(General Protection Fault). The memory addresses for the GDT, pagetables, and TSSes were picked just 'cause they would work without problem. They will be changed in the future.

K.J.

Re:TSS problems

Posted: Sat Aug 31, 2002 4:37 am
by Tim
Warmaster199: That read_ds function looks wrong: EDX will always contain zero, since DS is 16 bits in size. However, the result in EDX is not used.

Re:TSS problems

Posted: Sat Aug 31, 2002 9:55 am
by Warmaster199
yeah, I know some errors were there, Tim. Thanks for testing, K.J., and proving my theory :)