tss and user space

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
JAAman

Re:tss and user space

Post by JAAman »

Brendan wrote: Once the initial TSS is setup, you'd just change "TSS->esp0" during every task switch (if each task has it's own kernel stack).
this is not necessary, the kernel stack should not be in shared space, and should start at the same point for each task, therefore, esp0 doesn't ever need to change (unless for some reason your storing values on the stack between calls?)

on task switch, the kernel stack is swaped when the address space is swapped, and when the kernel function ends, it returns to its entry point (at the start of task), the only time this won't be correct on task swap, is if that task is in a kernel routine, in which case it will return to start before esp0 is ever used

basically, once it is set up, the TSS will never need to be changed, unless you are using the I/O bitmap
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:tss and user space

Post by Colonel Kernel »

JAAman wrote: this is not necessary, the kernel stack should not be in shared space, and should start at the same point for each task, therefore, esp0 doesn't ever need to change (unless for some reason your storing values on the stack between calls?)
Do you mean you'd have multiple kernel stacks in physical memory, but map the "current" one into a fixed location in the kernel's address space, or do you mean having only one kernel stack per processor? If it's the latter, you may find making the kernel itself preemptable to be a bit of a challenge...
on task switch, the kernel stack is swaped when the address space is swapped, and when the kernel function ends, it returns to its entry point (at the start of task)
What if not every task switch results in an address space switch (e.g. -- switching between threads in the same process)?
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
Assembler

Re:tss and user space

Post by Assembler »

Kemp wrote: Pointers use ->
Simple (and not so simple) variables use .

So you would use .
Hi,

"->" is used when u got a pointer to the structure
so "p->whatever" equals "(*p).whatever" because the "." is higher than "*".
but if u have the structure not a pointer to it u should use the "." normally.

thanks
Kemp

Re:tss and user space

Post by Kemp »

Which is exactly what I said, only worded more complicated...
Assembler

Re:tss and user space

Post by Assembler »

oh, i know that's what u said but i just wanted to make it more clearer for him.
Kemp

Re:tss and user space

Post by Kemp »

so "p->whatever" equals "(*p).whatever" because the "." is higher than "*"
To be fair, that was something I didn't mention (though I didn't go into pointer details).

A * before a pointer name dereferences the pointer (giving you the variable, or more accurately the memory location, it is pointing at). So for instance:

Code: Select all

char foo = 'A';
char *pChar = foo;
Would create a variable called foo that contains a char and a pointer called pChar that points to this variable.

Code: Select all

(*pChar) = 'B';
Would set the variable that pChar points to (foo) to 'B'.

Conversely, an & before the variable name gives the address of the variable (essentially creating a pointer on the fly), in this case

Code: Select all

&foo
would give you a pointer to foo.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:tss and user space

Post by Colonel Kernel »

Kemp wrote:

Code: Select all

char foo = 'A';
char *pChar = foo;
I see a bogon. Did you mean this?

Code: Select all

char foo = 'A';
char *pChar = &foo;
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:tss and user space

Post by kataklinger »

Probably he wanted to write the secon one, first one won't even compile and has no sense :)
Kemp

Re:tss and user space

Post by Kemp »

Yeah, sorry about that one, of course I meant &foo :P
JAAman

Re:tss and user space

Post by JAAman »

@colonel kernel

the former, for each task, the kernel stack is mapped to the same place

for thread switches, some of the address space should be switched anyway (imho), however, if you didn't want to do any switching, you could change SS:ESP0 only for thread switches, but not task switches (you have to handle them differently anyway, just change SS:ESP0 instead of CR3 for a thread switch)

really haven't desided how to handle threads yet myself, still thinking about a few things, but i will be changing at least part of the address space, prob including the kernel stack
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:tss and user space

Post by kataklinger »

But address space switching is expensive operations, and I think that's way they call threads light-weight processes, because you they don't have separate address space
JAAman

Re:tss and user space

Post by JAAman »

no, full address space switching is expensive, you can also switch only a few pages (the kernel stack, processID, etc) in fact i believe this is quite common way to handle it -- iirc many systems do this with the primary stack as well

switching pages is expensive, however it is also quite possible to implement threads as completely separate processes also (which i have actually considered myself, but i might not) just COW everything and you have a separate thread in a separate process, which actually makes a lot of sence from a security point (protecting threads from each other)
GLneo

Re:tss and user space

Post by GLneo »

ok i know i have a bad limit but how do i change that???, here some code if it helps:

Code: Select all

stack_data_t *schedule(stack_data_t *regs)
{
    cur_task_time_equ(get_pri_time(cur_task_pri()));
    rrq[front].stack = regs;
    front_to_end();
    TSS.esp0 = (int)rrq[front].stack;
    return (stack_data_t *)TSS.esp0;
}

stack_data_t *task_timer_c(stack_data_t *regs)
{
    clock();
//    (void)inport(0x60);
    outport(0x20, 0x20);
    if(cur_task_time() > 0)
    {
        dec_cur_task_time();
        return regs;
    }
    else
        return schedule(regs);
}

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++;
}

void fill_tss()
{
    TSS.ss0 = 0x10;
    TSS.bitmap = 0xFFFF;
}    

void start_sys()
{
    make_task(3, "KERNEL", task0, 0);
    make_task(3, "task0", task0, 3);
    make_task(3, "task1", task1, 3);
    fill_tss(); // fil the struct
    set_a_gdt(5, (unsigned long)&TSS, sizeof(TSS), 0x89, 0xCF); // put a pointer in GDT
    setup_tss(); // put pointer to GDT entery in cpu
    set_a_idt(32, (unsigned)task_timer, 0x08, 0x8E); // redirect timer
}
see anything???, thx

p.s. i know what -> and . do, i just couldn't remember which was which :)
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:tss and user space

Post by kataklinger »

Wrong part of code.

Send code for: set_a_gdt() & where do you load GDTR.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:tss and user space

Post by Colonel Kernel »

JAAman wrote: no, full address space switching is expensive, you can also switch only a few pages (the kernel stack, processID, etc) in fact i believe this is quite common way to handle it -- iirc many systems do this with the primary stack as well
By "primary stack", you mean user-mode stack, right? Which OSes that support multi-threading have every user-mode stack at the same virtual address...?

The only case I know of where a thread has its own private pages would be thread-local storage. You can wrap access to thread-local storage behind a few system calls, which means you wouldn't have to switch those pages if the calls were never made. IMO it doesn't make sense to flip pages on every thread switch -- this negates some of the performance benefit of multithreading.
switching pages is expensive, however it is also quite possible to implement threads as completely separate processes also (which i have actually considered myself, but i might not) just COW everything and you have a separate thread in a separate process, which actually makes a lot of sence from a security point (protecting threads from each other)
You're describing classic UNIX processes and fork(). This is not the same as multi-threading, which by definition involves supporting multiple threads per address space. Forked processes do not really share any address space since a write to memory by one process will not be visible to the other process.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
Post Reply