main
calls userinit
, mpmain
calls scheduler
to start running processes1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// Set up first user process.
void
userinit(void)
{
struct proc *p;
extern char _binary_initcode_start[], _binary_initcode_size[];
acquire(&ptable.lock);
p = allocproc();
initproc = p;
if((p−>pgdir = setupkvm()) == 0)
panic("userinit: out of memory?");
inituvm(p−>pgdir, _binary_initcode_start, (int)_binary_initcode_size);
p−>sz = PGSIZE;
memset(p−>tf, 0, sizeof(*p−>tf));
p−>tf−>cs = (SEG_UCODE << 3) | DPL_USER;
p−>tf−>ds = (SEG_UDATA << 3) | DPL_USER;
p−>tf−>es = p−>tf−>ds;
p−>tf−>ss = p−>tf−>ds;
p−>tf−>eflags = FL_IF;
p−>tf−>esp = PGSIZE;
p−>tf−>eip = 0; // beginning of initcode.S
safestrcpy(p−>name, "initcode", sizeof(p−>name));
p−>cwd = namei("/");
p−>state = RUNNABLE;
release(&ptable.lock);
}
userinit
- 调用allocproc
- 在proc table中找到一个空闲的slot,用来存放进程的proc struct
- 找到空闲的slot后, 为proc的kernel thread分配kernel stack
1 | // Per−CPU process scheduler. |
1 | // Switch TSS and h/w page table to correspond to process p. |
1 | // note: EMBRYO -> find unused slot, occupy the slot |
1 | // Saved registers for kernel context switches. |