Task Management
TilekarOS supports preemptive multitasking for both kernel and user-mode tasks.
1. Creating a Kernel Task
Kernel tasks run with full privileges (Ring 0) and share the kernel's address space.
/**
* task_create - Creates a new kernel task.
* @entry: The entry point function for the task.
* @privilege_level: 0 for kernel.
*/
task_t* task = task_create(my_kernel_function, 0);
What happens:
- A unique Task ID (TID) is assigned.
- A 4KB kernel stack is allocated.
- The task is added to the circular ready queue.
- It will begin execution from
my_kernel_functionwhen scheduled.
2. Creating a User Task
User tasks run with restricted privileges (Ring 3) in their own isolated virtual address space.
Why User Tasks?
In TilekarOS, user tasks provide Fault Isolation and Security:
- Protection: A bug in a user task (like a null pointer dereference) will only crash that task, not the whole kernel.
- Controlled Access: User tasks must go through a formal System Call interface to perform privileged actions like writing to the terminal or managing files.
- Address Space Isolation: Each user task gets its own Page Directory, meaning
0x08048000points to different physical memory for every process.
Example: Defining and Launching a User Task
-
Define the code (typically in an assembly file):
-
Launch from the kernel:
Implementation Details:
- Isolated Address Space:
task_create_usercreates a new page directory for the task. - Memory Mapping:
- The user's code is mapped at
0x08048000in its virtual address space. - A 4KB user stack is mapped at
0xB0000000. - Privilege Transition: The kernel prepares a stack frame and uses the
iretinstruction to jump to the code at0x08048000while dropping the CPU to Ring 3. - Protection: User tasks cannot execute privileged instructions (like
hlt) or access kernel memory (> 0xC0000000). They must use theint 0x80interface for all system services.
3. Task Lifecycle
- Ready: Task is waiting for its turn in the scheduler.
- Running: Task currently owns the CPU.
- Exiting: When a task returns from its entry point,
task_exit()is called automatically. - Zombie: Exited tasks remain as "zombies" until the scheduler cleans up their allocated memory (stack and
task_tstructure).
4. Scheduling
The scheduler uses a Round-Robin algorithm triggered by the Timer (PIT) every 10ms.
- Yielding: A task can voluntarily give up the CPU by calling
task_yield(). - Preemption: The timer interrupt forces a context switch if the current task's time slice has expired.