task switching
Posted: Tue May 20, 2003 1:42 pm
I need a tutorial, example or link about multitasking, task switching, how to describe tasks and how to switch tasks in protected mode.
Those are what I have seen and understood from Alexei A. Frounze's tutorial and examples. I think I m missing something. So Ill be glad if someone advice me a link, tutorial or example to study.;-------------- TSS definition
struc TSS
slink dd ?
sesp0 dd ?
sss0 dd ?
sesp1 dd ?
sss1 dd ?
sesp2 dd ?
sss2 dd ?
scr3 dd ?
seip dd ?
seflags dd ?
seax dd ?
secx dd ?
sedx dd ?
sebx dd ?
sesp dd ?
sebp dd ?
sesi dd ?
sedi dd ?
ses dd ?
scs dd ?
sss dd ?
sds dd ?
sfs dd ?
sgs dd ?
sldtr dd ?
strace dw ?
sio_map_addr dw ?
ends TSS
...
in setup gdt proc
--------------------
mov eax, 0
mov ax, Code32Segment
shl eax, 4
add eax, offset MainTaskTSS
mov [ds:MainTask_descriptor.base_addr0_15], ax
shr eax, 8
mov [ds:MainTask_descriptor.base_addr16_23], ah
mov eax, 0
mov ax, Code32Segment
shl eax, 4
add eax, offset Task1TSS
mov [ds:Task1_descriptor.base_addr0_15], ax
shr eax, 8
mov [ds:Task1_descriptor.base_addr16_23], ah
mov eax, 0
mov ax, Code32Segment
shl eax, 4
add eax, offset Task2TSS
mov [ds:Task2_descriptor.base_addr0_15], ax
shr eax, 8
mov [ds:Task2_descriptor.base_addr16_23], ah
...
...
tss decleration
-------------------
MainTaskTSS TSS <0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104>
Task1TSS TSS <0, 0, 0, 0, 0, 0, 0, 0, offset Task1, 202h, 0, 0, 0, 0, offset stacktask1, 0, 0, 0, Data32SegmentID, Code32SegmentID, Data32SegmentID, Data32SegmentID, 0, 0, 0, 0, 104>
Task2TSS TSS <0, 0, 0, 0, 0, 0, 0, 0, offset Task2, 202h, 0, 0, 0, 0, offset stacktask2, 0, 0, 0, Data32SegmentID, Code32SegmentID, Data32SegmentID, Data32SegmentID, 0, 0, 0, 0, 104>
....
after switching pmode
--------------
...
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0
lldt ax
mov ax, MainTaskID
ltr ax
...
and in timer int
-------------
cmp [TaskNo], 0
jne t2
mov [TaskNo], 1
db 0eah ;far jmp
dw 0, 0, Task2ID
t2:
mov [TaskNo], 0
db 0eah
dw 0, 0, Task1ID
Isnt this enough for TSS preparation?Pype.Clicker wrote: i cannot see any preparation of your TSS (i mean setting the entry point, code segment, data segments, stack pointer, etc ...)
Ill be glad if anyone has a working example...
MainTaskTSS TSS <0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104>
Task1TSS TSS <0, 0, 0, 0, 0, 0, 0, 0, offset Task1, 202h, 0, 0, 0, 0, offset stacktask1, 0, 0, 0, Data32SegmentID, Code32SegmentID, Data32SegmentID, Data32SegmentID, 0, 0, 0, 0, 104>
Task2TSS TSS <0, 0, 0, 0, 0, 0, 0, 0, offset Task2, 202h, 0, 0, 0, 0, offset stacktask2, 0, 0, 0, Data32SegmentID, Code32SegmentID, Data32SegmentID, Data32SegmentID, 0, 0, 0, 0, 104>
I just give a message in my task and then enter into an infinite loop. There is no division in my task procs. But there is an interesting thing.Beyond Infinity lazy wrote: i doubt you can induce a failure in taskswitching mechanism of a div by zero exception. I recommend you check your printf function (there of course you have something to convert integers to ascii - something that divides) or similar stuff where you DIVIDE something.
proc Task1
mov esi, offset Task1Message
call PMWriteMessage
tl1:
mov al, [esi+22]
inc al
cmp al, 39h
jb t1dnorst
mov al, 30h
t1dnorst:
mov [esi+22], al
jmp tl1
ret
endp Task1
In my timer code I change a byte(27th) of timer message and print it.(not includes ascii-str conversion). In my task, I also change a byte(22nd) of message but not prints it on screen(print part is out of loop). When execute my code, both 27th and 22nd bytes of timer message changes. So my task switching jumps to code but with failer of changing(pushing and popping) registers.proc Int20
mov esi, offset Int20Message
call PMWriteMessage
mov al, [esi+27]
inc al
cmp al, 39h
jne norst
mov al, 30h
norst:
mov [esi+27], al
mov al, 20h
out PIC8259MASTER, al
cmp [TaskNo], 0 ;switch to task once
jne t2
mov [TaskNo], 1
db 0eah ; far jmp
dw 0, 0, Task1ID
t2:
iretd
endp Int20
this sets up the TSS descriptor, but your task's state is described by the CONTENT of the task state segment, thus if you want your task to start with a given value of the stack pointer, you must set it up in the ESP field of the TSS ...udarkman wrote:Isnt this enough for TSS preparation?Pype.Clicker wrote: i cannot see any preparation of your TSS (i mean setting the entry point, code segment, data segments, stack pointer, etc ...)
I think I set ESP field in my TSS (offset stacktask1)... arent I right? ???Pype.Clicker wrote: this sets up the TSS descriptor, but your task's state is described by the CONTENT of the task state segment, thus if you want your task to start with a given value of the stack pointer, you must set it up in the ESP field of the TSS ...
and here is my TSS descriptor..Task1TSS TSS <0, 0, 0, 0, 0, 0, 0, 0, offset Task1, 202h, 0, 0, 0, 0, offset stacktask1, 0, 0, 0, Data32SegmentID, Code32SegmentID, Data32SegmentID, Data32SegmentID, 0, 0, 0, 0, 104>
and I think you are right about Div by 0 exception. I think I do sthg wrong and processor jumps garbage memory and execute nonsense codes. But where did I wrong? :-\MainTask_descriptor segment_descriptor < -1, 0, 0, 89h, 0cfh, 0>
Task1_descriptor segment_descriptor < -1, 0, 0, 89h, 0cfh, 0>
Task2_descriptor segment_descriptor < -1, 0, 0, 89h, 0cfh, 0>
Code: Select all
proc Int20
mov esi, offset Int20Message
call PMWriteMessage
mov al, [esi+27]
inc al
cmp al, 39h
jne norst
mov al, 30h
norst:
mov [esi+27], al
mov al, 20h
out PIC8259MASTER, al
cmp [TaskNo], 0 ;switch to task once
jne t2
mov [TaskNo], 1
db 0eah ; far jmp
dw 0, 0, Task1ID
t2:
iretd
endp Int20
Code: Select all
cmp [TaskNo], 0
jne t2
mov [TaskNo], 1
jmp far Task2ID:0
t2:
mov [TaskNo], 0
jmp far Task1ID:0
Code: Select all
IRQ0_handler :
save_state
whatever
if x==0 jmp T2
switch to task 1
jmp exit
T2:
switch to task 2
exit:
restore state
iretd
Im using tasm.What assembler does it come from ? (i'm just curious :p )
With this code I can not jump into my main task. The other tasks works fine unless I jump into main task. And also if I change the line like:....
mov ax, 0
lldt ax
mov ax, MainTaskID
ltr ax
this time I couldnt jump into task1. What may couse this?mov ax, Task1ID
ltr ax
My tasks includes infinite loop, I mean never returns. So I think 'jmp exit' command not necessary. But when I comment them the program crashes.proc Int20
pushad
push eax esi
mov esi, offset Int20Message
call PMWriteMessage
mov al, [esi+27]
inc al
cmp al, 39h
jne norst
mov al, 30h
norst:
mov [esi+27], al
mov al, 20h
out PIC8259MASTER, al
SwitchToTask1:
cmp [TaskNo], 0
jne SwitchToTask2
mov [TaskNo], 1
db 0eah
dw 0, 0, Task1ID
jmp Exit
SwitchToTask2:
cmp [TaskNo], 1
jne SwitchToMainTask
mov [TaskNo], 2
db 0eah
dw 0, 0, Task2ID
jmp Exit
SwitchToMainTask:
mov [TaskNo], 0
db 0eah
dw 0, 0, MainTaskID
Exit:
pop esi eax
popad
iretd
endp Int20
As I said, switching back to main task from task1 for ins.is it switching to it (as the first task) or switching *back* to it (after a successful switch to task1, for instance) ?
)Pype, Im sure you are right, but my repetation is due to my poor english. (Indeed, still dont understand why to need an exit instruction although will never return from task, but dont mind)If you don't believe me,