I just implemented scheduling in my kernel. I used JamesM's kernel dev tuts to give me an idea of how this works. (Pratically the whole kernel is somewhat based on the tutorial). I pretty much copied his move_stack() function. Now, I tested the scheduler and it gave me a page fault, like you could see on the "What your Os goes carzy..." thread. I debugged it and it revealed that the whole thing crashed because of move_stack(). Here's the code:
Code: Select all
void move_stack(void * new_stack_start, u32int size)
{
u32int i;
for (i = (u32int) new_stack_start;
i >= ((u32int) new_stack_start-size);
i -= 0x1000)
{
alloc_frame( get_page(i, 1, current_directory), 0 /* User mode */, 1 /* Is writable */ );
};
u32int pd_addr;
asm volatile("mov %%cr3, %0" : "=r" (pd_addr));
asm volatile("mov %0, %%cr3" : : "r" (pd_addr));
u32int old_stack_pointer; asm volatile("mov %%esp, %0" : "=r" (old_stack_pointer));
u32int old_base_pointer; asm volatile("mov %%ebp, %0" : "=r" (old_base_pointer));
u32int offset = (u32int)new_stack_start - initial_esp;
u32int new_stack_pointer = old_stack_pointer + offset;
u32int new_base_pointer = old_base_pointer + offset;
memcpy((void*)new_stack_pointer, (void*)old_stack_pointer, initial_esp-old_stack_pointer);
for(i = (u32int)new_stack_start; i > (u32int)new_stack_start-size; i -= 4)
{
u32int tmp = * (u32int*)i;
// If the value of tmp is inside the range of the old stack, assume it is a base pointer
// and remap it. This will unfortunately remap ANY value in this range, whether they are
// base pointers or not.
if (( old_stack_pointer < tmp) && (tmp < initial_esp))
{
tmp = tmp + offset;
u32int *tmp2 = (u32int*)i;
*tmp2 = tmp;
}
};
asm volatile("mov %0, %%esp" : : "r" (new_stack_pointer));
asm volatile("mov %0, %%ebp" : : "r" (new_base_pointer));
};