Hm, mal schauen. Also ich hab natürlich noch viel mehr gefunden, was da raus kann. Ohne jetzt tief in deinem Code bohren zu wollen, hab ich einfach mal meine Entfernen-Taste etwas strapaziert und Funktion-/Block-/Zeilenweise deinen Code gelöscht. Deine main-Methode ist ein 10-Zeiler und kernel.asm ist auch nur noch ein Schatten seiner selbst.
Also ich habs soweit reduziert, dass für mich das fork() als der Übeltäter aussieht. Im Kernel forkt man nicht. Das macht auch irgendwie keinen Sinn. Ich sehe da außerdem nicht, wo du den Stack kopierst. Das kernel_directory->tables == src->tables ist auch falsch, weil die CPU in deinem aktuellen Page Directory das Dirty Flag setzen kann. (Oder wie auch immer das heißt.)
Im allgemeinen ist fork() sowieso zu kompliziert. Ein create_task tuts auch. (Erstellt einen neuen Task, für den nur der Einsprungspunkt vorgegeben ist, nicht der ganze Prozess)
Bei mir funktionieren folgende Änderungen (an 36n.zip):
ckernel.c
#include "os.h"
#include "kheap.h"
#include "task.h"
extern page_directory_t* current_directory;
extern task_t* current_task;
extern tss_entry_t tss_entry;
extern ULONG read_eip();
void moo()
{
while(1) printformat("MOO %d", getpid()); // <-- kuh
}
void baa()
{
while(1) printformat("BAA %d", getpid()); // <- schaf
}
int main()
{
printformat("Welcome to PrettyOS 0.07\n");
// GDT, IDT, ISRS, IRQ, timer, keyboard, paging, enable interrupts, RAM disk, multitasking
gdt_install();
idt_install();
isrs_install();
irq_install();
initODA();
timer_install();
keyboard_install();
sti();
paging_install();
tasking_install();
create_task(moo);
create_task(baa);
pODA->ts_flag = 1;
while(1) printformat("%d", getpid());
return 0;
}
task.c neue Funktion:
extern void irq_tail();
void create_task(void *entry)
{
task_t* parent_task = (task_t*)current_task;
page_directory_t* directory = clone_directory(current_directory);
task_t* new_task = (task_t*)k_malloc(sizeof(task_t),0,0);
new_task->id = next_pid++;
new_task->page_directory = directory;
new_task->kernel_stack = k_malloc(KERNEL_STACK_SIZE,1,0)+KERNEL_STACK_SIZE;
new_task->next = 0;
task_t* tmp_task = (task_t*)ready_queue;
while (tmp_task->next)
tmp_task = tmp_task->next;
tmp_task->next = new_task; // ... and extend it
unsigned int *kernel_stack = (unsigned int*)new_task->kernel_stack;
//*(--kernel_stack) = 0x23; // ss
//*(--kernel_stack) = USER_STACK_VIRT + USER_STACK_SIZE - 0x4;
*(--kernel_stack) = 0x0202; // eflags = interrupts aktiviert und iopl = 0
*(--kernel_stack) = 0x08; // cs
*(--kernel_stack) = (unsigned int)entry; // eip
*(--kernel_stack) = 0; // interrupt nummer
*(--kernel_stack) = 0; // error code
// general purpose registers
//*(--kernel_stack) = 0; // eins von denen ist esp
*(--kernel_stack) = 0;
*(--kernel_stack) = 0;
*(--kernel_stack) = 0;
*(--kernel_stack) = 0;
*(--kernel_stack) = 0;
*(--kernel_stack) = 0;
*(--kernel_stack) = 0;
// segment registers
*(--kernel_stack) = 0x10;
*(--kernel_stack) = 0x10;
*(--kernel_stack) = 0x10;
*(--kernel_stack) = 0x10;
new_task->ebp = 0xd00fc0de;
new_task->esp = (unsigned int)kernel_stack;
new_task->eip = irq_tail;
}
*hust* Stackaufbau aus tyndur ^^
In isr.asm in irq_common_stub vor das mov esp, eax
global irq_tail
irq_tail:
Edit: Sorry, dass ich schon wieder eine neue Funktion/Methode vorschlage. Aber beim OS-Dev in dem Stadium ist der Weg das Ziel.