title: How to create physical and virtual page?
body: <p>I am trying to create a physical and virtual page using some example.
  I am trying to understand how the physical page address is determined.
  I have a few questions here.</p>
  <ol>
  <li><p>How do we know where the page Info is stored?
  I am guessing that if we divide the virtual address by <code>PAGE_SIZE</code> we will get the page number.
  i.e  <code>val = ((size_t)*virtAddr)/PAGE_SIZE;</code>
  but I don't understand why do we multiply by 8?</p>
  </li>
  <li><p>When I do <code>cat /proc/self/pagemap</code> it just hangs there.
  It seems like it is blocking call. How is my application able to come out from this when it gets the file descriptor?</p>
  </li>
  <li><p>Why do we multiply <code>PAGE_SIZE * pageInfo</code> to get the physical address?
  How does that relationship come up? What is the scene behind it?</p>
  </li>
  </ol>
  <p>Here is my code.</p>
  <pre><code>#include &lt;sys/mman.h&gt; //for mmap and mlock 
  #include &lt;unistd.h&gt; //for NULL, lseek
  #include &lt;stdlib.h&gt; //for exit and for valloc
  #include &lt;stdio.h&gt; //for printf
  #include &lt;fcntl.h&gt; //for file opening
  #include &lt;stdint.h&gt; //for uint32_t
  #include &lt;string.h&gt; //for memset
  
  #define PAGE_SIZE 4096 //mmap maps pages of memory, so we must give it multiples of this size
  
  void makeVirtPhysPage(void **virtAddr, void **physAddr)
  {
   *virtAddr = valloc(PAGE_SIZE); // allocate one page of RAM
   
    //force page into RAM
   ((int *)*virtAddr)[0] = 1; 
    //lock it there.
    mlock(*virtAddr, PAGE_SIZE);
    memset(*virtAddr, 0, PAGE_SIZE); // zero-fill the page for convenience 
  
    uint64_t pageInfo;
    size_t val;
    int file = open(&quot;/proc/self/pagemap&quot;, 'r');
    printf(&quot;The virtAddr is %lu\r\n&quot;, *virtAddr);
    printf(&quot;The Page size is %lu\r\n&quot;, PAGE_SIZE);
    val = ((size_t)*virtAddr)/PAGE_SIZE; // probably getting page number.
    val = val * 8;
    printf(&quot;The val is %lu\r\n&quot;, val);
    lseek(file, val, SEEK_SET);
    read(file, &amp;pageInfo,8);
    printf(&quot;The pageInfo says %p\r\n&quot;, pageInfo);
    *physAddr = (void*)(size_t)(pageInfo*PAGE_SIZE); // why multiply by page size?
    printf(&quot;makeVirtualPhysPage virtual to phys: %p -&gt; %p\r\n&quot;, *virtAddr, *physAddr);
  }
  
  void freeVirtPhysPage(void *virtAddr)
  {
    munlock(virtAddr, PAGE_SIZE);
    free(virtAddr);
  }
  
  int main()
  {
    void *virtSrcPage, *PhysSrcPage;
    makeVirtPhysPage(&amp;virtSrcPage, &amp;PhysSrcPage);
    char *srcPage = (char *)virtSrcPage;
    srcPage[0] = 'S';
    srcPage[1] = 'U';
    srcPage[1] = 'P';
    srcPage[1] = 'E';
    srcPage[1] = 'R';
  
    freeVirtPhysPage(virtSrcPage);
    printf(&quot;The value of virtSrcPage[0] is %c\r\n&quot;, srcPage[0]);
  
    return 0;
  }
  </code></pre>