Skip to content

Commit

Permalink
finish task2
Browse files Browse the repository at this point in the history
  • Loading branch information
CH3CHOHCH3 committed Mar 7, 2023
1 parent 773d70b commit 483cb5b
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 1 deletion.
2 changes: 2 additions & 0 deletions kernel/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ void kvminit(void);
void kvminithart(void);
uint64 kvmpa(uint64);
void kvmmap(uint64, uint64, uint64, int);
void ukvmmap(pagetable_t, uint64, uint64, uint64, int);
int mappages(pagetable_t, uint64, uint64, uint64, int);
pagetable_t uvmcreate(void);
void uvminit(pagetable_t, uchar *, uint);
Expand All @@ -178,6 +179,7 @@ uint64 walkaddr(pagetable_t, uint64);
int copyout(pagetable_t, uint64, char *, uint64);
int copyin(pagetable_t, char *, uint64, uint64);
int copyinstr(pagetable_t, char *, uint64, uint64);
void vmprint(pagetable_t, int);

// plic.c
void plicinit(void);
Expand Down
1 change: 1 addition & 0 deletions kernel/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ exec(char *path, char **argv)
p->trapframe->sp = sp; // initial stack pointer
proc_freepagetable(oldpagetable, oldsz);

if(p->pid==1) vmprint(p->pagetable, 0);
return argc; // this ends up in a0, the first argument to main(argc, argv)

bad:
Expand Down
39 changes: 38 additions & 1 deletion kernel/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ static void wakeup1(struct proc *chan);
static void freeproc(struct proc *p);

extern char trampoline[]; // trampoline.S
extern pagetable_t kernel_pagetable; // global kernel pagetable

// initialize the proc table at boot time.
void
Expand Down Expand Up @@ -120,6 +121,23 @@ allocproc(void)
release(&p->lock);
return 0;
}
// 让每个进程的内核页表直接复用全局内核页表;
p->kpagetable = uvmcreate();
if(p->kpagetable == 0){
freeproc(p);
release(&p->lock);
return 0;
}
// 全局内核页表的第一个一级 PTE 占用 0x4000_0000
// 内核在这个地址以下的部分要重新映射;
// 最终 PLIC 以下的地址空间给进程用;
// CLINT 是 M 模式处理时钟的,不用映射;
for(int i = 1; i < 512; ++i){
p->kpagetable[i] = kernel_pagetable[i];
}
ukvmmap(p->kpagetable, UART0, UART0, PGSIZE, PTE_R | PTE_W);
ukvmmap(p->kpagetable, PLIC, PLIC, 0x400000, PTE_R | PTE_W);
ukvmmap(p->kpagetable, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);

// Set up new context to start executing at forkret,
// which returns to user space.
Expand All @@ -142,6 +160,21 @@ freeproc(struct proc *p)
if(p->pagetable)
proc_freepagetable(p->pagetable, p->sz);
p->pagetable = 0;
if(p->kpagetable){
// 页表项:只需要释放第一个一级页表项;
// 物理内存:不需要释放任何物理内存;
pagetable_t lv2 = (pagetable_t)PTE2PA(p->kpagetable[0]);
for(int i = 0; i < 512; ++i){
pte_t pte = lv2[i];
if(pte & PTE_V){
uint64 lv3 = PTE2PA(pte);
kfree((void*)lv3);
}
}
kfree((void*)lv2);
kfree((void*)p->kpagetable);
}
p->kpagetable = 0;
p->sz = 0;
p->pid = 0;
p->parent = 0;
Expand Down Expand Up @@ -473,8 +506,12 @@ scheduler(void)
// before jumping back to us.
p->state = RUNNING;
c->proc = p;
// 切换到目标进程的内核页表
w_satp(MAKE_SATP(p->kpagetable));
sfence_vma();
swtch(&c->context, &p->context);

w_satp(MAKE_SATP(kernel_pagetable));
sfence_vma();
// Process is done running for now.
// It should have changed its p->state before coming back.
c->proc = 0;
Expand Down
1 change: 1 addition & 0 deletions kernel/proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct proc {
uint64 kstack; // Virtual address of kernel stack
uint64 sz; // Size of process memory (bytes)
pagetable_t pagetable; // User page table
pagetable_t kpagetable; // Kernel page table
struct trapframe *trapframe; // data page for trampoline.S
struct context context; // swtch() here to run process
struct file *ofile[NOFILE]; // Open files
Expand Down
29 changes: 29 additions & 0 deletions kernel/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ kvmmap(uint64 va, uint64 pa, uint64 sz, int perm)
panic("kvmmap");
}

void
ukvmmap(pagetable_t pagetable, uint64 va, uint64 pa, uint64 sz, int perm)
{
if(mappages(pagetable, va, sz, pa, perm) != 0)
panic("ukvmmap");
}

// translate a kernel virtual address to
// a physical address. only needed for
// addresses on the stack.
Expand Down Expand Up @@ -440,3 +447,25 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
return -1;
}
}

// 打印页表项
void vmprint(pagetable_t pagetable, int dep){
if(!dep){
printf("page table %p\n", pagetable);
}
// there are 2^9 = 512 PTEs in a page table.
for(int i = 0; i < 512; i++){
pte_t pte = pagetable[i];
if((pte & PTE_V)){
printf("..");
for(int j = 0; j < dep; ++j){
printf(" ..");
}
printf("%d: pte %p pa %p\n", i, pte, PTE2PA(pte));
if(dep != 2){
uint64 child = PTE2PA(pte);
vmprint((pagetable_t)child, dep + 1);
}
}
}
}

0 comments on commit 483cb5b

Please sign in to comment.