task2 finished
This commit is contained in:
@ -123,14 +123,20 @@ allocproc(void)
|
|||||||
|
|
||||||
found:
|
found:
|
||||||
p->pid = allocpid();
|
p->pid = allocpid();
|
||||||
p->state = USED;
|
|
||||||
|
|
||||||
// Allocate a trapframe page.
|
// Allocate a trapframe page.
|
||||||
if((p->trapframe = (struct trapframe *)kalloc()) == 0){
|
if((p->trapframe = (struct trapframe *)kalloc()) == 0){
|
||||||
|
release(&p->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a usyscall page.
|
||||||
|
if((p->usyscall = (struct usyscall *)kalloc()) == 0){
|
||||||
freeproc(p);
|
freeproc(p);
|
||||||
release(&p->lock);
|
release(&p->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
p->usyscall->pid = p->pid ;
|
||||||
|
|
||||||
// An empty user page table.
|
// An empty user page table.
|
||||||
p->pagetable = proc_pagetable(p);
|
p->pagetable = proc_pagetable(p);
|
||||||
@ -155,6 +161,9 @@ found:
|
|||||||
static void
|
static void
|
||||||
freeproc(struct proc *p)
|
freeproc(struct proc *p)
|
||||||
{
|
{
|
||||||
|
if (p->usyscall) {
|
||||||
|
kfree((void*)p->usyscall);
|
||||||
|
}
|
||||||
if(p->trapframe)
|
if(p->trapframe)
|
||||||
kfree((void*)p->trapframe);
|
kfree((void*)p->trapframe);
|
||||||
p->trapframe = 0;
|
p->trapframe = 0;
|
||||||
@ -202,6 +211,16 @@ proc_pagetable(struct proc *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// map the usyscall just below TRAMPOFRAME, for trampoline.S.
|
||||||
|
// 这个页需要设置PTE_U为,使得用户态可以访问
|
||||||
|
if(mappages(pagetable, USYSCALL, PGSIZE,
|
||||||
|
(uint64)(p->usyscall), PTE_R | PTE_U) < 0){
|
||||||
|
uvmunmap(pagetable, TRAPFRAME, 1, 0);
|
||||||
|
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
|
||||||
|
uvmfree(pagetable, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return pagetable;
|
return pagetable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +229,7 @@ proc_pagetable(struct proc *p)
|
|||||||
void
|
void
|
||||||
proc_freepagetable(pagetable_t pagetable, uint64 sz)
|
proc_freepagetable(pagetable_t pagetable, uint64 sz)
|
||||||
{
|
{
|
||||||
|
uvmunmap(pagetable, USYSCALL, 1, 0);
|
||||||
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
|
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
|
||||||
uvmunmap(pagetable, TRAPFRAME, 1, 0);
|
uvmunmap(pagetable, TRAPFRAME, 1, 0);
|
||||||
uvmfree(pagetable, sz);
|
uvmfree(pagetable, sz);
|
||||||
|
|||||||
@ -94,11 +94,12 @@ struct proc {
|
|||||||
|
|
||||||
// wait_lock must be held when using this:
|
// wait_lock must be held when using this:
|
||||||
struct proc *parent; // Parent process
|
struct proc *parent; // Parent process
|
||||||
|
|
||||||
// these are private to the process, so p->lock need not be held.
|
// these are private to the process, so p->lock need not be held.
|
||||||
uint64 kstack; // Virtual address of kernel stack
|
uint64 kstack; // Virtual address of kernel stack
|
||||||
uint64 sz; // Size of process memory (bytes)
|
uint64 sz; // Size of process memory (bytes)
|
||||||
pagetable_t pagetable; // User page table
|
pagetable_t pagetable; // User page table
|
||||||
|
// 进程的结构体中需要加上usyscall字段
|
||||||
|
struct usyscall *usyscall; // data page for usyscall
|
||||||
struct trapframe *trapframe; // data page for trampoline.S
|
struct trapframe *trapframe; // data page for trampoline.S
|
||||||
struct context context; // swtch() here to run process
|
struct context context; // swtch() here to run process
|
||||||
struct file *ofile[NOFILE]; // Open files
|
struct file *ofile[NOFILE]; // Open files
|
||||||
|
|||||||
@ -375,7 +375,9 @@ typedef uint64 *pagetable_t; // 512 PTEs
|
|||||||
#define PTE_W (1L << 2)
|
#define PTE_W (1L << 2)
|
||||||
#define PTE_X (1L << 3)
|
#define PTE_X (1L << 3)
|
||||||
#define PTE_U (1L << 4) // user can access
|
#define PTE_U (1L << 4) // user can access
|
||||||
|
#define PTE_A (1L << 6) // Accessed bit
|
||||||
|
#define PTE_D (1L << 7) // Dirty bit
|
||||||
|
#define PTE_PS (1L << 7) // Page Size bit in PTE (for 2MB superpages)
|
||||||
|
|
||||||
|
|
||||||
#if defined(LAB_MMAP) || defined(LAB_PGTBL)
|
#if defined(LAB_MMAP) || defined(LAB_PGTBL)
|
||||||
|
|||||||
@ -111,6 +111,7 @@ extern uint64 sys_recv(void);
|
|||||||
#ifdef LAB_PGTBL
|
#ifdef LAB_PGTBL
|
||||||
extern uint64 sys_pgpte(void);
|
extern uint64 sys_pgpte(void);
|
||||||
extern uint64 sys_kpgtbl(void);
|
extern uint64 sys_kpgtbl(void);
|
||||||
|
extern uint64 sys_pgaccess(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// An array mapping syscall numbers from syscall.h
|
// An array mapping syscall numbers from syscall.h
|
||||||
@ -146,6 +147,7 @@ static uint64 (*syscalls[])(void) = {
|
|||||||
#ifdef LAB_PGTBL
|
#ifdef LAB_PGTBL
|
||||||
[SYS_pgpte] sys_pgpte,
|
[SYS_pgpte] sys_pgpte,
|
||||||
[SYS_kpgtbl] sys_kpgtbl,
|
[SYS_kpgtbl] sys_kpgtbl,
|
||||||
|
[SYS_pgaccess] sys_pgaccess,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -123,3 +123,41 @@ sys_uptime(void)
|
|||||||
release(&tickslock);
|
release(&tickslock);
|
||||||
return xticks;
|
return xticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64
|
||||||
|
sys_pgaccess(void)
|
||||||
|
{
|
||||||
|
uint64 va;
|
||||||
|
int n;
|
||||||
|
uint64 user_mask_addr;
|
||||||
|
argaddr(0, &va);
|
||||||
|
argint(1, &n);
|
||||||
|
argaddr(2, &user_mask_addr);
|
||||||
|
if (va < 0 || n < 0 || user_mask_addr < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (n < 0 || n > 32)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct proc *p = myproc();
|
||||||
|
uint64 mask = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
uint64 v = va + i * PGSIZE;
|
||||||
|
pte_t *pte = walk(p->pagetable, v, 0);
|
||||||
|
|
||||||
|
if (!pte || (*pte & PTE_PS))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((*pte & PTE_V) && (*pte & PTE_A)) {
|
||||||
|
mask |= (1 << i); // Set bit i in mask
|
||||||
|
*pte &= ~PTE_A; // Clear the Accessed bit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copyout(p->pagetable, user_mask_addr, (char*)&mask, sizeof(mask)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,6 +101,9 @@ walk(pagetable_t pagetable, uint64 va, int alloc)
|
|||||||
for(int level = 2; level > 0; level--) {
|
for(int level = 2; level > 0; level--) {
|
||||||
pte_t *pte = &pagetable[PX(level, va)];
|
pte_t *pte = &pagetable[PX(level, va)];
|
||||||
if(*pte & PTE_V) {
|
if(*pte & PTE_V) {
|
||||||
|
if (*pte & PTE_PS) { // 如果是 Superpage
|
||||||
|
return pte;
|
||||||
|
}
|
||||||
pagetable = (pagetable_t)PTE2PA(*pte);
|
pagetable = (pagetable_t)PTE2PA(*pte);
|
||||||
#ifdef LAB_PGTBL
|
#ifdef LAB_PGTBL
|
||||||
if(PTE_LEAF(*pte)) {
|
if(PTE_LEAF(*pte)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user