;I worked on this code for several days,but it still confuse me.My task-swithing code do nothing but return to kernel,but it dosn't works.
mov [tss.esp0],dword s.esp0 ; set tss for schedule
mov [tss.ss0],word osdatasel
mov [tss.esp1],dword s.esp1
mov [tss.ss1],word 5*8+1
mov [tss.esp2],dword s.esp2
mov [tss.ss2],word 7*8+2
mov eax,cr3
mov [tss.cr3],eax
mov [tss.eip],dword schedule ;
pushf
pop eax
mov [tss.eflags],eax
mov [tss.esp],dword s.esp
mov [tss.es],word osdatasel
mov [tss.cs],word oscodesel
mov [tss.ss],word osdatasel
mov [tss.ds],word osdatasel
mov [tss.fs],word osdatasel
mov [tss.gs],word osdatasel
mov esi,tss
mov edi,0x40000 ; save to 0x40000
mov ecx,tsse-tss
cld
rep movsb
; set kernel tss
mov [tss.esp0],dword knl_mem-1
mov [tss.ss0], word osdatasel
mov [tss.esp1],dword knl_mem-1-0x10000
mov [tss.ss1], word 5*8
mov [tss.esp2],dword knl_mem-1-0x20000
mov [tss.ss2], word 7*8
mov eax,cr3
mov [tss.cr3],eax
mov [tss.eip],dword osloop
pushf
pop eax
mov [tss.eflags],eax
mov [tss.esp],dword knl_mem-1
mov [tss.es], word osdatasel
mov [tss.cs], word oscodesel
mov [tss.ss], word osdatasel
mov [tss.ds], word osdatasel
mov [tss.fs], word osdatasel
mov [tss.gs], word osdatasel
mov esi,tss
mov edi,0x40000+128 ; i set 128byte for each tss
mov ecx,tsse-tss
cld
rep movsb
cld
mov [td.limit],word 128 ; limit = 128
mov [td.base1],word 0 ; tss0 for schedule 0x40000
mov [td.base2],byte 4
mov [td.attr1],byte 10001001b ;
mov [td.attr2],byte 10000000b
mov [td.base3],byte 0
mov esi,task_d
mov edi,0x80000+0x50 ; save to GDT
mov ecx,8 ; task selector 0x50
rep movsb
mov [td.limit],word 128 ; selector for tss1(kernel)
mov [td.base1],word 128
mov [td.base2],byte 4
mov [td.attr1],byte 10001011b ; set B bit
mov [td.attr2],byte 10000000b
mov [td.base3],byte 0
mov esi,task_d
mov edi,0x80000+0x58 ; save to GDT
mov ecx,8
rep movsb
mov [td.limit],word 128 ; selector for init_ code
mov [td.base1],word 128+128
mov [td.base2],byte 4
mov [td.attr1],byte 10001001b
mov [td.attr2],byte 10000000b
mov [td.base3],byte 0
mov esi,task_d
mov edi,0x80000+0x60 ; save it
mov ecx,8
rep movsb
mov eax,0x60 ; tss2
ltr ax
mov al,11101111b ;
out 0xA1,al
mov al,10101000b ; enable IRQ0
out 0x21,al
jmp $ ; let timer take control
osloop:
mov eax,10*65536+24
mov ebx,0x00FFFFFF
mov ecx,msg_welcome
mov edx,msg_welcome_end-msg_welcome
call drawtext
jmp osloop
schedule:
cli
mov [0x40000],word 0x58 ; back link
mov eax,0x20
out 0xA0,al
out 0x20,al
sti
iret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; tss_struck
tss:
tss.back dw 0
dw 0
tss.esp0 dd 0
tss.ss0 dw 0
dw 0
tss.esp1 dd 0
tss.ss1 dw 0
dw 0
tss.esp2 dd 0
tss.ss2 dw 0
dw 0
tss.cr3 dd 0
tss.eip dd 0
tss.eflags dd 0
tss.eax dd 0
tss.ecx dd 0
tss.edx dd 0
tss.ebx dd 0
tss.esp dd 0
tss.ebp dd 0
tss.esi dd 0
tss.edi dd 0
tss.es dw 0
dw 0
tss.cs dw 0
dw 0
tss.ss dw 0
dw 0
tss.ds dw 0
dw 0
tss.fs dw 0
dw 0
tss.gs dw 0
dw 0
tss.ldt dw 0
dw 0
dw 0
db 0
tss.iomap times (128-104) db 0x00 ; i/o map offset
tsse:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; schedule task gate
DW 0
DW 0x50
DB 0
DB 0x85
DW 0
[NEED HELP] Task-switching
RE:[NEED HELP] Task-switching
As far as i know(and it works for me), task switching is done without a seperate task for the schedualer, nor is the back link used. All you need to do in the schdeual function is jump to the next task. That's all.
Anton.
Anton.
RE:[NEED HELP] Task-switching
I'll try:
So, you have an array of tasks segments(eventualy you will have your own struct), which are tasks.
In the schedualer(very simple) you have a counter. Everytime you get in to the shchedualer, you increment this counter.(So, this schedualer and this counter is global to all the tasks(this is usualy part of the kernel-which is supposed to be in every task)). Then you jump to task tasks[counter].(depending on how you do it, you might need to do "out 0x20,0x20" before it(not after))
For more information use "Development Links" on this site.
Anton.
So, you have an array of tasks segments(eventualy you will have your own struct), which are tasks.
In the schedualer(very simple) you have a counter. Everytime you get in to the shchedualer, you increment this counter.(So, this schedualer and this counter is global to all the tasks(this is usualy part of the kernel-which is supposed to be in every task)). Then you jump to task tasks[counter].(depending on how you do it, you might need to do "out 0x20,0x20" before it(not after))
For more information use "Development Links" on this site.
Anton.
RE:[NEED HELP] Task-switching
So you mean software task-switching,right?
As far as I know,software task-switching is faster than hardware(but i don't know how to do that),which gate do you access to scheduler in IDT? And,how do you jump to tasks?
Do you mind post some relevant code on this board? or send it to my mailbox?
I'll check the Links.
Thank you.
E-mean X.
As far as I know,software task-switching is faster than hardware(but i don't know how to do that),which gate do you access to scheduler in IDT? And,how do you jump to tasks?
Do you mind post some relevant code on this board? or send it to my mailbox?
I'll check the Links.
Thank you.
E-mean X.
RE:[NEED HELP] Task-switching
//So you mean software task-switching,right?
No.
Software switching means that you load all the regs, .. outself. Hardware swichting means that you use intel32 instrucitons(64 platfrom does not support it).
//And,how do you jump to tasks?
You create a task segment, and then do a jmp far [selector of the new task segment]:any number. (Look in the intel docs)
//Do you mind post some relevant code on this board? or send it to my mailbox?
Well here is some code to switch back and forth between two tasks.
void do_timer()
{
if(current == 0x20 )current=0x28;
else if(current == 0x28 )current=0x20;
outb(0x20,0x20);
if(current == 0x20 )asm volatile("jmpl $0x20,$0x20");
else if(current == 0x28 )asm volatile("jmpl $0x28,$0x28");
}
Anton.
No.
Software switching means that you load all the regs, .. outself. Hardware swichting means that you use intel32 instrucitons(64 platfrom does not support it).
//And,how do you jump to tasks?
You create a task segment, and then do a jmp far [selector of the new task segment]:any number. (Look in the intel docs)
//Do you mind post some relevant code on this board? or send it to my mailbox?
Well here is some code to switch back and forth between two tasks.
void do_timer()
{
if(current == 0x20 )current=0x28;
else if(current == 0x28 )current=0x20;
outb(0x20,0x20);
if(current == 0x20 )asm volatile("jmpl $0x20,$0x20");
else if(current == 0x28 )asm volatile("jmpl $0x28,$0x28");
}
Anton.