# Part 5: How to operate on page tables

This *section* explains 3 things:&#x20;

1\. How page table directory is stored.&#x20;

2\. How to find the address of PTE given virtual address&#x20;

3\. How to map page by creating PTE.

### How page table directory is stored.

```
typedef uint64 pte_t;
typedef uint64 *pagetable_t;// 512 PTEs
```

pagetable\_t is a pointer points to 512 PTEs. page tables are physical memory, initialized by kalloc(). The \*pte stores physical memory.

### How to find the address of PTE given virtual address

```
*// Return the address of the PTE in page table pagetable*
*// that corresponds to virtual address va.  If alloc!=0,*
*// create any required page-table pages.*
*//*
*// The risc-v Sv39 scheme has three levels of page-table*
*// pages. A page-table page contains 512 64-bit PTEs.*
*// A 64-bit virtual address is split into five fields:*
*//   39..63 — must be zero.*
*//   30..38 — 9 bits of level-2 index.*
*//   21..39 — 9 bits of level-1 index.*
*//   12..20 — 9 bits of level-0 index.*
*//    0..12 — 12 bits of byte offset within the page.*
static pte_t *
walk(pagetable_t *pagetable*, uint64 *va*, int *alloc*)
{
  if(va >= MAXVA)
    panic(“walk”);

  for(int level = 2; level > 0; level—) {
    pte_t *pte = &pagetable[PX(level, va)];
    if(*pte & PTE_V) {
      pagetable = (pagetable_t)PTE2PA(*pte);
    } else {
      if(!alloc || (pagetable = (pde_t*)kalloc()) == 0)
        return 0;
      memset(pagetable, 0, PGSIZE);
      *pte = PA2PTE(pagetable) | PTE_V;
    }
  }
  return &pagetable[PX(0, va)];
}
```

*`pagetable = (pde_t)kalloc())`*&#x20;

Above code creates the level\_X page table directly from physical memory, and set to pte.

### How to map page.

```c
*// Create PTEs for virtual addresses starting at va that refer to*
*// physical addresses starting at pa. va and size might not*
*// be page-aligned. Returns 0 on success, -1 if walk() couldn’t*
*// allocate a needed page-table page.*
int
mappages(pagetable_t *pagetable*, uint64 *va*, uint64 *size*, uint64 *pa*, int *perm*)
{
  uint64 a, last;
  pte_t *pte;

  a = PGROUNDDOWN(va);
  last = PGROUNDDOWN(va + size - 1);
  for(;;){
    if((pte = walk(pagetable, a, 1)) == 0)
      return -1;
    if(*pte & PTE_V)
      panic("remap");
    *pte = PA2PTE(pa) | perm | PTE_V;
    if(a == last)
      break;
    a += PGSIZE;
    pa += PGSIZE;
  }
  return 0;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xiayingp.gitbook.io/build_a_os/virtual-memory/page-table/part-5-how-to-operate-on-page-tables.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
