Skip to content

Commit

Permalink
PIC doesn't work after fork(), reinit PIC to fix
Browse files Browse the repository at this point in the history
thx fleuria
  • Loading branch information
SilverRainZ committed Sep 6, 2015
1 parent ed0656d commit fc0e84c
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 11 deletions.
2 changes: 1 addition & 1 deletion mm/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ pde_t *uvm_copy(pte_t *pgdir, uint32_t size){
printl("uvm_copy: phyaddr: 0x%x -> 0x%x\n", pa, mem);

memcpy((void *)mem, (void *)pa, PAGE_SIZE);
vmm_map(pgd, USER_BASE + i, mem, PTE_W | PTE_U | PTE_P);
vmm_map(pgd, USER_BASE + i, mem, PTE_R | PTE_U | PTE_P); // TODO (?)
}
return pgd;
}
Expand Down
6 changes: 6 additions & 0 deletions notes/whyerror.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,9 @@ stupid! 错误并不是发生在执行 userland 的时候, 而是因为刚进入
当要执行的 ISR 的段的 `DPL` < `CPL` 时, CPU 会从 tss 取出对应特权级的 ss 和 esp(这里是 ss0 和 esp0), 然而...

如果段描述符的 Access bit `DC` 置位时, 意味着该段可以被与之相等或更低特权级的段访问(所以就没有取出 tss 的内容了甚至 cs 寄存器的 CPL 也不改变)...但是 kerenl 的页表可是 `PTE_K`的, 所以发生 Page Fault.

#2015-9-6 进入 fork 生成的进程后, PIC 中断不发生, 而第一个进程却不会这样
不清楚为什么会这样, 只能强制在 `fork_ret` 中再初始化一次, 代码勉强工作.
// TODO

感谢F叔提供的思路!
10 changes: 10 additions & 0 deletions proc/init.asm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ __init_start:
; push (msg_arg1 - $$) + 0xc0000000
mov eax, 1
int 0x80
cmp eax, 0
jz child
jmp $
child:
mov eax, 1
int 0x80
cmp eax, 0
jz child2
jmp $
child2:
jmp $

msg_arg1:
Expand Down
46 changes: 36 additions & 10 deletions proc/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,52 @@
// proc
#include <proc.h>

#include <pic.h>

extern void _isr_stub_ret();
extern void context_switch(struct context **old, struct context *new);


static uint32_t cur_pid = 0;
static struct proc *initproc = NULL;
static struct proc ptable[NPROC];
struct context *cpu_context;

struct proc *proc = NULL;

/* import irq_remap, only use in fork_ret */
extern void irq_remap();
/* do not ask me why use irq_remap here, irq didn't work after fork()
* and I don't know why, and have to reinit it
* thx to fleuria
*/
void fork_ret(){
static int fst = 1;

if (fst == 1){
fst = 0;
} else {

outb(PIC1_CMD, ICW1_INIT + ICW1_ICW4); // starts the initialization sequence (in cascade mode)
outb(PIC2_CMD, ICW1_INIT + ICW1_ICW4);
}

return;
}

static void print_proc(struct proc *pp){
void print_proc(struct proc *pp){
uint32_t pa;

vmm_get_mapping(pp->pgdir, USER_BASE, &pa);

printl("print_proc:\n name: %s\n",pp->name);
printl("print_proc:\n")
printl(" name: %s\n",pp->name);
printk(" pid: %d\n", pp->pid);
printl(" kern_stack: 0x%x\n",pp->kern_stack);
printl(" pgdir: 0x%x\n",pp->pgdir);
printl(" phy addr: 0x%x\n", pa);
}

static struct proc *proc_alloc(){
struct proc *pp;
char *tos;
Expand Down Expand Up @@ -78,15 +101,15 @@ static struct proc *proc_alloc(){

void proc_init(){
struct proc *pp;
extern char __init_start;
extern char __init_end;

printl("proc_userinit: clear ptable\n");

memset(ptable, 0, sizeof(struct proc) * NPROC);

printl("proc_userinit: prepare for init\n");

extern char __init_start;
extern char __init_end;

pp = proc_alloc();

pp->pgdir = (pde_t *)pmm_alloc();
Expand Down Expand Up @@ -116,6 +139,7 @@ void proc_init(){
printl("proc_init: init stack build\n");

strcpy(pp->name, "init");

pp->cwd = p2i("/");
pp->state = P_RUNABLE;

Expand All @@ -129,22 +153,23 @@ void scheduler(){
struct proc *pp;

printl("scheduler: start\n");

for (;;){
for (pp = &ptable[0]; pp < &ptable[NPROC]; pp++){
if (pp->state != P_RUNABLE){
continue;
}
printl("scheduler: proc `%s` will run\n", pp->name);
print_proc(pp);
printl("scheduler: proc `%s`(PID: %d) will run\n", pp->name, pp->pid);

printl("scheduler: switch pgdir & set tss\n");
uvm_switch(pp);
pp->state = P_RUNNING;

proc = pp;

printl(">>>> context switch\n");
context_switch(&cpu_context, pp->context);
printl("scheduler: return form proc `%s`\n", pp->name);
printl("<<<< return form proc `%s`\n", pp->name);
}
}
}
Expand Down Expand Up @@ -277,6 +302,7 @@ int fork(){
child->pgdir = uvm_copy(proc->pgdir, proc->size);

if (child->pgdir == 0){
panic("fork:");
pmm_free((uint32_t)child->kern_stack);
child->kern_stack = 0;
child->state = P_UNUSED;
Expand All @@ -291,7 +317,6 @@ int fork(){
*child->fm = *proc->fm; // return form same address

child->fm->eax = 0;

printl("fork: dup opened files\n");
for (i = 0; i < NOFILE; i++){
if (proc->ofile[i]){
Expand All @@ -300,9 +325,10 @@ int fork(){
}

child->cwd = idup(proc->cwd);

child->state = P_RUNABLE;

strncpy(child->name, "init2", 5);
strncpy(child->name, proc->name, sizeof(proc->name));

printl("fork: done\n");
return child->pid;
Expand Down

0 comments on commit fc0e84c

Please sign in to comment.