Bad version (?)
This commit is contained in:
@ -1,7 +1,49 @@
|
||||
; tasking.asm
|
||||
;
|
||||
; tasking-asm.asm
|
||||
;
|
||||
; Created on: Sep 6, 2011
|
||||
; Author: Tiberiu
|
||||
;
|
||||
|
||||
bits 32
|
||||
|
||||
global TaskReadEip
|
||||
TaskReadEip:
|
||||
global PagingCopyPagePhysical
|
||||
PagingCopyPagePhysical:
|
||||
push ebx
|
||||
pushf
|
||||
cli
|
||||
|
||||
mov ebx, [esp+12]
|
||||
mov ecx, [esp+16]
|
||||
|
||||
; Disable paging
|
||||
mov edx, cr0
|
||||
and edx, 0x7fffffff
|
||||
mov cr0, edx
|
||||
|
||||
; copy
|
||||
mov edx, 1024
|
||||
|
||||
.loop:
|
||||
mov eax, [ebx]
|
||||
mov [ecx], eax
|
||||
add ebx, 4
|
||||
add ecx, 4
|
||||
dec edx
|
||||
jnz .loop
|
||||
|
||||
; reenable paging
|
||||
mov edx, cr0
|
||||
or edx, 0x80000000
|
||||
mov cr0, edx
|
||||
|
||||
; return
|
||||
popf
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
|
||||
global TaskingReadEip
|
||||
TaskingReadEip:
|
||||
pop eax
|
||||
jmp eax
|
||||
|
@ -1,107 +1,141 @@
|
||||
/*
|
||||
* tasking-multi.c
|
||||
*
|
||||
* Created on: Sep 8, 2011
|
||||
* Created on: Sep 7, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <tasking.h>
|
||||
#include <memory-add.h>
|
||||
#include <debugio.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Task* TaskList;
|
||||
Task* CurrentTask;
|
||||
uint32 NextPid = 1;
|
||||
volatile Task *CurrentTask;
|
||||
volatile Task *TaskQueue;
|
||||
volatile uint32 NextPid = 1;
|
||||
|
||||
void TaskSwitch (_RegsStack32* regs)
|
||||
void TaskingInitialize()
|
||||
{
|
||||
MagicBreakpoint();
|
||||
// Stop interrupts
|
||||
asm volatile ("cli");
|
||||
|
||||
if (!TaskList) return;
|
||||
// Relocate stack
|
||||
TaskingMoveStack(0xE0000000, 0x4000);
|
||||
|
||||
uint32 eip = TaskReadEip();
|
||||
if (eip == 0xABCDEF) return;
|
||||
// Set up first task (kernel)
|
||||
CurrentTask = TaskQueue = (Task*) kmalloc(sizeof(Task));
|
||||
CurrentTask->Pid = NextPid ++;
|
||||
CurrentTask->Esp = CurrentTask->Ebp = CurrentTask->Eip = 0;
|
||||
CurrentTask->Pd = CurrentDirectory;
|
||||
CurrentTask->Next = NULL;
|
||||
|
||||
// Save context
|
||||
asm volatile ("mov %%esp, %0" : "=r"(CurrentTask->Esp));
|
||||
asm volatile ("mov %%ebp, %0" : "=r"(CurrentTask->Ebp));
|
||||
CurrentTask->Eip = eip;
|
||||
// Reenable interrupts
|
||||
asm volatile ("sti");
|
||||
|
||||
// Next task
|
||||
CurrentTask = (!CurrentTask->Next) ? TaskList : CurrentTask->Next ;
|
||||
|
||||
// Switch context
|
||||
PagingSwitchDirectory(CurrentTask->Pd);
|
||||
|
||||
// Prepare for jump
|
||||
asm volatile (""
|
||||
"mov %0, %%ebp; "
|
||||
"mov %1, %%esp; "
|
||||
"mov %2, %%ecx; "
|
||||
"mov $0xABCDEF, %%eax; "
|
||||
"jmp *%%ecx; "
|
||||
: : "r"(CurrentTask->Ebp), "r"(CurrentTask->Esp), "r"(CurrentTask->Eip)
|
||||
: "eax", "ecx");
|
||||
Log("Tasking", "Initialized, currenttask: pid=%u esp=%x ebp=%x eip=%x Pd=%x Next=%x\n", CurrentTask->Pid,
|
||||
CurrentTask->Esp, CurrentTask->Ebp, CurrentTask->Eip, CurrentTask->Pd, CurrentTask->Next);
|
||||
}
|
||||
|
||||
// Fallback for new tasks
|
||||
void TaskEnd ()
|
||||
int32 Fork()
|
||||
{
|
||||
// Find parent of current task
|
||||
if (CurrentTask->Pid == TaskList->Pid) TaskList = TaskList->Next;
|
||||
asm volatile ("cli");
|
||||
|
||||
else {
|
||||
Task* t = TaskList;
|
||||
while (t->Next && t->Next->Pid != CurrentTask->Pid) t = t->Next;
|
||||
Task* Parent = (Task*) CurrentTask;
|
||||
PageDirectory* Dir = PagingCloneDirectory(CurrentDirectory);
|
||||
|
||||
t->Next = CurrentTask->Next;
|
||||
// Create a new process
|
||||
Task* n = (Task*)kmalloc(sizeof(Task));
|
||||
n->Pid = NextPid++;
|
||||
n->Esp = n->Ebp = 0;
|
||||
n->Eip = 0;
|
||||
n->Pd = Dir;
|
||||
n->Next = 0;
|
||||
|
||||
// Add it at the end of the queue
|
||||
Task* temp = (Task*) TaskQueue;
|
||||
while (temp->Next) temp = temp->Next; // Find end of queue
|
||||
temp->Next = n; // Add it
|
||||
|
||||
// Read eip
|
||||
uint32 eip = TaskingReadEip();
|
||||
|
||||
// We could be the parent
|
||||
if (CurrentTask == Parent)
|
||||
{
|
||||
uint32 esp, ebp;
|
||||
asm volatile ("mov %%esp, %0" : "=r"(esp));
|
||||
asm volatile ("mov %%ebp, %0" : "=r"(ebp));
|
||||
n->Esp = esp;
|
||||
n->Ebp = ebp;
|
||||
n->Eip = eip;
|
||||
|
||||
asm volatile ("sti");
|
||||
return n->Pid;
|
||||
}
|
||||
|
||||
// Free allocated space
|
||||
kfree((void*)CurrentTask->StackLowerBase);
|
||||
kfree(CurrentTask);
|
||||
|
||||
// Wait for next task
|
||||
for (;;) ;
|
||||
// Or the child
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void TaskCreate (void (*func)())
|
||||
void TaskingScheduler()
|
||||
{
|
||||
// Create a new task
|
||||
Task* t = kmalloc(sizeof(Task));
|
||||
|
||||
// Set up data
|
||||
t->StackLowerBase = (uint32) kmalloc(0x1000); // Allocate some space for new stack
|
||||
t->StackUpperBase = t->StackLowerBase + 0x1000;
|
||||
t->Next = NULL;
|
||||
t->Pd = KernelDirectory;
|
||||
t->Pid = NextPid++;
|
||||
|
||||
// Set up stack
|
||||
/*memset(&t->Regs, 0, sizeof(_RegsStack32));
|
||||
t->Regs.ebp = t->StackUpperBase;
|
||||
t->Regs.esp = (t->StackUpperBase - 0x4 - sizeof(_RegsStack32));
|
||||
t->Regs.useresp = t->StackUpperBase - 0x4;
|
||||
t->Regs.eip = (uint32) func;
|
||||
*(uint32 *) (t->Regs.esp) = (uint32) TaskEnd; // Fallback function
|
||||
t->Initialized = 0;
|
||||
|
||||
// Read eflags
|
||||
asm volatile ("pushf; pop %0" : "=r"(t->Regs.eflags));*/
|
||||
|
||||
// Add the task to the list
|
||||
Task* last = TaskList;
|
||||
while (last && last->Next) last = last->Next;
|
||||
if (last) last->Next = t;
|
||||
// For now, just switch tasks
|
||||
TaskingSwitch();
|
||||
}
|
||||
|
||||
void TaskInitialize()
|
||||
void Func()
|
||||
{
|
||||
Task* t = kmalloc(sizeof(Task));
|
||||
|
||||
t->Pid = NextPid++;
|
||||
t->Pd = KernelDirectory;
|
||||
t->Next = NULL;
|
||||
|
||||
TaskList = CurrentTask = t;
|
||||
}
|
||||
|
||||
void TaskingSwitch()
|
||||
{
|
||||
// Make sure tasking is initialized, or there are at least 2 processes running
|
||||
if (!CurrentTask) return;
|
||||
|
||||
// Save esp & epb
|
||||
uint32 esp, ebp, eip;
|
||||
asm volatile("mov %%esp, %0" : "=r"(esp));
|
||||
asm volatile("mov %%ebp, %0" : "=r"(ebp));
|
||||
eip = TaskingReadEip();
|
||||
|
||||
// Have we just switched tasks?
|
||||
if (eip == 0xABCDE) return;
|
||||
|
||||
// No? Switch
|
||||
// Save stack address and current instruction pointer
|
||||
CurrentTask->Eip = eip;
|
||||
CurrentTask->Esp = esp;
|
||||
CurrentTask->Ebp = ebp;
|
||||
|
||||
//Log("Tasking", "Saved eip=%x esp=%x ebp=%x\n", eip, esp, ebp);
|
||||
|
||||
CurrentTask = CurrentTask ->Next; // Switch task
|
||||
if (!CurrentTask) CurrentTask = TaskQueue; // End of queue? Start over
|
||||
|
||||
// Read registers
|
||||
eip = CurrentTask->Eip;
|
||||
esp = CurrentTask->Esp;
|
||||
ebp = CurrentTask->Ebp;
|
||||
|
||||
//Log("Tasking", "Loaded eip=%x esp=%x ebp=%x", eip, esp, ebp);
|
||||
|
||||
CurrentDirectory = CurrentTask->Pd;
|
||||
MagicBreakpoint();
|
||||
|
||||
// Put data in registers
|
||||
asm volatile (" "
|
||||
"cli;"
|
||||
"mov %0, %%ecx;"
|
||||
"mov %1, %%esp;"
|
||||
"mov %2, %%ebp;"
|
||||
"mov %3, %%cr3;"
|
||||
"mov $0xABCDE, %%eax;"
|
||||
"sti;"
|
||||
"jmp *%%ecx"
|
||||
: : "r"(eip), "r"(esp), "r"(ebp), "r"(CurrentDirectory->PhysicalAddr));
|
||||
}
|
||||
|
||||
int32 GetPid()
|
||||
{
|
||||
return CurrentTask->Pid;
|
||||
}
|
||||
|
51
Kernel/tasking/tasking-stack.c
Normal file
51
Kernel/tasking/tasking-stack.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* tasking-stack.c
|
||||
*
|
||||
* Created on: Sep 7, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
|
||||
#include <memory-add.h>
|
||||
uint32 InitialStack;
|
||||
|
||||
void TaskingSetInitialStack(uint32 addr)
|
||||
{
|
||||
InitialStack = addr;
|
||||
}
|
||||
|
||||
void TaskingMoveStack (uint32 newstart, uint32 size)
|
||||
{
|
||||
|
||||
uint32 i;
|
||||
for (i = newstart; i >= newstart-size; i-= 0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, CurrentDirectory), 0, 1);
|
||||
|
||||
// Flush TLB by rewriting cr3
|
||||
uint32 t;
|
||||
asm volatile ("mov %%cr3, %0" : "=r" (t));
|
||||
asm volatile ("mov %0, %%cr3" : : "r" (t));
|
||||
|
||||
// Read old esp, ebp regs
|
||||
uint32 oldStackPointer, oldBasePointer;
|
||||
asm volatile ("mov %%esp, %0" : "=r"(oldStackPointer));
|
||||
asm volatile ("mov %%ebp, %0" : "=r"(oldBasePointer));
|
||||
|
||||
uint32 offset = newstart - InitialStack;
|
||||
uint32 newStackPointer = oldStackPointer + offset;
|
||||
uint32 newBasePointer = oldBasePointer + offset;
|
||||
|
||||
// Copy stack content
|
||||
memcpy((void*)newStackPointer, (void*)oldStackPointer, InitialStack-oldStackPointer);
|
||||
|
||||
// (Attempt to) change EBP addresses in new stack
|
||||
for (i = newstart; i > newstart - size; i-=4)
|
||||
{
|
||||
uint32 *temp = (uint32*)i;
|
||||
if (oldStackPointer < *temp && *temp < InitialStack)
|
||||
*temp += offset;
|
||||
}
|
||||
|
||||
// Set stack pointers to new stack
|
||||
asm volatile ("mov %0, %%esp" : : "r" (newStackPointer));
|
||||
asm volatile ("mov %0, %%ebp" : : "r" (newBasePointer));
|
||||
}
|
Reference in New Issue
Block a user