memcpy(tsk, current, sizeof(task_union));
+ assert(tsk->magic == TASK_MAGIC);
+
+ tsk->state = TASK_INITING;
+
+ INIT_LIST_HEAD(&tsk->list);
+ unsigned long iflags;
+ irq_save(iflags);
+ list_add(&tsk->list, &all_tasks);
+ irq_restore(iflags);
+
tsk->cr3 = va2pa((unsigned long)alloc_one_page(0));
assert(tsk->cr3 != 0);
#endif
}
+ pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1;
+
+ // printd("child regs: %x %x\n", child_regs, regs);
+ memcpy(child_regs, regs, sizeof(*regs));
+
+ if (flags & FORK_KRNL) {
+ strcpy(tsk->name, (char *)(child_regs->eax));
+ child_regs->eax = 0;
+ } else {
+ child_regs->eip = *((unsigned long *)&&fork_child);
+ }
+
+ // 这一句已经不需要了,通过fork_child已经能给子进程返回0了
+ // child_regs->eax = 0;
+
tsk->pid = get_next_pid();
tsk->ppid = current->pid;
tsk->priority = current->priority;
tsk->need_resched = 0;
tsk->sched_cnt = 0;
tsk->sched_keep_cnt = 0;
- assert(tsk->magic == TASK_MAGIC);
- pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1;
-
- printd("child regs: %x %x\n", child_regs, regs);
- memcpy(child_regs, regs, sizeof(*regs));
-
- tsk->esp0 = TASK_SIZE + (unsigned long)tsk;
+ // for switch_to
+ tsk->eip = child_regs->eip;
tsk->esp = (unsigned long)child_regs;
- tsk->eip = (unsigned long)ret_from_fork_user;
- if (flags & FORK_KRNL) {
- strcpy(tsk->name, (char *)(child_regs->eax));
- tsk->eip = (unsigned long)ret_from_fork_krnl;
- }
-
- child_regs->eax = 0;
- child_regs->eflags |= 0x200; // enable IF
+ tsk->esp0 = TASK_SIZE + (unsigned long)tsk;
printd("task %08x child_regs esp %08x esp0 %08x\n", tsk, tsk->esp, tsk->esp0);
- tsk->state = TASK_INITING;
-
- INIT_LIST_HEAD(&tsk->list);
- unsigned long iflags;
- irq_save(iflags);
- list_add(&tsk->list, &all_tasks);
- irq_restore(iflags);
-
tsk->state = TASK_READY;
return (int)tsk->pid;
+
+fork_child:
+ return 0;
}
int sysc_fork(pt_regs_t regs) { return do_fork(®s, 0); }
/*
*--------------------------------------------------------------------------
* File Name: syscall.S
- *
+ *
* Description: none
- *
- *
+ *
+ *
* Author: Zhao Yanbai [zhaoyanbai@126.com]
- *
+ *
* Version: 1.0
* Create Date: Tue Feb 10 13:20:33 2009
* Version: 2.0
* Last Update: Wed Feb 10 23:36:34 2010
* Version: 3.0
* Last Update: Fri May 2 00:21:37 2014
- *
+ *
*--------------------------------------------------------------------------
*/
.code32
.text
.global syscall_entry
-.global ret_from_fork_user
.global ret_from_fork_krnl
.extern reenter
//.global syscall_exit
syscall_entry:
#if FIX_SYSENTER_ESP_MODE
- movl (%esp),%esp
+ movl (%esp),%esp
#endif
-
+
// sysenter have cleared IF, and sysexit will not set IF.
sti
// 保存返回值
movl %eax, PT_REGS_EAX(%esp)
-ret_from_fork_user:
RESTORE_REGS
// 内核线程fork出路
ret_from_fork_krnl:
RESTORE_REGS
- addl $12, %esp
- popfl
- addl $8, %esp
+ addl $12, %esp // 0 EIP CS
+ popfl // EFLAGS
+ addl $8, %esp // ESP SS
call *%edx
- addl $4, %esp
- # 还没有实现do_exit
- #call do_exit
+ addl $4, %esp // CALL PUSH EIP
+
+ // TODO
+ // add exit here
+
+
-
-
# this routine should be load align by PAGE_SIZE
# this page is shared by the kernel and userspace
popl %ebp;
popl %edx;
popl %ecx;
- ret
\ No newline at end of file
+ ret
int do_fork(pt_regs_t *regs, unsigned long flags);
int sysc_wait(uint32_t ticks);
+#define get_eflags(x) __asm__ __volatile__("pushfl; popl %0;" : "=g"(x)::"memory")
+
void kernel_task(char *name, void *entry) {
pt_regs_t regs;
regs.ss = SELECTOR_KRNL_DS;
regs.fs = SELECTOR_KRNL_DS;
regs.gs = SELECTOR_KRNL_DS;
+ get_eflags(regs.eflags);
int pid = do_fork(®s, FORK_KRNL);