TSS

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
DarylD

TSS

Post by DarylD »

Why would I get a GPF when using ljmp *(...) to task switch using TSS's?

From what I can say, all the values in the TSS are filled in correctly, I am using two TSS's and the task register is also loaded correctly (I assume) by pointing at the first TSS.

I don't have to fill much in the first TSS apart from selectors right?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:TSS

Post by Pype.Clicker »

options are (iirc):
- your TSS selector isn't a TSS (bvut i guess it's not the case ;)
- if your TSS was busy, had an incorrect size, etc. you would get a task fault instead, so this is not the problem you face.
- maybe one of your data segment is wrong (not the stack segment 'cuz that one would trigger a stack fault).
- maybe your CS selector (in the target TSS) is wrong or the eip field is beyond the CS limit ...

that's all i can say ... try to find out the values that are in the registers at the time of the segfault ...
also check the "task switching" section of Intel System Programmers Manual for a detailed review of all (about 1 page of them) possible reason of failure...
DarylD

Re:TSS

Post by DarylD »

Well, the TSS is just a regular descriptor but with the access set to 0xE9 (i.e. its a kernel thread), the CS/DS etc are all set to the same as the running kernel. The eflags is the same as the running kernel too.

The EIP is a valid address too, I checked it in the kernel disassembly.

It is a simple worker thread I am trying to switch to.

PS. You have built quite a nice kernel there!
DarylD

Re:TSS

Post by DarylD »

Think I might have fixed it now (update: NOOO!!)

I was not popping one item off the stack during my int 0x0 (timer) handler routine.

It helps to actually show the eip of the GPF to track problems down ;)

Update: I have fixed the above problem, but now it GPF's on the actual ljmp *(%eax) statement where %eax is a GDT reference pointing to a TSS (i.e. 0x30)

I hate to bug you guys about this, but its baffling me I tell you!! I have tried a million and one permutations of code!!
Tim

Re:TSS

Post by Tim »

DarylD wrote:I hate to bug you guys about this, but its baffling me I tell you!! I have tried a million and one permutations of code!!
My advice is to ditch the TSS and write the task switching stuff yourself, for precisely this reason (i.e. it's a nightmare to debug).
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:TSS

Post by Pype.Clicker »

i personnally had problems too with ljmp for the task-switching, so i opted for a tiny nasm function that do it cleanly ...

Code: Select all

; "far" jump, mostly to allow task switching
; protocole: void _farJmp(offset, segment).
Cglobal farJmp
farJmp:
   push ebp
   mov ebp,esp
   jmp far [ebp+8]
   pop ebp
   ret
the Cglobal is a macro of mine that do either global %1 or global _%1 depending on a __UNDERSCORE__ flag (for linux/dos independence ...)
DarylD

Re:TSS

Post by DarylD »

Tim,

But software task switching looks decidely more complex!

Although having trawled google, I did come across one article on why Linux doesn't use TSS's for switching. To quote "It's
conceptually impossible to determine in a simple way what
caused an exception during a TSS switch. It's a 'too complex'
operation to be described with a simple fault. Soft-switching
sorts all the fault sources out nicely."

Okay, software switching it is. So this is essentially a case of saving/loading all registers into a structure for each thread. Is that right? After all these are all saved during an interrupt anyway so I can just use the register stack??
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:TSS

Post by Pype.Clicker »

DarylD wrote: Okay, software switching it is. So this is essentially a case of saving/loading all registers into a structure for each thread. Is that right? After all these are all saved during an interrupt anyway so I can just use the register stack??
It mainly depends on the environment which will call your software switching code (for instance, a C function will expect some registers to remain unchanged ...)

And about the complexity, software task-switching can become as complicated as hardware one when you also have to deal with multiple address space, distinct I/O operations, etc.
With the possible exceptions list in right hand and a good exception report on screen, TSS faults aren't *that* complicated ...

For instance, what is the reported selector (error code) for your GPF ?
DarylD

Re:TSS

Post by DarylD »

The selector can not be correct.

It reports something like 0x6BF which obviously isn't a valid selector!!

Anyway, I think I will switch to software task switching, so long as there is one TSS entry present and selected with the TR then it should handle stack changes (I assume).

UPDATE :: I got software task switching working between two tasks by saving/restoring the stack. Woo Hoo!! (This only works with no privilige level change but its a start!!)
Post Reply