syscalls: hopefully fix fork syscall

This commit is contained in:
2025-11-23 15:23:38 +03:00
parent c8036a9aae
commit a358d0b1ac
3 changed files with 52 additions and 22 deletions
+1 -7
View File
@@ -33,9 +33,6 @@ switchProcess:
trapret:
; Восстанавливаем общие регистры из trap frame
;popal ; edi, esi, ebp, oesp, ebx, edx, ecx, eax
; Восстанавливаем сегментные регистры
pop gs
pop fs
@@ -44,9 +41,6 @@ trapret:
popad
; Пропускаем trapno и err
add esp, 8 ; trapno (4 байта) + err (4 байта)
; Теперь ESP указывает на eip, cs, eflags, esp, ss
; (interrupt and error fields removed from TrapFrame)
iret
+51 -12
View File
@@ -86,8 +86,16 @@ int sys_fork(TrapFrame *tf)
destroy_page_dir(new_pd);
return -1;
}
Process* child = (Process*)((uint32_t)p_physical + 0xC0000000);
map_page(p_physical, (void*)child, PAGE_PRESENT | PAGE_RW);
// Map the Process structure page into the CHILD's page directory
map_page_in_directory(new_pd, p_physical, (void*)phys_to_virt((uint32_t)p_physical), PAGE_PRESENT | PAGE_RW);
// Also map the same page into the current (parent) page directory so the
// kernel can access and initialize it now via the kernel virtual mapping.
map_page(p_physical, (void*)phys_to_virt((uint32_t)p_physical), PAGE_PRESENT | PAGE_RW);
// Get virtual address for initialization (kernel mapping) and clear it
Process* child = (Process*)phys_to_virt((uint32_t)p_physical);
memset(child, 0, sizeof(Process));
child->pid = ++pid_counter;
@@ -102,27 +110,58 @@ int sys_fork(TrapFrame *tf)
debug_log("Failed to allocate kernel stack\n");
return -1;
}
child->kstack = (char*)((uint32_t)kstack_physical + 0xC0000000);
map_page(kstack_physical, child->kstack, PAGE_PRESENT | PAGE_RW);
// Map the kernel stack in the CHILD's page directory
map_page_in_directory(new_pd, kstack_physical, (void*)phys_to_virt((uint32_t)kstack_physical), PAGE_PRESENT | PAGE_RW);
// Also map kernel stack into the current PD so the kernel can write to it
map_page(kstack_physical, (void*)phys_to_virt((uint32_t)kstack_physical), PAGE_PRESENT | PAGE_RW);
child->kstack = (char*)phys_to_virt((uint32_t)kstack_physical);
debug_log("child->kstack: %X\n", child->kstack);
child->kstack_top = (uint32_t)child->kstack + KSTACKSIZE;
uint8_t* sp = (uint8_t*)(child->kstack + KSTACKSIZE);
// 1. Place the TrapFrame on the child's stack.
sp -= sizeof(TrapFrame);
child->tf = (TrapFrame*)sp;
// Debug: print parent's trapframe before copying
debug_log("parent tf @ %X\n", tf);
debug_log("parent tf->eip=%X cs=%X eflags=%X user_esp=%X user_ss=%X\n",
tf->eip, tf->cs, tf->eflags, tf->usermode_esp, tf->usermode_ss);
debug_log("parent tf regs: eax=%X ebx=%X ecx=%X edx=%X edi=%X esi=%X ebp=%X esp=%X\n",
tf->eax, tf->ebx, tf->ecx, tf->edx, tf->edi, tf->esi, tf->ebp, tf->esp);
memcpy(&child->tf->gs, &tf->gs, 12 * sizeof(uint32_t));
uint32_t* parent_cpu_state_ptr = (uint32_t*)&tf->interrupt;
child->tf->eip = parent_cpu_state_ptr[0];
child->tf->cs = parent_cpu_state_ptr[1];
child->tf->eflags = parent_cpu_state_ptr[2];
child->tf->usermode_esp = parent_cpu_state_ptr[3];
child->tf->usermode_ss = parent_cpu_state_ptr[4];
// Copy the trapframe contents from the parent into the child's trapframe
memcpy(child->tf, tf, sizeof(TrapFrame));
/* Copy instruction pointer and segment registers from parent trapframe */
child->tf->eip = tf->eip;
child->tf->cs = tf->cs;
child->tf->eflags = tf->eflags;
child->tf->usermode_esp = tf->usermode_esp;
child->tf->usermode_ss = tf->usermode_ss;
child->tf->eax = 0; // Child returns 0
/* Ensure saved kernel-ESP in the saved-registers block points
to the location right after the saved registers (where the
iret frame starts). popad will restore ESP from this field,
so it must point to the iret frame, not the user-mode ESP. */
child->tf->esp = (uint32_t)child->tf + offsetof(TrapFrame, eip);
child->tf->eax = 0; // Child returns 0
debug_log("Parent returns PID: %X, Child returns 0\n", child->pid);
// Debug: dump important trapframe and stack info for the child
debug_log("child->tf @ %X\n", child->tf);
debug_log("child->tf->eip=%X cs=%X eflags=%X user_esp=%X user_ss=%X\n",
child->tf->eip, child->tf->cs, child->tf->eflags,
child->tf->usermode_esp, child->tf->usermode_ss);
debug_log("child->tf regs: eax=%X ebx=%X ecx=%X edx=%X edi=%X esi=%X ebp=%X esp=%X\n",
child->tf->eax, child->tf->ebx, child->tf->ecx, child->tf->edx,
child->tf->edi, child->tf->esi, child->tf->ebp, child->tf->esp);
debug_log("child->kstack=%X kstack_top=%X kesp=%X\n", child->kstack, child->kstack_top, child->kesp);
sp -= sizeof(Context);
child->context = (Context*)sp;
memset(child->context, 0, sizeof(Context));