{"componentChunkName":"component---src-templates-post-template-js","path":"/unix-xv6-005-kernel-main-02-en","result":{"data":{"markdownRemark":{"id":"6bbd9053-6787-54c1-a17d-b1d242397b95","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/unix-xv6-005-kernel-main-02\">original page</a>.</p>\n</blockquote>\n<p>Inspired by <a href=\"https://amzn.to/3q8TU3K\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">An Introduction to OS Code Reading: Learning Kernel Internals with UNIX V6</a>, I’m reading <a href=\"https://github.com/mit-pdos/xv6-public\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">xv6 OS</a>.</p>\n<p>Because UNIX V6 itself does not run on x86 CPUs, I decided to read the source of <a href=\"https://github.com/kash1064/xv6-public\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">kash1064/xv6-public: xv6 OS</a>, a fork of the <a href=\"https://github.com/mit-pdos/xv6-public\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">xv6 OS</a> repository that makes UNIX V6 run on the x86 architecture.</p>\n<p>In the <a href=\"/unix-xv6-004-kernel-main-01\">previous article</a>, I looked at the locking-related behavior of the <code class=\"language-text\">kinit1</code> function, which is executed first from <code class=\"language-text\">main</code>.</p>\n<p>This time, I will trace how <code class=\"language-text\">kvmalloc</code> initializes the xv6 kernel’s page tables.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li>\n<p><a href=\"#about-32-bit-paging\">About 32-bit paging</a></p>\n<ul>\n<li><a href=\"#pdt-and-pt\">PDT and PT</a></li>\n<li><a href=\"#how-virtual-addresses-are-resolved-to-physical-addresses\">How virtual addresses are resolved to physical addresses</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#the-kvmalloc-function\">The <code class=\"language-text\">kvmalloc</code> function</a></p>\n<ul>\n<li><a href=\"#about-virtual-memory\">About virtual memory</a></li>\n<li><a href=\"#the-setupkvm-function\">The <code class=\"language-text\">setupkvm</code> function</a></li>\n<li><a href=\"#allocating-pages-with-kalloc\">Allocating pages with <code class=\"language-text\">kalloc</code></a></li>\n<li><a href=\"#creating-ptes-for-virtual-addresses\">Creating PTEs for virtual addresses</a></li>\n<li><a href=\"#the-freevm-function\">The <code class=\"language-text\">freevm</code> function</a></li>\n</ul>\n</li>\n<li><a href=\"#the-switchkvm-function\">The <code class=\"language-text\">switchkvm</code> function</a></li>\n<li><a href=\"#summary\">Summary</a></li>\n<li><a href=\"#reference-books\">Reference Books</a></li>\n</ul>\n<h2 id=\"about-32-bit-paging\" style=\"position:relative;\"><a href=\"#about-32-bit-paging\" aria-label=\"about 32 bit paging permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About 32-bit paging</h2>\n<p>This time I will start from xv6OS’s <code class=\"language-text\">kvmalloc</code> function.</p>\n<p>The <code class=\"language-text\">kvmalloc</code> function creates the kernel page table.</p>\n<p>Before reading the source code, I want to organize the paging mechanism in a 32-bit environment.</p>\n<p>Paging is implemented by the MMU (Memory Management Unit).</p>\n<p>On x86, the MMU maps memory by using a PD (Page Directory) and PT (Page Table).</p>\n<h3 id=\"pdt-and-pt\" style=\"position:relative;\"><a href=\"#pdt-and-pt\" aria-label=\"pdt and pt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>PDT and PT</h3>\n<p>Both the PDT and PT contain PDEs (Page Directory Entries) and PTEs (Page Table Entries), respectively.</p>\n<p>Each PDE and PTE is 4 bytes (32 bits), and a PD contains 1024 PDEs while a PT contains 1024 PTEs.</p>\n<p>That makes both of them 4 KiB in size, which is one default page on x86.</p>\n<p>For the details of each entry, the following page is helpful.</p>\n<p>Reference: <a href=\"https://wiki.osdev.org/Paging\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Paging - OSDev Wiki</a></p>\n<h3 id=\"how-virtual-addresses-are-resolved-to-physical-addresses\" style=\"position:relative;\"><a href=\"#how-virtual-addresses-are-resolved-to-physical-addresses\" aria-label=\"how virtual addresses are resolved to physical addresses permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How virtual addresses are resolved to physical addresses</h3>\n<p>When translating a virtual address to a physical address, the virtual address is divided into the following three parts.</p>\n<ul>\n<li>Top 10 bits: PDE index</li>\n<li>Next 10 bits: PTE index</li>\n<li>Bottom 12 bits: page offset</li>\n</ul>\n<p>During address translation, the MMU looks up the PD and uses the virtual-address index to identify the PDE.</p>\n<p>Next, it uses the PDE information together with the virtual-address index to identify the PTE.</p>\n<p>Because the PTE resolves the base address of the physical address, the final physical address can be identified by combining it with the offset inside the virtual address.</p>\n<p>The following diagram explained the flow clearly, so I am quoting it here.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/c4e6687bec1fc2e4b2022ecd1f666969/41099/zu04.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.24999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHtXcgqv//EABgQAAMBAQAAAAAAAAAAAAAAAAABEQIQ/9oACAEBAAEFAuZdUIJQ/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8Bp//EABgQAAIDAAAAAAAAAAAAAAAAAAABIDFB/9oACAEBAAY/AtLcf//EABsQAQADAAMBAAAAAAAAAAAAAAEAESExQVGB/9oACAEBAAE/IafR9iUblBuGIeZ21gCif//aAAwDAQACAAMAAAAQPM//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAWEQEBAQAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8QVs//xAAaEAEBAQEBAQEAAAAAAAAAAAABEQAhMUFR/9oACAEBAAE/EAxtvyOZEYOrTdYgZ7vBDP0wR6B5F0AQ3//Z'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/c4e6687bec1fc2e4b2022ecd1f666969/8ac56/zu04.webp 240w,\n/static/c4e6687bec1fc2e4b2022ecd1f666969/d3be9/zu04.webp 480w,\n/static/c4e6687bec1fc2e4b2022ecd1f666969/b0a15/zu04.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/c4e6687bec1fc2e4b2022ecd1f666969/09b79/zu04.jpg 240w,\n/static/c4e6687bec1fc2e4b2022ecd1f666969/7cc5e/zu04.jpg 480w,\n/static/c4e6687bec1fc2e4b2022ecd1f666969/41099/zu04.jpg 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/jpeg\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/c4e6687bec1fc2e4b2022ecd1f666969/41099/zu04.jpg\"\n            alt=\"img\"\n            title=\"img\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://xtech.nikkei.com/it/article/COLUMN/20071107/286632/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">6th Episode: Making Data on Memory Invisible (Part 1) | Nikkei Cross Tech (xTECH)</a></p>\n<p>A PD is simply an array of PDEs.</p>\n<p>The starting address of the PD is stored in the CR3 register.</p>\n<h2 id=\"the-kvmalloc-function\" style=\"position:relative;\"><a href=\"#the-kvmalloc-function\" aria-label=\"the kvmalloc function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The <code class=\"language-text\">kvmalloc</code> function</h2>\n<p>Now then, continuing from the <a href=\"/unix-xv6-004-kernel-main-01\">previous article</a>, let’s follow the processing of the kernel’s <code class=\"language-text\">main</code> function.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Bootstrap processor starts running C code here.</span>\n<span class=\"token comment\">// Allocate a real stack and switch to it, first</span>\n<span class=\"token comment\">// doing some setup required for memory allocator to work.</span>\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token function\">kinit1</span><span class=\"token punctuation\">(</span>end<span class=\"token punctuation\">,</span> <span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token operator\">*</span><span class=\"token number\">1024</span><span class=\"token operator\">*</span><span class=\"token number\">1024</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// phys page allocator</span>\n  <span class=\"token function\">kvmalloc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>      <span class=\"token comment\">// kernel page table</span>\n  <span class=\"token function\">mpinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>        <span class=\"token comment\">// detect other processors</span>\n  <span class=\"token function\">lapicinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>     <span class=\"token comment\">// interrupt controller</span>\n  <span class=\"token function\">seginit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>       <span class=\"token comment\">// segment descriptors</span>\n  <span class=\"token function\">picinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>       <span class=\"token comment\">// disable pic</span>\n  <span class=\"token function\">ioapicinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>    <span class=\"token comment\">// another interrupt controller</span>\n  <span class=\"token function\">consoleinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>   <span class=\"token comment\">// console hardware</span>\n  <span class=\"token function\">uartinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>      <span class=\"token comment\">// serial port</span>\n  <span class=\"token function\">pinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>         <span class=\"token comment\">// process table</span>\n  <span class=\"token function\">tvinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>        <span class=\"token comment\">// trap vectors</span>\n  <span class=\"token function\">binit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>         <span class=\"token comment\">// buffer cache</span>\n  <span class=\"token function\">fileinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>      <span class=\"token comment\">// file table</span>\n  <span class=\"token function\">ideinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>       <span class=\"token comment\">// disk </span>\n  <span class=\"token function\">startothers</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>   <span class=\"token comment\">// start other processors</span>\n  <span class=\"token function\">kinit2</span><span class=\"token punctuation\">(</span><span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span><span class=\"token number\">4</span><span class=\"token operator\">*</span><span class=\"token number\">1024</span><span class=\"token operator\">*</span><span class=\"token number\">1024</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span>PHYSTOP<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// must come after startothers()</span>\n  <span class=\"token function\">userinit</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>      <span class=\"token comment\">// first user process</span>\n  <span class=\"token function\">mpmain</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>        <span class=\"token comment\">// finish this processor's setup</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In the <a href=\"/unix-xv6-004-kernel-main-01\">previous article</a>, I got as far as the end of <code class=\"language-text\">kinit1</code>, so this time I will start with <code class=\"language-text\">kvmalloc</code>.</p>\n<p>The <code class=\"language-text\">kvmalloc</code> function is defined in <code class=\"language-text\">vm.c</code> as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Allocate one page table for the machine for the kernel address</span>\n<span class=\"token comment\">// space for scheduler processes.</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">kvmalloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  kpgdir <span class=\"token operator\">=</span> <span class=\"token function\">setupkvm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">switchkvm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The <code class=\"language-text\">kvmalloc</code> function changes the kernel page table.</p>\n<p>At this point, it switches to a page table design that lets the kernel manage process address spaces.</p>\n<p>Reference: <a href=\"https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">P.30 xv6OS</a></p>\n<p>In xv6OS, one page table is created per process, and when a process runs, the kernel uses that process’s page table.</p>\n<p>There is also a page table called <code class=\"language-text\">kpgdir</code> that is used when the CPU is not running a process.</p>\n<h3 id=\"about-virtual-memory\" style=\"position:relative;\"><a href=\"#about-virtual-memory\" aria-label=\"about virtual memory permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About virtual memory</h3>\n<p>In xv6OS, as well as in 32-bit OSes such as Windows and Linux on the x86 architecture, each process is given a private memory space called virtual memory.</p>\n<p>Because each process’s virtual address space is independent, each one can access memory within its own 2 GiB virtual address space.</p>\n<p>(When a process references an address, the kernel decides which physical memory address it actually points to.)</p>\n<p>Thanks to this mechanism, even when paging is used, a process can always access memory through virtual addresses, so applications can be developed without worrying about changes to physical memory addresses.</p>\n<p>A 32-bit OS can manage at most 4 GiB of address space.</p>\n<p>However, by creating a virtual address space for each process and using paging, the system can operate as if it had a larger memory space than the actual physical memory.</p>\n<p>It also prevents memory conflicts and makes access control possible because each process has its own isolated memory space.</p>\n<p>By the way, the reason the virtual address space is 2 GiB even though a 32-bit OS can handle up to 4 GiB seems to be that the upper 2 GiB are reserved for the kernel.</p>\n<p>The following diagram is helpful if you want more detail.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 454px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/b3c1d/image-20.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 97.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAACxElEQVQ4y42Ui5KaQBBF/f/fSmpTlY1bRkVBUQFBXsLwBhG56Z5diG4eu1S1DjBz5/TtHiZ93+P9laYxyqp4eDbM+9v8+2vCP9driziO4fsRPK+EZcVwnAxBUCMMC3RdN4p9SvB1cgfTDKGqDRZzgdkswnJZ0L1AkohPU05utxstSJBlKXTdgaZVFAXWao7NpsZKCYjUfyD8r2BPgmVZUhSUpsBiIfDy4slgyv0+R12XlPbtU5ST+5swLKXgdEqCU5dSTsnPmjbLpY+czUdeTu5fum5CnpUPKW+3CRFWVLiO4voh5ZsgaPcOp5MgH1siE5jPz9jtOykYhoFcfLlc/qB8Lz4ZBpdLI4uyXCbSv+dnB4qSUfhwvRMJ9Wjb9oHyfYwe8s5dd6WixJLu6emAL191LJUU63UoO4CFhviXf/x80suTkUKIGMYhgLpuKEqoqxJbrYVGfZimiaxy0zQoikIC1FVFAA7yvJBCgxWSMM9zROcQumFBO9K/E8nY2hSmizzL5OSK2uschvJUVSQohJBr67qWm90dPUrlQikLG4duC7PbvUa/g1UZqIpKTmY6FuK+5awMw6A+3eN8Pkt/X1O+8yMofBxh4QSHwn6NxiaySi4Ig0CmyQJMxXQZ0XPwZiPhIGpHR6j5CiuxxDpRaKxgl+ioy3r8QPDF6TGZrus4Ho+wbVtS/+5D9COhQaka7Z5SPtB4D7u20F5a+T6KIknn+75MmQnZLi4SW/HgYSIS7NwdlGSBeTDD1HmGIhbYhCq9SzHMY1ImZCIuDsdQ+VGQT0ld1bBCE1qxxsx7wbf9E1apgm2kwXd9KeS5LjW5N1aWv1IsxuOR8D5lL3OxaVQs45/4cfoOrVbJwy0VI5Q+B1QUl0RZiAXYO37GxA+CkpIOv3kyYcYH7HwdmqPCoLEdWUiTFEMvcEN7b5QsxsHjoSi/ABqT/23sEaz0AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/8ac56/image-20.webp 240w,\n/static/bda5ce08cfe2ad1e3267f7b9bcef994f/44d9f/image-20.webp 454w\"\n              sizes=\"(max-width: 454px) 100vw, 454px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/8ff5a/image-20.png 240w,\n/static/bda5ce08cfe2ad1e3267f7b9bcef994f/b3c1d/image-20.png 454w\"\n            sizes=\"(max-width: 454px) 100vw, 454px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/b3c1d/image-20.png\"\n            alt=\"img\"\n            title=\"img\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">P.31 xv6OS</a></p>\n<h3 id=\"the-setupkvm-function\" style=\"position:relative;\"><a href=\"#the-setupkvm-function\" aria-label=\"the setupkvm function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The <code class=\"language-text\">setupkvm</code> function</h3>\n<p>For now, let’s trace what <code class=\"language-text\">kvmalloc</code> does.</p>\n<p>In the line <code class=\"language-text\">kpgdir = setupkvm();</code>, the return value of <code class=\"language-text\">setupkvm</code> is stored in <code class=\"language-text\">kpgdir</code>, which has type <code class=\"language-text\">pde_t</code>.</p>\n<p>Incidentally, <code class=\"language-text\">mmu.h</code> shows that these page-table entry types are <code class=\"language-text\">uint</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">typedef</span> uint <span class=\"token class-name\">pte_t</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">setupkvm</code> function is defined in <code class=\"language-text\">vm.c</code> as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Set up kernel part of a page table.</span>\n<span class=\"token class-name\">pde_t</span><span class=\"token operator\">*</span> <span class=\"token function\">setupkvm</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token class-name\">pde_t</span> <span class=\"token operator\">*</span>pgdir<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">kmap</span> <span class=\"token operator\">*</span>k<span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>pgdir <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">pde_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">kalloc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">memset</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> PGSIZE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span>PHYSTOP<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>DEVSPACE<span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"PHYSTOP too high\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>k <span class=\"token operator\">=</span> kmap<span class=\"token punctuation\">;</span> k <span class=\"token operator\">&lt;</span> <span class=\"token operator\">&amp;</span>kmap<span class=\"token punctuation\">[</span><span class=\"token function\">NELEM</span><span class=\"token punctuation\">(</span>kmap<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> k<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">mappages</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>virt<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>phys_end <span class=\"token operator\">-</span> k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span>\n                <span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span>k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>perm<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> \n    <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">freevm</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> pgdir<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>First, here are the variable declarations.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token class-name\">pde_t</span> <span class=\"token operator\">*</span>pgdir<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">kmap</span> <span class=\"token operator\">*</span>k<span class=\"token punctuation\">;</span></code></pre></div>\n<p>As noted above, <code class=\"language-text\">pde_t</code> is the same as <code class=\"language-text\">uint</code>.</p>\n<p>The next structure, <code class=\"language-text\">kmap</code>, is the kernel memory-mapping table defined in <code class=\"language-text\">vm.c</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// This table defines the kernel's mappings, which are present in</span>\n<span class=\"token comment\">// every process's page table.</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">kmap</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>virt<span class=\"token punctuation\">;</span>\n  uint phys_start<span class=\"token punctuation\">;</span>\n  uint phys_end<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">int</span> perm<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> kmap<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>KERNBASE<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>             EXTMEM<span class=\"token punctuation\">,</span>    PTE_W<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// I/O space</span>\n  <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>KERNLINK<span class=\"token punctuation\">,</span> <span class=\"token function\">V2P</span><span class=\"token punctuation\">(</span>KERNLINK<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token function\">V2P</span><span class=\"token punctuation\">(</span>data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>     <span class=\"token comment\">// kern text+rodata</span>\n  <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>data<span class=\"token punctuation\">,</span>     <span class=\"token function\">V2P</span><span class=\"token punctuation\">(</span>data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>     PHYSTOP<span class=\"token punctuation\">,</span>   PTE_W<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// kern data+memory</span>\n  <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>DEVSPACE<span class=\"token punctuation\">,</span> DEVSPACE<span class=\"token punctuation\">,</span>      <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>         PTE_W<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// more devices</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>It defines the start addresses, end addresses, and permissions.</p>\n<p>The initialized mappings match the layout in the image I showed earlier.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 454px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/b3c1d/image-20-16455945916397.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 97.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAACxElEQVQ4y42Ui5KaQBBF/f/fSmpTlY1bRkVBUQFBXsLwBhG56Z5diG4eu1S1DjBz5/TtHiZ93+P9laYxyqp4eDbM+9v8+2vCP9driziO4fsRPK+EZcVwnAxBUCMMC3RdN4p9SvB1cgfTDKGqDRZzgdkswnJZ0L1AkohPU05utxstSJBlKXTdgaZVFAXWao7NpsZKCYjUfyD8r2BPgmVZUhSUpsBiIfDy4slgyv0+R12XlPbtU5ST+5swLKXgdEqCU5dSTsnPmjbLpY+czUdeTu5fum5CnpUPKW+3CRFWVLiO4voh5ZsgaPcOp5MgH1siE5jPz9jtOykYhoFcfLlc/qB8Lz4ZBpdLI4uyXCbSv+dnB4qSUfhwvRMJ9Wjb9oHyfYwe8s5dd6WixJLu6emAL191LJUU63UoO4CFhviXf/x80suTkUKIGMYhgLpuKEqoqxJbrYVGfZimiaxy0zQoikIC1FVFAA7yvJBCgxWSMM9zROcQumFBO9K/E8nY2hSmizzL5OSK2uschvJUVSQohJBr67qWm90dPUrlQikLG4duC7PbvUa/g1UZqIpKTmY6FuK+5awMw6A+3eN8Pkt/X1O+8yMofBxh4QSHwn6NxiaySi4Ig0CmyQJMxXQZ0XPwZiPhIGpHR6j5CiuxxDpRaKxgl+ioy3r8QPDF6TGZrus4Ho+wbVtS/+5D9COhQaka7Z5SPtB4D7u20F5a+T6KIknn+75MmQnZLi4SW/HgYSIS7NwdlGSBeTDD1HmGIhbYhCq9SzHMY1ImZCIuDsdQ+VGQT0ld1bBCE1qxxsx7wbf9E1apgm2kwXd9KeS5LjW5N1aWv1IsxuOR8D5lL3OxaVQs45/4cfoOrVbJwy0VI5Q+B1QUl0RZiAXYO37GxA+CkpIOv3kyYcYH7HwdmqPCoLEdWUiTFEMvcEN7b5QsxsHjoSi/ABqT/23sEaz0AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/8ac56/image-20-16455945916397.webp 240w,\n/static/bda5ce08cfe2ad1e3267f7b9bcef994f/44d9f/image-20-16455945916397.webp 454w\"\n              sizes=\"(max-width: 454px) 100vw, 454px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/8ff5a/image-20-16455945916397.png 240w,\n/static/bda5ce08cfe2ad1e3267f7b9bcef994f/b3c1d/image-20-16455945916397.png 454w\"\n            sizes=\"(max-width: 454px) 100vw, 454px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/bda5ce08cfe2ad1e3267f7b9bcef994f/b3c1d/image-20-16455945916397.png\"\n            alt=\"img\"\n            title=\"img\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">P.31 xv6OS</a></p>\n<h3 id=\"allocating-pages-with-kalloc\" style=\"position:relative;\"><a href=\"#allocating-pages-with-kalloc\" aria-label=\"allocating pages with kalloc permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Allocating pages with <code class=\"language-text\">kalloc</code></h3>\n<p>After that, it checks and initializes the memory region to use after creating the page table.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>pgdir <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">pde_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">kalloc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> PGSIZE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span>PHYSTOP<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>DEVSPACE<span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"PHYSTOP too high\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">kalloc</code> function is defined in <code class=\"language-text\">kalloc.c</code> as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Allocate one 4096-byte page of physical memory.</span>\n<span class=\"token comment\">// Returns a pointer that the kernel can use.</span>\n<span class=\"token comment\">// Returns 0 if the memory cannot be allocated.</span>\n<span class=\"token keyword\">char</span><span class=\"token operator\">*</span> <span class=\"token function\">kalloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">run</span> <span class=\"token operator\">*</span>r<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>kmem<span class=\"token punctuation\">.</span>use_lock<span class=\"token punctuation\">)</span> <span class=\"token function\">acquire</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>kmem<span class=\"token punctuation\">.</span>lock<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  r <span class=\"token operator\">=</span> kmem<span class=\"token punctuation\">.</span>freelist<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">)</span> kmem<span class=\"token punctuation\">.</span>freelist <span class=\"token operator\">=</span> r<span class=\"token operator\">-></span>next<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>kmem<span class=\"token punctuation\">.</span>use_lock<span class=\"token punctuation\">)</span> <span class=\"token function\">release</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>kmem<span class=\"token punctuation\">.</span>lock<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>r<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>As I confirmed in the <a href=\"/unix-xv6-004-kernel-main-01\">previous article</a>, locking is still disabled at this point.</p>\n<p>So I will ignore <code class=\"language-text\">acquire</code> and <code class=\"language-text\">release</code>.</p>\n<p><code class=\"language-text\">kmem.freelist</code> holds freed pages in a singly linked list.</p>\n<p>In other words, it looks like <code class=\"language-text\">kalloc</code> simply checks whether there is a free region and allocates one page.</p>\n<p>If allocation succeeds, <code class=\"language-text\">kalloc</code> returns a pointer to the allocated page and stores it in <code class=\"language-text\">pgdir</code>.</p>\n<p>That makes it possible for <code class=\"language-text\">memset(pgdir, 0, PGSIZE);</code> in the next line to initialize that one page of memory to zero.</p>\n<p>I already checked the behavior of <code class=\"language-text\">memset</code> in the <a href=\"/unix-xv6-004-kernel-main-01\">previous article</a>, so I will omit it here.</p>\n<p>The last line only checks whether <code class=\"language-text\">PHYSTOP</code> exceeds <code class=\"language-text\">DEVSPACE</code>, so I will skip that as well.</p>\n<p>In the end, the allocated one-page region <code class=\"language-text\">pgdir</code> is used as the PDT after this.</p>\n<h3 id=\"creating-ptes-for-virtual-addresses\" style=\"position:relative;\"><a href=\"#creating-ptes-for-virtual-addresses\" aria-label=\"creating ptes for virtual addresses permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating PTEs for virtual addresses</h3>\n<p>By this point, <code class=\"language-text\">pgdir</code> contains a reference to the one-page memory region that was allocated.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>k <span class=\"token operator\">=</span> kmap<span class=\"token punctuation\">;</span> k <span class=\"token operator\">&lt;</span> <span class=\"token operator\">&amp;</span>kmap<span class=\"token punctuation\">[</span><span class=\"token function\">NELEM</span><span class=\"token punctuation\">(</span>kmap<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> k<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> \n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">mappages</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>virt<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>phys_end <span class=\"token operator\">-</span> k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span>k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>perm<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> \n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">freevm</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">return</span> pgdir<span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">NELEM</code> is the following macro defined in <code class=\"language-text\">defs.h</code>, and it returns the number of elements in a fixed-size array.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// number of elements in fixed-size array</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">NELEM</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span><span class=\"token operator\">/</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></span></span></code></pre></div>\n<p>In other words, the loop condition <code class=\"language-text\">k = kmap; k &lt; &amp;kmap[NELEM(kmap)]; k++</code> simply means “process every element in the <code class=\"language-text\">kmap</code> array.”</p>\n<p>The key part is the following lines.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">mappages</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>virt<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>phys_end <span class=\"token operator\">-</span> k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span><span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span>k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>perm<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> \n<span class=\"token punctuation\">{</span>\n    <span class=\"token function\">freevm</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The <code class=\"language-text\">mappages</code> function is defined in <code class=\"language-text\">vm.c</code>. It creates PTEs for the virtual addresses passed as arguments and points them to the physical addresses passed as arguments.</p>\n<p>A PTE stores the physical address of the page together with access-control and attribute information.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/cea566737a194af6446f300861a595e8/41099/zu03b.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAIABQDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAABtiAP/8QAFxAAAwEAAAAAAAAAAAAAAAAAAAEQEf/aAAgBAQABBQJzD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABYQAAMAAAAAAAAAAAAAAAAAAAAQMf/aAAgBAQAGPwJU/8QAGRAAAgMBAAAAAAAAAAAAAAAAAAERMUFx/9oACAEBAAE/IWkvWdD/2gAMAwEAAgADAAAAEIvv/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQMBAT8Qqv/EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oACAECAQE/EIj/xAAaEAEAAgMBAAAAAAAAAAAAAAABABExUXGR/9oACAEBAAE/EEWU4wKHtcHtn//Z'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/cea566737a194af6446f300861a595e8/8ac56/zu03b.webp 240w,\n/static/cea566737a194af6446f300861a595e8/d3be9/zu03b.webp 480w,\n/static/cea566737a194af6446f300861a595e8/b0a15/zu03b.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/cea566737a194af6446f300861a595e8/09b79/zu03b.jpg 240w,\n/static/cea566737a194af6446f300861a595e8/7cc5e/zu03b.jpg 480w,\n/static/cea566737a194af6446f300861a595e8/41099/zu03b.jpg 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/jpeg\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/cea566737a194af6446f300861a595e8/41099/zu03b.jpg\"\n            alt=\"img\"\n            title=\"img\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://xtech.nikkei.com/it/article/COLUMN/20071107/286632/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">6th Episode: Making Data on Memory Invisible (Part 1) | Nikkei Cross Tech (xTECH)</a></p>\n<p>Reference: <a href=\"http://softwaretechnique.web.fc2.com/OS_Development/kernel_development07.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">０から作るOS開発　ページングその１　ページとPTEとPDE</a></p>\n<p>Let’s first look at the source.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Create PTEs for virtual addresses starting at va that refer to</span>\n<span class=\"token comment\">// physical addresses starting at pa. va and size might not</span>\n<span class=\"token comment\">// be page-aligned.</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">int</span> <span class=\"token function\">mappages</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">pde_t</span> <span class=\"token operator\">*</span>pgdir<span class=\"token punctuation\">,</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>va<span class=\"token punctuation\">,</span> uint size<span class=\"token punctuation\">,</span> uint pa<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> perm<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>a<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>last<span class=\"token punctuation\">;</span>\n  <span class=\"token class-name\">pte_t</span> <span class=\"token operator\">*</span>pte<span class=\"token punctuation\">;</span>\n\n  a <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">PGROUNDDOWN</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span>va<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  last <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">PGROUNDDOWN</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span>va<span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> size <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>pte <span class=\"token operator\">=</span> <span class=\"token function\">walkpgdir</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n      <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>pte <span class=\"token operator\">&amp;</span> PTE_P<span class=\"token punctuation\">)</span>\n      <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"remap\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token operator\">*</span>pte <span class=\"token operator\">=</span> pa <span class=\"token operator\">|</span> perm <span class=\"token operator\">|</span> PTE_P<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>a <span class=\"token operator\">==</span> last<span class=\"token punctuation\">)</span>\n      <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    a <span class=\"token operator\">+=</span> PGSIZE<span class=\"token punctuation\">;</span>\n    pa <span class=\"token operator\">+=</span> PGSIZE<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">mappages</code> takes the following five arguments.</p>\n<ul>\n<li><code class=\"language-text\">*pgdir</code>: the allocated page (PDT)</li>\n<li><code class=\"language-text\">*va</code>: the virtual address to create PTEs for</li>\n<li><code class=\"language-text\">size</code>: the size of the physical address range to associate</li>\n<li><code class=\"language-text\">pa</code>: the starting physical address to associate</li>\n<li><code class=\"language-text\">perm</code>: the permissions to assign</li>\n</ul>\n<p>First, based on the virtual address to create PTEs for and the size of the physical-address range to associate, page-aligned addresses are stored in <code class=\"language-text\">a</code> and <code class=\"language-text\">last</code>.</p>\n<p>I already explained <code class=\"language-text\">PGROUNDDOWN</code> in a previous article, so I will skip it here.</p>\n<p>The next loop runs while adding the page size until <code class=\"language-text\">a</code> becomes equal to <code class=\"language-text\">last</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>pte <span class=\"token operator\">=</span> <span class=\"token function\">walkpgdir</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>pte <span class=\"token operator\">&amp;</span> PTE_P<span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"remap\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span>pte <span class=\"token operator\">=</span> pa <span class=\"token operator\">|</span> perm <span class=\"token operator\">|</span> PTE_P<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>a <span class=\"token operator\">==</span> last<span class=\"token punctuation\">)</span> <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n  a <span class=\"token operator\">+=</span> PGSIZE<span class=\"token punctuation\">;</span>\n  pa <span class=\"token operator\">+=</span> PGSIZE<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The function that actually allocates the PTE area is <code class=\"language-text\">walkpgdir</code>.</p>\n<p><code class=\"language-text\">walkpgdir</code> is defined in <code class=\"language-text\">vm.c</code>.</p>\n<p>It returns the address of the PTE in the page table <code class=\"language-text\">pgdir</code> that corresponds to the virtual address passed as an argument.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Return the address of the PTE in page table pgdir</span>\n<span class=\"token comment\">// that corresponds to virtual address va.  If alloc!=0,</span>\n<span class=\"token comment\">// create any required page table pages.</span>\n<span class=\"token keyword\">static</span> <span class=\"token class-name\">pte_t</span> <span class=\"token operator\">*</span> \n<span class=\"token function\">walkpgdir</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">pde_t</span> <span class=\"token operator\">*</span>pgdir<span class=\"token punctuation\">,</span> <span class=\"token keyword\">const</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>va<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> alloc<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token class-name\">pde_t</span> <span class=\"token operator\">*</span>pde<span class=\"token punctuation\">;</span>\n  <span class=\"token class-name\">pte_t</span> <span class=\"token operator\">*</span>pgtab<span class=\"token punctuation\">;</span>\n\n  pde <span class=\"token operator\">=</span> <span class=\"token operator\">&amp;</span>pgdir<span class=\"token punctuation\">[</span><span class=\"token function\">PDX</span><span class=\"token punctuation\">(</span>va<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>pde <span class=\"token operator\">&amp;</span> PTE_P<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    pgtab <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">pte_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span><span class=\"token function\">PTE_ADDR</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>pde<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>alloc <span class=\"token operator\">||</span> <span class=\"token punctuation\">(</span>pgtab <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">pte_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">kalloc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// Make sure all those PTE_P bits are zero.</span>\n    <span class=\"token function\">memset</span><span class=\"token punctuation\">(</span>pgtab<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> PGSIZE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// The permissions here are overly generous, but they can</span>\n    <span class=\"token comment\">// be further restricted by the permissions in the page table</span>\n    <span class=\"token comment\">// entries, if necessary.</span>\n    <span class=\"token operator\">*</span>pde <span class=\"token operator\">=</span> <span class=\"token function\">V2P</span><span class=\"token punctuation\">(</span>pgtab<span class=\"token punctuation\">)</span> <span class=\"token operator\">|</span> PTE_P <span class=\"token operator\">|</span> PTE_W <span class=\"token operator\">|</span> PTE_U<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> <span class=\"token operator\">&amp;</span>pgtab<span class=\"token punctuation\">[</span><span class=\"token function\">PTX</span><span class=\"token punctuation\">(</span>va<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>First, the line <code class=\"language-text\">pde = &amp;pgdir[PDX(va)];</code> resolves the index in the PDT used for the virtual address.</p>\n<p><code class=\"language-text\">PDX(va)</code> is a macro defined in <code class=\"language-text\">mmu.h</code> that resolves the page-directory index from a virtual address.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// A virtual address 'la' has a three-part structure as follows:</span>\n<span class=\"token comment\">//</span>\n<span class=\"token comment\">// +--------10------+-------10-------+---------12----------+</span>\n<span class=\"token comment\">// | Page Directory |   Page Table   | Offset within Page  |</span>\n<span class=\"token comment\">// |      Index     |      Index     |                     |</span>\n<span class=\"token comment\">// +----------------+----------------+---------------------+</span>\n<span class=\"token comment\">//  \\--- PDX(va) --/ \\--- PTX(va) --/</span>\n\n<span class=\"token comment\">// page directory index</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">PDX</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>va<span class=\"token punctuation\">)</span>         <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>va<span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> PDXSHIFT<span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;</span> <span class=\"token number\">0x3FF</span><span class=\"token punctuation\">)</span></span></span>\n\n<span class=\"token comment\">// page table index</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name function\">PTX</span><span class=\"token expression\"><span class=\"token punctuation\">(</span>va<span class=\"token punctuation\">)</span>         <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>va<span class=\"token punctuation\">)</span> <span class=\"token operator\">>></span> PTXSHIFT<span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;</span> <span class=\"token number\">0x3FF</span><span class=\"token punctuation\">)</span></span></span>\n\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">PTXSHIFT</span>        <span class=\"token expression\"><span class=\"token number\">12</span>      </span><span class=\"token comment\">// offset of PTX in a linear address</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">PDXSHIFT</span>        <span class=\"token expression\"><span class=\"token number\">22</span>      </span><span class=\"token comment\">// offset of PDX in a linear address</span></span></code></pre></div>\n<p>Next, the line <code class=\"language-text\">if(*pde &amp; PTE_P)</code> checks the Present bit of the PDE it found.</p>\n<p>The Present bit of a PDE is used to tell whether the page is currently present.</p>\n<p>Reference: <a href=\"https://wiki.osdev.org/Paging\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Paging - OSDev Wiki</a></p>\n<p>Here, it seems to be checking whether a PDE already exists for the virtual address received as an argument.</p>\n<p>In the initial state, the PD has been initialized to 0 by <code class=\"language-text\">memset</code>, so the following code runs.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>alloc <span class=\"token operator\">||</span> <span class=\"token punctuation\">(</span>pgtab <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">pte_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">kalloc</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// Make sure all those PTE_P bits are zero.</span>\n<span class=\"token function\">memset</span><span class=\"token punctuation\">(</span>pgtab<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> PGSIZE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// The permissions here are overly generous, but they can</span>\n<span class=\"token comment\">// be further restricted by the permissions in the page table</span>\n<span class=\"token comment\">// entries, if necessary.</span>\n<span class=\"token operator\">*</span>pde <span class=\"token operator\">=</span> <span class=\"token function\">V2P</span><span class=\"token punctuation\">(</span>pgtab<span class=\"token punctuation\">)</span> <span class=\"token operator\">|</span> PTE_P <span class=\"token operator\">|</span> PTE_W <span class=\"token operator\">|</span> PTE_U<span class=\"token punctuation\">;</span></code></pre></div>\n<p>If the third argument <code class=\"language-text\">alloc</code> is set to 1 and there is no PDE corresponding to the virtual address, the necessary PT is created here.</p>\n<p>I already covered the behavior of <code class=\"language-text\">kalloc</code>, so I will omit it.</p>\n<p>The one-page region obtained here is referenced as <code class=\"language-text\">pgtab</code>.</p>\n<p>It is also initialized to 0 in every byte by <code class=\"language-text\">memset</code>.</p>\n<p>Then the PDE is given the address of <code class=\"language-text\">pgtab</code>, converted to a physical address, together with the permissions to set on the PDE.</p>\n<p>Ultimately, the return value of <code class=\"language-text\">walkpgdir</code> is a reference to the PTE slot resolved from the PDE corresponding to the virtual address received as an argument.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">return</span> <span class=\"token operator\">&amp;</span>pgtab<span class=\"token punctuation\">[</span><span class=\"token function\">PTX</span><span class=\"token punctuation\">(</span>va<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Now that <code class=\"language-text\">walkpgdir</code> has finished, we return to <code class=\"language-text\">mappages</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">;</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>pte <span class=\"token operator\">=</span> <span class=\"token function\">walkpgdir</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>pte <span class=\"token operator\">&amp;</span> PTE_P<span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"remap\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span>pte <span class=\"token operator\">=</span> pa <span class=\"token operator\">|</span> perm <span class=\"token operator\">|</span> PTE_P<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>a <span class=\"token operator\">==</span> last<span class=\"token punctuation\">)</span> <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n  a <span class=\"token operator\">+=</span> PGSIZE<span class=\"token punctuation\">;</span>\n  pa <span class=\"token operator\">+=</span> PGSIZE<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>A PTE slot corresponding to this virtual address has now been allocated in <code class=\"language-text\">pte</code>.</p>\n<p>When <code class=\"language-text\">walkpgdir</code> finishes, every PTE is still zero-initialized, so the line <code class=\"language-text\">*pte = pa | perm | PTE_P;</code> assigns the physical address and permissions.</p>\n<p>With that, <code class=\"language-text\">mappages</code> finishes creating the PTEs that connect virtual addresses and physical addresses.</p>\n<h3 id=\"the-freevm-function\" style=\"position:relative;\"><a href=\"#the-freevm-function\" aria-label=\"the freevm function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The <code class=\"language-text\">freevm</code> function</h3>\n<p>Finally, we return to <code class=\"language-text\">setupkvm</code>.</p>\n<p>The following loop repeated once for each element in the <code class=\"language-text\">kmap</code> array.</p>\n<p><code class=\"language-text\">mappages</code> created the PDEs and PTEs that connect virtual addresses and physical addresses.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>k <span class=\"token operator\">=</span> kmap<span class=\"token punctuation\">;</span> k <span class=\"token operator\">&lt;</span> <span class=\"token operator\">&amp;</span>kmap<span class=\"token punctuation\">[</span><span class=\"token function\">NELEM</span><span class=\"token punctuation\">(</span>kmap<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> k<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">mappages</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>virt<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>phys_end <span class=\"token operator\">-</span> k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span>\n              <span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span>k<span class=\"token operator\">-></span>phys_start<span class=\"token punctuation\">,</span> k<span class=\"token operator\">-></span>perm<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">freevm</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">return</span> pgdir<span class=\"token punctuation\">;</span></code></pre></div>\n<p>If page-table creation fails, <code class=\"language-text\">pgdir</code>, the PDT page used up to this point, is passed to <code class=\"language-text\">freevm</code> and the memory region is freed.</p>\n<p>The <code class=\"language-text\">freevm</code> function is also defined in <code class=\"language-text\">vm.c</code>.</p>\n<p>Since <code class=\"language-text\">freevm</code> is not executed at this point, I will omit the details.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Free a page table and all the physical memory pages</span>\n<span class=\"token comment\">// in the user part.</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">freevm</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">pde_t</span> <span class=\"token operator\">*</span>pgdir<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  uint i<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>pgdir <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"freevm: no pgdir\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">deallocuvm</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">,</span> KERNBASE<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> NPDENTRIES<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">&amp;</span> PTE_P<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span> v <span class=\"token operator\">=</span> <span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span><span class=\"token function\">PTE_ADDR</span><span class=\"token punctuation\">(</span>pgdir<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token function\">kfree</span><span class=\"token punctuation\">(</span>v<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token function\">kfree</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>pgdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"the-switchkvm-function\" style=\"position:relative;\"><a href=\"#the-switchkvm-function\" aria-label=\"the switchkvm function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The <code class=\"language-text\">switchkvm</code> function</h2>\n<p>At this point, <code class=\"language-text\">setupkvm</code> is finished, and it returns the kernel’s PDT.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Allocate one page table for the machine for the kernel address</span>\n<span class=\"token comment\">// space for scheduler processes.</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">kvmalloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  kpgdir <span class=\"token operator\">=</span> <span class=\"token function\">setupkvm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">switchkvm</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>As I confirmed in the first half of this article, on x86 the starting address of the PDT referenced by the kernel is stored in the CR3 register.</p>\n<p>The behavior of <code class=\"language-text\">switchkvm</code> is simple: it converts the virtual address of the created PDT into a physical address and stores it in the CR3 register.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Switch h/w page table register to the kernel-only page table,</span>\n<span class=\"token comment\">// for when no process is running.</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">switchkvm</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token function\">lcr3</span><span class=\"token punctuation\">(</span><span class=\"token function\">V2P</span><span class=\"token punctuation\">(</span>kpgdir<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>   <span class=\"token comment\">// switch to the kernel page table</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The <code class=\"language-text\">lcr3</code> function is defined in <code class=\"language-text\">x86.h</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">static</span> <span class=\"token keyword\">inline</span> <span class=\"token keyword\">void</span>\n<span class=\"token function\">lcr3</span><span class=\"token punctuation\">(</span>uint val<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">asm</span> <span class=\"token keyword\">volatile</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"movl %0,%%cr3\"</span> <span class=\"token operator\">:</span> <span class=\"token operator\">:</span> <span class=\"token string\">\"r\"</span> <span class=\"token punctuation\">(</span>val<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>With that, <code class=\"language-text\">kvmalloc</code> has finished creating and switching the kernel page table.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>With this, I have read 3 of the 18 functions called from the xv6 kernel’s <code class=\"language-text\">main</code> function.</p>\n<p>There is still a long way to go, but I will keep working through it little by little.</p>\n<h2 id=\"reference-books\" style=\"position:relative;\"><a href=\"#reference-books\" aria-label=\"reference books permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reference Books</h2>\n<ul>\n<li><a href=\"https://amzn.to/3qZSCY7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Build an OS in 30 Days!</a></li>\n<li><a href=\"https://amzn.to/3qXYsZX\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Introduction to OS Development from Zero</a></li>\n<li><a href=\"https://amzn.to/3q8TU3K\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">An Introduction to OS Code Reading: Learning Kernel Internals with UNIX V6</a></li>\n<li><a href=\"https://amzn.to/3I6fkVt\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Detailed Linux Kernel</a></li>\n<li><a href=\"https://amzn.to/3JRUdI2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Build and Understand an OS: Theory and Implementation for Running x86 Computers</a></li>\n</ul>","fields":{"slug":"/unix-xv6-005-kernel-main-02-en","tagSlugs":["/tag/unix-en/","/tag/xv-6-en/","/tag/kernel-en/","/tag/os-en/","/tag/english/"]},"frontmatter":{"date":"2022-01-26","description":"I am learning about kernels by reading the source code of the educational OS xv6OS. In this article, I walk through the behavior of the xv6OS kernel's main function.","tags":["Unix (en)","xv6 (en)","Kernel (en)","OS (en)","English"],"title":"Reading xv6OS Thoroughly to Fully Understand the Kernel - Page Tables (PDT/PT) Edition -","socialImage":{"publicURL":"/static/988e06e77b527a3d56e1d03e058a92da/unix-xv6-005-kernel-main-02.png"}}}},"pageContext":{"slug":"/unix-xv6-005-kernel-main-02-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}