Page 1 of 1

Question about Task switch using only one TSS Desciptor

Posted: Sun Feb 12, 2006 4:25 am
by raywill
When Using only one TSS Desciptor in the kernel,before we do

Code: Select all

jmp tss_sel:0
we need to reset base address to the 'new' task's tss.
The CPU will save the current task state to the 'current' TSS.
Since the base address has changed,how does CPU find the current(old) TSS?

Here is my understanding of how CPU does this:
Intel Manual says that CPU read the base address cached in TR invisiable portion.So even if we have changed the content of the TSS Desciptor ,the cached content is not affected at all.
The content of TR invisiable portion changes only when call ,jump or ltr instruction used.

I don't know if I am right.Please give me some hint.
Thanks.

Re:Question about Task switch using only one TSS Desciptor

Posted: Sun Feb 12, 2006 5:34 pm
by octavio
if you use only one tss you can?t do a hardware task switch
' jmp tss_desc,0 ' will generate a fault because the current task is bussy ,search in the faq about software task switch.
>how does CPU find the current(old) TSS?
CPU uses physical adress for descriptors table and also for the TSS data.

I don't know if I am right i?m also learning :)

Re:Question about Task switch using only one TSS Desciptor

Posted: Sun Feb 12, 2006 11:08 pm
by raywill
if you use only one tss you can?t do a hardware task switch
But I ever seen a tutual implement task switch using only one TSS Descriptor(by John S. Fine [email protected])
' jmp tss_desc,0 ' will generate a fault because the current task is bussy ,
What's if I clear BF before I do jump?
search in the faq about software task switch.
I have implemented software task switch sucessfully.
I just want to do it in another way :)

Re:Question about Task switch using only one TSS Desciptor

Posted: Mon Feb 13, 2006 2:38 am
by Ytinasni
....cached in TR invisiable portion.So even if we have changed the content of the TSS Desciptor ,the cached content is not affected at all.
Correct.
The content of TR invisiable portion changes only when call ,jump or ltr instruction used.
Also correct.
Note that the 'cache' consists of only the physical address and limit from the descriptor, not the contents of the TSS.
What's if I clear BF before I do jump?
It'll either
- error because the current task ISNT busy; or
- Save the current task state into the TSS, and load it all out unchanged, effectively giving you a few 'nop' instructions

I dont know which, as i dont have the intel processor manuals handy.
But I ever seen a tutual implement task switch using only one TSS Descriptor
That would be software task switching.

This Page has plenty of information about both Software and Hardware switching.

Re:Question about Task switch using only one TSS Desciptor

Posted: Mon Feb 13, 2006 8:48 am
by Brendan
Hi,
Ytinasni wrote:
What's if I clear BF before I do jump?
It'll either
- error because the current task ISNT busy; or
- Save the current task state into the TSS, and load it all out unchanged, effectively giving you a few 'nop' instructions

I dont know which, as i dont have the intel processor manuals handy.
Not quite - it will work AFAIK. The CPU saves the old CPU state where the hidden parts of the TR register tells it to, and loads the new CPU state from the where the GDT descriptor tells it to.

I'd be a little cautious though (it relies on the exact order that the CPU uses for each step of the task switch). It will work on Intel CPUs, but I'm not sure about other manufacturers (e.g. Cyrix, Transmeta, VIA). I'd also check to see if the busy flag is set after the task switch, just in case.
Ytinasni wrote:
But I ever seen a tutual implement task switch using only one TSS Descriptor
That would be software task switching.
Once upon a time (about 10 years ago) this method was discussed on a protected mode mailing list where John Fine was one of the most knowledgeable participants. I haven't seen this tutorial, but I wouldn't be surprised if it does exactly what Raywill says it does....

The other alternative discussed at the time was using 2 GDT descriptors and flipping between them. This approach is a little messier, but would be 100% reliable in all cases.


Cheers,

Brendan

Re:Question about Task switch using only one TSS Desciptor

Posted: Mon Feb 13, 2006 9:42 pm
by raywill
Once upon a time (about 10 years ago) this method was discussed on a protected mode mailing list where John Fine was one of the most knowledgeable participants. I haven't seen this tutorial, but I wouldn't be surprised if it does exactly what Raywill says it does....
Here is the readme from his source code:
read.me for tasktes1.zip Hardware multi-tasking example
Version 1.0, Mar 25, 1998
Sample code
by John S. Fine [email protected]
I do not place any restrictions on your use of this source code
I do not provide any warranty of the correctness of this source code
____________________________________________________________________________

