Page 6 of 6

Re:tss and user space

Posted: Sat Jan 07, 2006 12:22 pm
by kataklinger
Probbably ypu have bad value of CS on stack while CPU executing IRET.

Re:tss and user space

Posted: Sat Jan 07, 2006 1:27 pm
by OZ

Code: Select all

int* stack = (int*)kmalloc(512);  //setup 512 byte size stack 

/* 512 bytes give space for 128 values on the stack - we will have 15 values on the stack - the stack grows to smaller addresses therefore goto stacktop*/

stack+=113;                           

stack[0]=0x10; //es
stack[1]=0x10; //ds
stack[2]=0x10; //fs
stack[3]=0x10; //gs
stack[4]=0;    //edi
stack[5]=0;    //esi
stack[6]=0;    //ebp
stack[7]=0;    //esp
stack[8]=0;    //ebx
stack[9]=0;    //edx
stack[10]=0;    //ecx
stack[11]=0;    //eax
stack[12]=(uint)entry; //entry point  
stack[13]=0x08;
stack[14]=0x0202;

task->p_kstack = (uint)stack+14;  // stackend will be stacktop + pushed values
it's the kernel mode version - so you've got to edit it respecting the 17 pushed values in usermode

Re:tss and user space

Posted: Sat Jan 07, 2006 1:32 pm
by GLneo
thx, OZ, but i've had a better maker for awile:

Code: Select all

void make_task(int pri, char *name, void (*entry)(), int ring)
{
    void *stack_mem;
    stack_data_t *stack;

    stack_mem = (unsigned int *)malloc(STACK_SIZE);
    stack_mem += STACK_SIZE - sizeof(stack_data_t);
    stack = stack_mem;
    if(ring == 0)
    {
        stack->gs = KERNEL_DATA_SEG;
        stack->fs = KERNEL_DATA_SEG;
        stack->es = KERNEL_DATA_SEG;
        stack->ds = KERNEL_DATA_SEG;
        stack->cs = KERNEL_CODE_SEG;
    }
    else
    {
        stack->gs = USER_DATA_SEG;
        stack->fs = USER_DATA_SEG;
        stack->es = USER_DATA_SEG;
        stack->ds = USER_DATA_SEG;
        stack->cs = USER_CODE_SEG;
    }    
    stack->edi = 0;
    stack->esi = 0;
    stack->esp = (unsigned int)stack;
    stack->ebp = stack->esp;
    stack->ebx = 0;
    stack->edx = 0;
    stack->ecx = 0;
    stack->eax = 0;
    stack->eip = (unsigned int)entry;
    stack->eflags = 0x00000202;
    
    strncpy(rrq[end].name, name, 32);
    rrq[end].stack = stack;
    rrq[end].ss = KERNEL_STACK_SEG;
    rrq[end].priority = pri;
    rrq[end].time = get_pri_time(pri);
    end++;
}
this works for kernel tasks, but i dont think i used stack corectly, dont i have to reverse it???

Re:tss and user space

Posted: Sat Jan 07, 2006 2:02 pm
by kataklinger
If CPU is in RING0 and interrupt happens, then CPU won't pop SS3 & ESP3 on stack, so you need to take care of that.

Re:tss and user space

Posted: Sat Jan 07, 2006 2:22 pm
by GLneo
ok thx, i changed my swiching asm code to this:

Code: Select all

_task_timer:
    push ss ; <------------- NEW -------------
    pushad
    push ds
    push es
    push fs
    push gs
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
;    cli
    push esp
    mov eax, _task_timer_c
    call eax
;    sti
    pop esp
    mov esp, eax
    pop gs
    pop fs
    pop es
    pop ds
    popad
    pop ss ; <------------- NEW -------------
    iretd
but didn't help, same error???, why, thx

Re:tss and user space

Posted: Sat Jan 07, 2006 5:07 pm
by kataklinger
You must learn to debug by yourself, I can't fall this anymore. Try looking this: http://my.execpc.com/~geezer/os/cosmos10.zip
look at krnl\kstart.asm. Maybe it will help.

Re:tss and user space

Posted: Sun Jan 08, 2006 7:49 am
by OZ
Plz don't get this wrong, but you got him wrong ;D
The asm stub is the same as for kernel mode, all you might need to add is patching the tss.
The rest stays the same as you had it for kernel mode.
The ESP? and SS? are pushed automatically as the usermode transition aka calling your handler happens. Therefore the only thing you should take care of is creating your stack frame for first execution must respect the fact, that theoretically before would have happened such a kernel / userland transition which would have resulted in a stack frame containing the additional ESP? and SS? just before the stackend - not the stacktop.

Re:tss and user space

Posted: Sun Jan 08, 2006 11:53 am
by GLneo
ok, well, right now i'm not using any user tasks, and it works ok just using kernel tasks, but when i enable my TSS it crashes, and i'm not even returning from a user task, is there a way to tell the cpu im using software switching so it dosnt use the TSS to switch tasks???, thx

Re:tss and user space

Posted: Mon Jan 09, 2006 8:51 am
by Crazed123

Code: Select all

set_a_gdt(5, (unsigned long)&TSS, sizeof(TSS) - 1, 0x89, 0x10);
Try that. You were setting the granularity flags used for a code or data segment and giving a limit a byte too long.

Re:tss and user space

Posted: Mon Jan 09, 2006 8:58 am
by JAAman
the CPU will never use the TSS to switch tasks, unless you explicitly tell it to (jmp,call, or ret to a TSS discripter for example)

but the CPU will always use the TSS for switching stacks (there is no way to disable it) even if you have not defined one yet (which will prob result in a tripple-fault, immediatly upon entering ring3)

under x86-64 there is even a way to define several different stacks to be used with different ints