I was solving the print a pagetable question in the Pagetables lab in the XV6 operating system in MIT’s 6.1810, as described here (https://pdos.csail.mit.edu/6.S081/2023/labs/pgtbl.html):
To help you visualize RISC-V page tables, and perhaps to aid future debugging, your second task is to write a function that prints the contents of a page table.
Define a function called vmprint(). It should take a pagetable_t argument, and print that pagetable in the format described below. Insert if(p->pid==1) vmprint(p->pagetable) in exec.c just before the return argc, to print the first process’s page table. You receive full credit for this part of the lab if you pass the pte printout test of make grade.
Now when you start xv6 it should print output like this, describing the page table of the first process at the point when it has just finished exec()ing init:
page table 0x0000000087f6b000
..0: pte 0x0000000021fd9c01 pa 0x0000000087f67000
.. ..0: pte 0x0000000021fd9801 pa 0x0000000087f66000
.. .. ..0: pte 0x0000000021fda01b pa 0x0000000087f68000
.. .. ..1: pte 0x0000000021fd9417 pa 0x0000000087f65000
.. .. ..2: pte 0x0000000021fd9007 pa 0x0000000087f64000
.. .. ..3: pte 0x0000000021fd8c17 pa 0x0000000087f63000
..255: pte 0x0000000021fda801 pa 0x0000000087f6a000
.. ..511: pte 0x0000000021fda401 pa 0x0000000087f69000
.. .. ..509: pte 0x0000000021fdcc13 pa 0x0000000087f73000
.. .. ..510: pte 0x0000000021fdd007 pa 0x0000000087f74000
.. .. ..511: pte 0x0000000020001c0b pa 0x0000000080007000
init: starting sh
Your code might emit different physical addresses than those shown above. The number of entries and the virtual addresses should be the same.
However, my code emits the same PAs but different VAs. Specifically, the permission bits are different
page table 0x0000000087f6b000
..0: pte 0x0000000021fd9c01 pa 0x0000000087f67000
.. ..0: pte 0x0000000021fd9801 pa 0x0000000087f66000
.. .. ..0: pte 0x0000000021fda01f pa 0x0000000087f68000
.. .. ..1: pte 0x0000000021fd941f pa 0x0000000087f65000
.. .. ..2: pte 0x0000000021fd9007 pa 0x0000000087f64000
.. .. ..3: pte 0x0000000021fd8c17 pa 0x0000000087f63000
..255: pte 0x0000000021fda801 pa 0x0000000087f6a000
.. ..511: pte 0x0000000021fda401 pa 0x0000000087f69000
.. .. ..509: pte 0x0000000021fdcc13 pa 0x0000000087f73000
.. .. ..510: pte 0x0000000021fdd007 pa 0x0000000087f74000
.. .. ..511: pte 0x0000000020001c0b pa 0x0000000080007000
init: starting sh
NOTE: The last 5 bits of a PTE represent the Valid, Read, Write, Execute, User permission bits respectively
What I am not able to understand is how can the permission bits change?
The lab further asks the question
For every leaf page in the vmprint output, explain what it logically contains and what its permission bits are. Figure 3.4 in the xv6 book might be helpful, although note that the figure might have a slightly different set of pages than the init process that’s being inspected here.
For the addresses I have marked in bold, as per addresses given in the question, I would have said that 0x0000000021fda01b is in the text region (VR-XU set) and 0x0000000021fd9417 is in the data section (VRW-U set, and is closest to text). However, in the addresses I see, the permission bits are 1f so VRWXU all are set which doesn’t seem to correspond to any valid location in the address space.
PS: If it helps, running make qemu to start the kernel spits out a lot of warnings like riscv64-linux-gnu-ld: warning: user/initcode.out has a LOAD segment with RWX permissions