To run:

vload tasktest.bin

It runs 200 simultaneous tasks. Each task has a different combination
of the scheduling parameters "defer" and "quantum". Each task just
updates a counter on the screen, so you can see how fast they are
running.

Every task has a private TSS with a private CR3 value (a private page
directory) and one private page table and one private page (for its
stack). All tasks share the same code (as well as GDT, IDT etc.)

It uses only a single TSS descriptor in the GDT. It modifies the
TSS descriptor in the GDT to always point to the current task.

To rebuild (If you don't have gcc, you can skip that step):
You need JLOC version 0.6 or later.

gcc -c -O3 counter.c
gcc -c -O3 showcoun.c
NASM -f OBJ tasktest.asm
NASM -f OBJ tasks_h.asm
NASM -f OBJ idt2.asm
NASM -f OBJ set_vec.asm
NASM -f OBJ dump.asm
NASM -f OBJ 8259.asm
NASM -f OBJ mempool.asm
NASM -f OBJ meminit.asm
NASM -f OBJ pri_heap.asm
JLOC tasktest.lnk tasktest.bin tasktest.map
____________________________________________________________________________

This example includes a very flexible scheduler. It is based on the real-
time event scheduler in my 8254 examples. Some of the documentation there
might help to understand its inner working. This version is a normal
scheduler and not a real-time event scheduler.

The explanation of the scheduler parameters (as well as the code for
creating and time-slicing tasks) is in TASKS_H.ASM.

The code for maintaining the priority heap of active tasks is in
PRI_HEAP.ASM.
____________________________________________________________________________

This example include a manager for three pools of free 4K pages. The
kernel of a paged OS should manage pools of 4K pages. This is a good
example of how to do that using no significant memory overhead outside of
the free pages themselves. This code is in MEMPOOL.ASM

In this example, the initial set of free pages is identified and "freed"
by MEMINIT.ASM. That module also moves the entire kernel and all its
paging and other data to new pages allocated from the last pool. This
step might be required in an OS that needs low memory for DMA buffers
or similar purposes.
____________________________________________________________________________

Another interesting feature is the use of the "EMPTY" section. In
TASKTEST.LNK the EMPTY section is forced to be 4Kb aligned and beyond the
end of the stack. In MEMINIT.ASM, any memory allocated to that section is
returned to the free pool. In TASKS_H.ASM, memory is requested for
portions of that section as required by the kernel. This demonstrates a
common feature in mapped kernels. You can allocate a large amount of
address space for potentially large structures, and you can wait to
allocate RAM to that address space until you actually need it.
You can get the source code here:
http://www.xemean.net/resource/article.asp?id=12


Use two tss descriptor is really messing things up :(

Re:Question about Task switch using only one TSS Desciptor

Posted: Tue Feb 14, 2006 2:33 am
by Brendan
Hi,

From John's source, in the file "TASKS_H.ASM":
; A single descriptor in the GDT is used for all TSS's. In order to make
; that trick work:
;
; 1) I overwrite the address portion of the descriptor each time the
; current task is changed. To simplify that step, I assume that all the
; TSS's lie in the task structures in the "tasks" array, and that the
; task structures are aligned on 256 byte boundaries. This allows me to
; update only the middle word of the address.
;
; 2) The descriptor must be marked nonBusy before JMPing to it. In the
; current version, that is done exactly once (after the LTR in the
; startup code). The JMP does the following in sequence:
; I) Check that the new descriptor is not busy.
; II) Mark the new descriptor as busy.
; III) Mark the old descriptor as not busy.
; Since the old descriptor IS the new descriptor, it ends up not busy
; even though it is the current descriptor.
;
; If this code is used in an environment in which some task switches
; occur outside its control (such as interrupts to task gates), it may
; be necessary to uncomment the step of marking the descriptor not busy
; before the JMP.
I guess that makes it fairly clear...


Cheers,

Brendan

Re:Question about Task switch using only one TSS Desciptor

Posted: Tue Feb 14, 2006 8:05 am
by raywill
Still....How CPU does this?
I think the source code does not tell me that .
Is what I guessed in the first post right?