Requirement:
Calling mprotect() should change the protection bits of the page range starting at addr and of len pages to be read only.
Before start:
Xv6 maps the data, stack, and heap with the permissions PTE_R, PTE_W, and PTE_U.
Xv6 sets the PTE_W, PTE_R, PTE_U, and PTE_V flags in these PTEs.
mmu.h
#define PTE_P 0x001 // Present
#define PTE_W 0x002 // Writeable
#define PTE_U 0x004 // User
#define PTE_PS 0x080 // Page Size
There is one page table per processes.
proc.h
38 struct proc {
40 pde_t* pgdir; // Page table
};
exec.c
96 // Commit to the user image.
97 oldpgdir = curproc->pgdir;
98 curproc->pgdir = pgdir;
99 curproc->sz = sz;
vm.c allocuvm function, allocate user address space

mappages, which installs PTEs for new mappings.
For each virtual address to be mapped, mappages calls walkpgdir() to find the address of the PTE for that address.
It then initializes the PTE to hold the relevant physical page number, the desired permissions (PTE_W, PTE_X, and/or PTE_R), and PTE_P to mark the PTE as present. 
To modify the permission of the page, we should first get specfifc PTE from the walkpgdir().
we have to use curproc->pgdir as a parameter for walkpgdir().
Actual Implementation:
1. implement mprotect() & munprotect() function in vm.c
defs.h




