ICh habe jetzt tausende von Bugs behoben, unter anderem hab ich vergessen, vor der Adresse das CS auf den Stack zu pushen, und ich hab vergessen, dass der Stack nach unten wächst. Er bleibt jetzt bei task_add stehen (ich zeig gleich wo) und springt in den thread rein, weil die funktion zum espschreiben ihre parameter auf den stack bekommt :-@
Ich bräuchte nur eine Möglichkeit, mit inline-assembly t_esp in esp zu schreiben.
task_scheduler wird vom timerint aufgerufen, der den returnwert von task_scheduler in espschreib und dann popa pop ds es fs gs macht.
task.c:
//Implementations
struct task_node* task_init()
{
task_current=kmalloc(sizeof(struct task_node));
if(task_current==0)
return 0;
task_current->prev=0;
task_current->next=0;
task_current->t_task.t_id=0;
task_current->t_task.t_esp=read_esp();
task_current->t_task.t_cr3=read_cr3();
task_current->t_task.t_descriptor="Nanocore";
task_enable=1;
return task_current;
}
unsigned long task_add(unsigned long t_eip, unsigned long t_esp, unsigned long t_id, unsigned long t_cr3, char* descriptor, unsigned short t_cs)
{
task_enable=0;
asm("cli");
printm("nanocore","tasking disabled!");
struct task_node* tnode=0;
tnode=kmalloc(sizeof(struct task_node));
if(tnode==0)
{
nanocore_panic("Could not malloc enough memory!");
return 0;
}
*(unsigned long*)t_esp=t_eip;
unsigned long tmp_esp=read_esp();
write_esp(t_esp);
printm("nanocore","wrote esp");
pushval(t_eip);
asm("pushw %0":"=r"(t_cs));
asm("pushal");
asm("push %ds");
asm("push %es");
asm("push %fs");
asm("push %gs");
tnode->t_task.t_esp=read_esp();
printm("nanocore","second write_esp()"); //<<< das geht noch
write_esp(tmp_esp); //<<<<<<<<<<<<<<<<---------- ERROR
printm("nanocore","wrote esp again!"); //<<< das kommt nicht mehr, stattdessen springt er in den thread, der gerade erstellt wurde und hat die ints aus.,
tnode->t_task.t_id=t_id;
tnode->t_task.t_cr3=t_cr3;
tnode->t_task.t_descriptor=descriptor;
tnode->prev=task_current;
task_attach(tnode);
printm("nanocore","going to enable tasking!");
task_enable=1;
asm("sti");
return;
}
struct task_node* task_last()
{
struct task_node* p=task_current;
while(p->next)
{
p=p->next;
}
return p;
}
struct task_node* task_first()
{
struct task_node* p=task_current;
while(p->prev)
{
p=p->prev;
}
return p;
}
void task_unlink(struct task_node* tnode)
{
if(tnode)
{
if(tnode->next)
tnode->next->prev=tnode->prev;
if(tnode->prev)
tnode->prev->next=tnode->next;
}
return;
}
void task_attach(struct task_node* tnode)
{
task_last()->next=tnode;
return;
}
void task_next()
{
if(task_current->next)
{
task_current=task_current->next;
}
else
{
task_current=task_first();
}
return;
}
unsigned long task_scheduler()
{
if(task_enable)
{
task_store_data(); // Save
task_next(); // All the logic is in there
#ifdef _NANO_DEBUG_
printm("using task",task_current->t_task.t_descriptor);
char esp_d[8];
itoa(esp_d,'x',task_current->t_task.t_esp);
printm("esp",esp_d);
#endif
return task_current->t_task.t_esp;
}
else
{
gemstone_putc('N');
return 0;
}
}
void task_store_data()
{
task_current->t_task.t_esp=read_esp();
task_current->t_task.t_cr3=read_cr3();
return;
}