kernel stack location

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.
Post Reply
dawix
Posts: 15
Joined: Thu Oct 20, 2011 10:10 pm

kernel stack location

Post by dawix »

Hi,
i have my kernel loaded at 0xC0000000, when my kernel starts it uses a temporary stack in the bss section of 4096 bytes, it then enters in protected mode starting using the user mode stack at 0xBFFF0000, when it forks for the first:
all the kernel code pages are linked
all the user mode pages (under 0xC0000000) are copied in new frames.
Everithing works but...what about the kernel stack i don't want a shared one i want that every process have his kernel stack (it's correct?! )
So where to put the kernel stack?! i have to copy the content of the temporary one in a new frame before the fork so that when a fork happens all the processes have the same virtual stack address? because if i don't copy it before the first fork the first forked process must be treated in a different way than the 2nd , 3rd, etc forked tasks.
I don't know if it's clear but if it's not the kernel of the question is: TELL ME ABOUT THE KERNEL STACK :D
AndrewBuckley
Member
Member
Posts: 95
Joined: Thu Jan 29, 2009 9:13 am

Re: kernel stack location

Post by AndrewBuckley »

your trying to give user processes the kernel stack? why?
dawix
Posts: 15
Joined: Thu Oct 20, 2011 10:10 pm

Re: kernel stack location

Post by dawix »

no...every process has it's own global table directory. This directory maps:
0x00000000:0xBFFFFFFFF -> user space
0xC0000000:0xFFFFFFFFF -> kernel space
in the directory all the kernel space pages are linked to the first process kernel code, all the rest is copied. Now i want to copy the kernel stack as well so every process can do a syscall using the shared code and heap but using it's own copied kernel stack.
I heard the every task must mantain a user stack and a kernel stack.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: kernel stack location

Post by egos »

You can map all kernel stacks into kernel space or remap each stack at same address when task switching occurs. I use first variant because I store thread structure in the stack region.
If you have seen bad English in my words, tell me what's wrong, please.
dawix
Posts: 15
Joined: Thu Oct 20, 2011 10:10 pm

Re: kernel stack location

Post by dawix »

Ok you map the kernel stack in the kernel space but...when you fork a new process. you don' link the father kernel stack right? you copy it so the child process just have linked (in it's page directory/table) the kernel code and heap? for the new kernel stack you allocate a new frame and copy in it the original one content!? tell me if i'm wrong...
thanks
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: kernel stack location

Post by egos »

When I create starting application thread I just allocate a new stack frame, map memory into it, write start stack frame and thread structure to the top, write executable file name and parameter string to the bottom, insert thread in the run queue. After thread will take control the InitFirstUserThread routine will be executed.
If you have seen bad English in my words, tell me what's wrong, please.
dawix
Posts: 15
Joined: Thu Oct 20, 2011 10:10 pm

Re: kernel stack location

Post by dawix »

ok i solved in this way, maybe it's the linux way because i saw in the linux kernel internals book that is implemented like this:
every process have his kernel stack... the kernel mantains a series of task struct associated with the kernel stack that the process use, like this:

Code: Select all

 
union {
    task_t task;
    uint kstack[1024];
} init_task;
for every context switch i update the unique tss with the current process kstack address so when is in user mode and an interrupt happens it start using it's kernel stack. In this way is possible to have nested interrupts and a preemptive kernel.
Thanks God :D
dawix
Posts: 15
Joined: Thu Oct 20, 2011 10:10 pm

Re: kernel stack location

Post by dawix »

ah the tss is updated in this way:

Code: Select all

current_task = current_task->next;
tss[1] = current_task->stacktop;                   // the ESP0 field in the tss is updated with a correct value
the stacktop value is assigned for the 1st process statically as:

Code: Select all

union {
    task_t task;
    uint kstack[1024]
} start_task;
...
....
start_task->stacktop = &start_task[1024]
for the other tasks in the fork function like this:

Code: Select all

task_t *newtask = (task_t *) malloc(4096);
newtask->stacktop = ((uint)newtask +4096);
newtask->eip = ret_from_syscall;
newtask->esp = newtask->stacktop  - (14*4); // minus all the values pushed in the stack by the "syscall" asm routine before calling the "syscall_handler" and by "int 0x80" automatically, so that returning in "ret_from_syscall" pops the values correcly )
memcopy(newtask + sizeof(task_t), current + sizeof(task_t), 4096-sizeof(task_t))    // this copies the values in the stack used by "ret_from_syscall"
and this is the syscall asm part

Code: Select all

syscall:
    pusha                    ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax

    mov ecx, ds               ; Lower 16-bits of eax = ds.
    push ecx                 ; save the data segment descriptor

    mov cx, 0x10  ; load the kernel data segment descriptor
    mov ds, cx
    mov es, cx
    mov fs, cx
    mov gs, cx

    call syscall_handler          ; where the syscall is dispatched depending on eax value
ret_from_isr:
    pop ebx        ; reload the original data segment descriptor
    mov ds, bx
    mov es, bx
    mov fs, bx
    mov gs, bx

    popa           ; Pops edi,esi,ebp...
    iret              ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
so actually the ony things that the current process must copy in the new process stack is the value popped in ebx, the values popped by popa and the stuff used by iret to return in usermode [-o<
Post Reply