Page 1 of 1

[NEED HELP] Task-switching

Posted: Sat Jul 31, 2004 11:00 pm
by E-mean X.
;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

RE:[NEED HELP] Task-switching

Posted: Sun Aug 01, 2004 11:00 pm
by Anton
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.

RE:[NEED HELP] Task-switching

Posted: Sun Aug 01, 2004 11:00 pm
by E-mean X.
Hi,Anton:
Can you tell me something more? or drop me a mail: [email protected]
regards,
E-mean X.

RE:[NEED HELP] Task-switching

Posted: Sun Aug 01, 2004 11:00 pm
by Anton
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.

RE:[NEED HELP] Task-switching

Posted: Sun Aug 01, 2004 11:00 pm
by E-mean X.
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.

RE:[NEED HELP] Task-switching

Posted: Sun Aug 01, 2004 11:00 pm
by Anton
//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.