Page 1 of 1

TSS load fail?

Posted: Fri Dec 03, 2010 3:17 pm
by mariuszp
Okay, this is pretty weird. I used JamesM's code as an example for loading the Task State Segment (TSS) but it kept on rebooting. I used his TSS structure first, but then I re-wrote the TSS structure using the TSS wiki on OSDev. Just like JamesM, I loaded ss0 with 0x10 and esp0 with 0. There were no interrupts, nor did I currently get to user-mode. I really need help because it confuses me!

i have a failure() function that halts the processor so I used it for debugging. Before I loaded the TSS, everything worked fine. I found out the reboot happens AFTER the load - DIRECTLY after. Here's all code required:

init_gdt()

Code: Select all

static void init_gdt()
{
   gdt_pointer.limit = (sizeof(struct gdt_entry) * 5) - 1;
   gdt_pointer.base  = (u32int)&gdt_entries;

   gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
   gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
   gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
   gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
   gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
   write_tss(5, 0x10, 0);

   gdt_flush((u32int)&gdt_pointer);
   tss_flush();
   failure("Force stop after TSS load");
};
write_tss() (changed!)

Code: Select all

static void write_tss(s32int num, u16int ss0, u32int esp0)
{
   u32int base = (u32int) &tss;
   u32int limit = base + sizeof(struct tss_entry);

   gdt_set_gate(num, base, limit, 0xE9, 0x00);

   memset(&tss, 0, sizeof(struct tss_entry));

   tss.ss0  = ss0;
   tss.esp0 = esp0;
}
tss_flush()

Code: Select all

[GLOBAL tss_flush]
tss_flush:
  mov ax, 0x2B ; TSS index
  ltr ax
  ret
struct tss_entry

Code: Select all

struct tss_entry
{
	u32int link;        // Unused
	u32int esp0;        // Kernel stack pointer (loaded on task-switch)
	u32int ss0;         // Kernel stack segment (0x10, u32int to avoid the resv. 16-bit high word)
	u32int esp1;        // Unused....
	u32int ss1;
	u32int esp2;
	u32int ss2;
	u32int cr3;
	u32int eip;
	u32int eflags;
	u32int eax;
	u32int ecx;
	u32int edx;
	u32int ebx;
	u32int esp;
	u32int ebp;
	u32int esi;
	u32int edi;
	u32int es;
	u32int cs;
	u32int ss;
	u32int ds;
	u32int fs;
	u32int gs;
	u32int ldtr;
	u16int iopb;        // Please do not use this value, because no programs will have access to I/O ports directly
	u16int resv;
} __attribute__ ((packed));
Any help???? Or clues???? At least does anyone know what could cause that weird problem?

P.S. failure() did not halt - there was a reboot. That means the problem happens directly after the load. Please note, that without KVM, the system crashes instead of reboots.

Re: TSS load fail?

Posted: Fri Dec 03, 2010 3:22 pm
by NickJohnson
Why are you setting esp0 to 0? It's supposed to be the stack pointer for kernel interrupt handlers.

Re: TSS load fail?

Posted: Fri Dec 03, 2010 3:25 pm
by mariuszp
In JamesM's tutorial, he temporarily set it to 0. As I said, interrupts do not happen yet. Or does it matter?

Re: TSS load fail?

Posted: Fri Dec 03, 2010 3:33 pm
by mariuszp
I tried loading esp0 from the esp register. Still fails.

Re: TSS load fail?

Posted: Fri Dec 03, 2010 3:42 pm
by NickJohnson
Sorry - I didn't see that you weren't enabling interrupts yet.

The most significant think I see is that you set "limit" to base + sizeof(tss) instead of base + sizeof(tss) - 1, which it should be IIRC.

Re: TSS load fail?

Posted: Fri Dec 03, 2010 3:45 pm
by mariuszp
Thanks. But it still does not fix the problem. Does loading the TSS require certain conditions or something? If so, please describe them.

Re: TSS load fail?

Posted: Fri Dec 03, 2010 3:55 pm
by NickJohnson
Oh, I see the problem now: you have the size of the GDT set to 5 descriptors, when the TSS is the 6th. You're probably getting a general protection fault when the processor tries to load the TSS descriptor from outside of the GDT.

Re: TSS load fail?

Posted: Sat Dec 04, 2010 2:33 pm
by mariuszp
NickJohnson wrote:Oh, I see the problem now: you have the size of the GDT set to 5 descriptors, when the TSS is the 6th. You're probably getting a general protection fault when the processor tries to load the TSS descriptor from outside of the GDT.
Works. Thanks.

Re: TSS load fail?

Posted: Sat Dec 04, 2010 2:44 pm
by mariuszp
I was trying to fix that bug for weeks. I even had to rewrite code. AND YOU FIXED IT!!! THANKS!!!!!

Credit.

Re: TSS load fail?

Posted: Sat Dec 04, 2010 11:14 pm
by iLewis
mariuszp wrote:I was trying to fix that bug for weeks. I even had to rewrite code. AND YOU FIXED IT!!! THANKS!!!!!

Credit.
You will find your life much much easier if you set up exception handlers that print the exception number to the screen and the contents of the registers. EIP is extremely useful since you can disassemble your kernel and find the offset as given by EIP. Also you will find that the error codes given by some exceptions will help you greatly too.

Taking blind stabs in the dark and just trying to "fluke it" when something dosnt work takes ages.

I suggest you do some research on google about "Interrupt handlers", since i was unable to find a tute on osdev about the topic, only how to reprogram the PIC which you will have to do anyway.

Re: TSS load fail?

Posted: Sun Dec 05, 2010 6:08 am
by mariuszp
iLewis wrote:
mariuszp wrote:I was trying to fix that bug for weeks. I even had to rewrite code. AND YOU FIXED IT!!! THANKS!!!!!

Credit.
You will find your life much much easier if you set up exception handlers that print the exception number to the screen and the contents of the registers. EIP is extremely useful since you can disassemble your kernel and find the offset as given by EIP. Also you will find that the error codes given by some exceptions will help you greatly too.

Taking blind stabs in the dark and just trying to "fluke it" when something dosnt work takes ages.

I suggest you do some research on google about "Interrupt handlers", since i was unable to find a tute on osdev about the topic, only how to reprogram the PIC which you will have to do anyway.
I did set up an exception handler. Both for bad TSS AND double fault. None of them reported any error.

Re: TSS load fail?

Posted: Sun Dec 05, 2010 6:27 am
by iLewis
mariuszp wrote:I did set up an exception handler. Both for bad TSS AND double fault. None of them reported any error.
You only set up for handlers for 2 exceptions? :S Id have just gone with all 16 that way nothing can get past you without you knowing about it and you catch (which is probable in your case) GPFs and if you have paging, Page Faults

Having said that however, if your TSS has in incorrect ESP0 (which you say is all working now, Good to hear :D) then when an interrupt is fired and ESP0 is loaded, and if that is 0... well... your handler will just fault again even if it is a double fault handler as soon as you attempt to preserve a register/push/pop something