I've asked a lot of question about context switching, but this is not about context switching. I'm having a conceptual problem about multitasking in my os.
I've *finally* finished context switching, and it works really good. This is the stack setup of tasks:
[args]
[eip (address of task)]
[eip (address of start_task)]
[eax]
[ebx]
[ecx]
[edx]
[ebp]
[esi]
[edi]
But what should "start_task" do? My implementation allocates the CPL=3 stack (if task->type isn't TASK_TYPE_KERNEL) of task, sets the IOPL and VM (if task->type is TASK_TYPE_V8086) and does an iret. (again if task->type isn't TASK_TYPE_KERNEL)
Also I noticed some problems:
start_task doesn't return to its caller, so return eip isn't in the stack as C expects. This means values of arguments in void start_task(uint32_t address_of_task, uint32_t args) will be wrong as address_of_task will be considered as return eip, address_of_task will point to args and args will point args + 4 in stack.
I fixed that rewriting start_task in asm, but same problem applies to tasks again.
What happens if I do that in a user program?
Code: Select all
void task1 (void* args)
{
printf("Hello from task1! arg is : %X\n", (uint32_t)*args);
exit();
}
int main(int argc, char** argv)
{
printf("Hello from main, now I will create a task!\n");
uint32_t arg = 0xDEADBEEF;
pid_t pid = add_task(task1, (void*)&arg, PRIORITY_LOW, "task1"); //My os doesn't have fork, instead it uses its own task creating system
return 0;
}
If I load an elf file directly, there is no problem as _start is written in assembly. Problem occurs when I add a C function directly(without any assembly entry) as a task.
For example I have a "task monitor" task runs in kernel that autonomously manages tasks. In kernel_idle I create it with:
Code: Select all
void task_monitor(void* args)
{
for (;;)
{
...
}
}
void kernel_idle()
{
...
kadd_task(create_task_struct(task_monitor, TASK_TYPE_KERNEL, args), PRIORITY_MID, "Task Monitor");
...
}
So tasks have that in the stack when they start running (after start_task):
[args]
But they should have these in the stack if I start a C function directly as a task:
[args]
[return eip]
or maybe:
[args]
[return eip]
[ebp (for stack frame)]
What should I do?
Thanks in advance.