<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>0x646b - xv6</title>
    <subtitle>Personal Commentary</subtitle>
    <link rel="self" type="application/atom+xml" href="https://Karthik-d-k.github.io/tags/xv6/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://Karthik-d-k.github.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-26T00:00:00+00:00</updated>
    <id>https://Karthik-d-k.github.io/tags/xv6/atom.xml</id>
    <entry xml:lang="en">
        <title>RISC-V Startup Code</title>
        <published>2026-06-26T00:00:00+00:00</published>
        <updated>2026-06-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Karthik
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://Karthik-d-k.github.io/blog/riscv-startup-code/"/>
        <id>https://Karthik-d-k.github.io/blog/riscv-startup-code/</id>
        
        <content type="html" xml:base="https://Karthik-d-k.github.io/blog/riscv-startup-code/">&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;I work with different microcontroller boards day to day. My job is to write startup code in Rust for board bring-up,
especially RISC-V cores and to write, generate, and maintain the Peripheral Access Crate (PAC) for each RISC-V SoC.&lt;&#x2F;p&gt;
&lt;p&gt;Working this low in the stack, I wanted to write down what actually makes a
RISC-V core come alive and run our code. Concretely:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What is already true when the board powers on or resets?&lt;&#x2F;li&gt;
&lt;li&gt;What does the hardware hand us for free, and what must we set up ourselves?&lt;&#x2F;li&gt;
&lt;li&gt;How do we make the hardware do what we want, purely from software?&lt;&#x2F;li&gt;
&lt;li&gt;What has to be in place before we can call our first Rust function?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’ll answer these using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mit-pdos&#x2F;xv6-riscv&quot;&gt;xv6&lt;&#x2F;a&gt;, a small teaching OS that targets a 64-bit RISC-V core
and runs on QEMU. Its boot path is the same bare-metal bring-up problem I deal with every day - set up a stack, place code and data, pick a privilege level, jump to our code - just unusually well documented, which makes it a great thing to learn from.&lt;&#x2F;p&gt;
&lt;p&gt;This post follows only the path from &lt;code&gt;power-on&lt;&#x2F;code&gt; to the main Rust function (&lt;code&gt;main&lt;&#x2F;code&gt;); everything the kernel does after that
is for a later post.&lt;&#x2F;p&gt;
&lt;p&gt;I’m porting xv6 from C to Rust to learn real OS concepts by building one, reading the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mit-pdos&#x2F;xv6-riscv&quot;&gt;C source&lt;&#x2F;a&gt; alongside the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mit-pdos&#x2F;xv6-riscv-book&quot;&gt;xv6 book&lt;&#x2F;a&gt;. You can find my &lt;strong&gt;in-progress&lt;&#x2F;strong&gt; port on GitHub: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Karthik-d-k&#x2F;xv6rs&quot;&gt;xv6rs&lt;&#x2F;a&gt;. Every code snippet in this post is taken from that repo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-v-eei&quot;&gt;RISC-V EEI&lt;&#x2F;h2&gt;
&lt;p&gt;EEI stands for &lt;strong&gt;Execution Environment Interface&lt;&#x2F;strong&gt;, defined by the RISC-V Unprivileged spec.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A RISC-V core is defined to have its own Instruction Fetch Unit and each core might support multiple RISC-V-compatible hardware threads, or harts, through multithreading.&lt;&#x2F;li&gt;
&lt;li&gt;RISC-V defines up to three &lt;strong&gt;privilege levels&lt;&#x2F;strong&gt;: Machine (M), Supervisor (S), and User (U), most to least privileged.
Only M is mandatory; S and U are optional. The xv6 target implements all three.&lt;&#x2F;li&gt;
&lt;li&gt;An EEI is the contract a layer offers to the software above it: it pins down the &lt;strong&gt;initial state, the harts, the memory and I&#x2F;O regions, instruction behavior, and how traps and &lt;code&gt;ecall&lt;&#x2F;code&gt; are handled&lt;&#x2F;strong&gt; - to have defined behavior for the running software.&lt;&#x2F;li&gt;
&lt;li&gt;Crucially, the EEI is &lt;strong&gt;relative&lt;&#x2F;strong&gt;: it depends on which level you run at. For M-mode software the EEI is the hardware platform itself
(which begins at power-on reset); for S-mode software, M-mode sets up the EEI; and so on up the stack.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;See the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;unpriv&#x2F;unpriv-index.html&quot;&gt;RISC-V Unprivileged spec&lt;&#x2F;a&gt; for the full definition.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;program-s-entry-point&quot;&gt;Program’s Entry Point&lt;&#x2F;h2&gt;
&lt;p&gt;xv6 operating system runs on RISC-V multiprocessor under QEMU. So QEMU sets up EEI for us, such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Loads kernel at address &lt;code&gt;0x80000000&lt;&#x2F;code&gt;, where DRAM is present&lt;&#x2F;li&gt;
&lt;li&gt;Initial values of DRAM will be &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Starting privilege level will be set to &lt;code&gt;M&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Hart numbers are incremental and start from &lt;code&gt;0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With the combination of linker script and assembly, we will set our program to start from address &lt;code&gt;0x80000000&lt;&#x2F;code&gt;.
In theory we could have done this using Rust instead of assembly, but compiled Rust code, like C, assumes some things are already set up when any function is called like a valid stack pointer, a zeroed &lt;code&gt;.bss&lt;&#x2F;code&gt; and an initialized &lt;code&gt;.data&lt;&#x2F;code&gt; section. Here we are starting from garbage state w.r.t. QEMU, we will use assembly to set this up so that we could use Rust functions later.&lt;&#x2F;p&gt;
&lt;p&gt;As DRAM is filled with 0’s, we need not clear the &lt;code&gt;.bss&lt;&#x2F;code&gt; section and we need not move contents from Flash to RAM for the &lt;code&gt;.data&lt;&#x2F;code&gt; section as it will already be in DRAM. So the only thing missing is setting a valid stack pointer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;entry.rs&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rs &quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;core::arch::global_asm;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;global_asm!(
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    .section .text.entry
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    .global _entry
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    _entry:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            la sp, stack0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            csrr a1, mhartid
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            addi a1, a1, 1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            slli a0, a1, 12       # `li a0, 4096`; `mul a0, a0, a1`;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            add sp, sp, a0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            call start
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;kernel.x&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ld&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-ld &quot;&gt;&lt;code class=&quot;language-ld&quot; data-lang=&quot;ld&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;OUTPUT_ARCH&lt;&#x2F;span&gt;&lt;span&gt;( &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&amp;quot;riscv&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; )
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ENTRY&lt;&#x2F;span&gt;&lt;span&gt;( &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;_entry&lt;&#x2F;span&gt;&lt;span&gt; )
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;SECTIONS
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt; = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x80000000&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.text&lt;&#x2F;span&gt;&lt;span&gt; : {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;KEEP&lt;&#x2F;span&gt;&lt;span&gt;(*(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.text.entry&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;    *(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.text .text.&lt;&#x2F;span&gt;&lt;span&gt;*)
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.bss&lt;&#x2F;span&gt;&lt;span&gt; : {
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt; = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ALIGN&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;  *(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;.bss.stack0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;start.rs&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rs &quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span&gt;(no_mangle)]
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span&gt;(link_section = &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.bss.stack0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;static mut&lt;&#x2F;span&gt;&lt;span&gt; stack0: [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u8&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4096 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;NCPU&lt;&#x2F;span&gt;&lt;span&gt;] = [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4096 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;NCPU&lt;&#x2F;span&gt;&lt;span&gt;]; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; NCPU: No of CPU&amp;#39;s
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In &lt;code&gt;kernel.x&lt;&#x2F;code&gt;, we are setting start address to &lt;code&gt;0x80000000&lt;&#x2F;code&gt; and also we are keeping all symbols from &lt;code&gt;.text.entry&lt;&#x2F;code&gt; section at this address.
As we only have &lt;code&gt;_entry&lt;&#x2F;code&gt; symbol in this section (see &lt;code&gt;entry.rs&lt;&#x2F;code&gt;), the first instruction of our program is &lt;code&gt;la sp, stack0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;stack0&lt;&#x2F;code&gt; is declared in &lt;code&gt;start.rs&lt;&#x2F;code&gt; file, which is placed in &lt;code&gt;.bss&lt;&#x2F;code&gt; section. It should have 16-byte alignment according to RISC-V spec which is enforced by linker script.&lt;&#x2F;li&gt;
&lt;li&gt;Each hart will get &lt;code&gt;4 KiB of stack&lt;&#x2F;code&gt;, we are using &lt;code&gt;mhartid&lt;&#x2F;code&gt; register (remember QEMU should set this as per EEI’s contract) to get the hart id.&lt;&#x2F;li&gt;
&lt;li&gt;Once the stack is set up, we &lt;code&gt;call start&lt;&#x2F;code&gt;. The C version follows this with a &lt;code&gt;spin: j spin&lt;&#x2F;code&gt; loop as a safety net; I leave it out because our &lt;code&gt;start&lt;&#x2F;code&gt; is marked &lt;code&gt;-&amp;gt; !&lt;&#x2F;code&gt; and never returns.&lt;&#x2F;li&gt;
&lt;li&gt;C version uses &lt;code&gt;mul&lt;&#x2F;code&gt; instruction instead of shift instruction &lt;code&gt;slli&lt;&#x2F;code&gt; that we are using to calculate &lt;code&gt;sp = stack0 + ((hartid + 1) * 4096)&lt;&#x2F;code&gt;, the reason for this change on the Rust side is a known limitation in how target features reach the assembler for hand-written asm. If we use &lt;code&gt;mul a0, a0, a1&lt;&#x2F;code&gt;, the assembler will throw the following error:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;error: mul instruction requires the following: ‘Zmmul’ (Integer Multiplication)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Even though we are targeting &lt;strong&gt;&lt;code&gt;riscv64gc-unknown-none-elf&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; which has multiplication support, that feature isn’t automatically applied to the assembler for hand-written &lt;code&gt;global_asm!&lt;&#x2F;code&gt;, so this will not compile.
We could solve this issue by using &lt;code&gt;.option arch, +m&lt;&#x2F;code&gt;, but I just showed you how we could avoid &lt;code&gt;mul&lt;&#x2F;code&gt; altogether by just using a base instruction (i.e., shift).
You can find more details about this &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-embedded&#x2F;riscv&#x2F;blob&#x2F;fec25a239b707eedf58e6ade7078af17d6482190&#x2F;riscv-target-parser&#x2F;src&#x2F;lib.rs#L205&quot;&gt;here&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sourceware.org&#x2F;binutils&#x2F;docs-2.35&#x2F;as&#x2F;RISC_002dV_002dDirectives.html&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;s-mode-kernel&quot;&gt;S-Mode Kernel&lt;&#x2F;h2&gt;
&lt;p&gt;xv6 kernel runs in S-mode whereas user programs run in U-mode. Now that we are in M-mode by default, we will use a function named &lt;code&gt;start&lt;&#x2F;code&gt; which we are calling at the end of assembly code to set up relevant things in M-mode and then we transition to S-mode.&lt;&#x2F;p&gt;
&lt;p&gt;The following things have to be set in xv6 during M-S mode transition:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Set Previous privilege mode to &lt;code&gt;S&lt;&#x2F;code&gt;, so that when we call &lt;code&gt;mret&lt;&#x2F;code&gt;, it transitions to S-mode.&lt;&#x2F;li&gt;
&lt;li&gt;Set Exception Program counter to our &lt;code&gt;main&lt;&#x2F;code&gt; function.&lt;&#x2F;li&gt;
&lt;li&gt;Disable paging (&lt;code&gt;satp = 0&lt;&#x2F;code&gt;, Bare mode) so that S-mode starts out using physical addresses. Paging applies to S-mode too once enabled - the kernel will run on virtual addresses through a page table we set up in a later post. (Unrestricted access to &lt;em&gt;physical&lt;&#x2F;em&gt; memory comes separately, from PMP)&lt;&#x2F;li&gt;
&lt;li&gt;Delegate all interrupts and exceptions to S-mode, so that traps will be handled by S-mode handlers instead of M-mode.&lt;&#x2F;li&gt;
&lt;li&gt;Configure PMP (Physical Memory Protection) to give S-mode access to all of physical memory, so that kernel has unrestricted access to all I&#x2F;O and peripherals.&lt;&#x2F;li&gt;
&lt;li&gt;Enable&#x2F;Configure timer interrupts for scheduling purposes.&lt;&#x2F;li&gt;
&lt;li&gt;Keep each hart’s id in &lt;code&gt;tp&lt;&#x2F;code&gt; register, so that we can tell which hart we’re running on to index per-CPU data).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;start.rs&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rs &quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span&gt;(no_mangle)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub extern &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;start&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; ! {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; x: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;r_mstatus&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    x &amp;amp;= !&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;MSTATUS_MPP_MASK&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    x |= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;MSTATUS_MPP_S&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_mstatus&lt;&#x2F;span&gt;&lt;span&gt;(x);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_mepc&lt;&#x2F;span&gt;&lt;span&gt;(main as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;*const &lt;&#x2F;span&gt;&lt;span&gt;() as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_satp&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_medeleg&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0xffff&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_mideleg&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0xffff&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_sie&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;r_sie&lt;&#x2F;span&gt;&lt;span&gt;() | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;SIE_SEIE &lt;&#x2F;span&gt;&lt;span&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;SIE_STIE&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_pmpaddr0&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x3fffffffffffff&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_pmpcfg0&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0xf&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;timerinit&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; id: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u64 &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;r_mhartid&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_tp&lt;&#x2F;span&gt;&lt;span&gt;(id);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        asm!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;mret&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;options&lt;&#x2F;span&gt;&lt;span&gt;(noreturn));
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ask each hart to generate timer interrupts.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;timerinit&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_mie&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;r_mie&lt;&#x2F;span&gt;&lt;span&gt;() | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;MIE_STIE&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_menvcfg&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;r_menvcfg&lt;&#x2F;span&gt;&lt;span&gt;() | (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;63&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_mcounteren&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;r_mcounteren&lt;&#x2F;span&gt;&lt;span&gt;() | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;w_stimecmp&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;r_time&lt;&#x2F;span&gt;&lt;span&gt;() + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1000000&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;main-function&quot;&gt;main function&lt;&#x2F;h2&gt;
&lt;p&gt;Once &lt;code&gt;mret&lt;&#x2F;code&gt; instruction at the end of &lt;code&gt;start&lt;&#x2F;code&gt; function is executed, we will fall into S-mode and jump to &lt;code&gt;main&lt;&#x2F;code&gt; function because &lt;code&gt;mepc&lt;&#x2F;code&gt; is set to &lt;code&gt;main&lt;&#x2F;code&gt; and &lt;code&gt;MPP&lt;&#x2F;code&gt; is set to &lt;code&gt;S&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;main.rs&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rs&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rs &quot;&gt;&lt;code class=&quot;language-rs&quot; data-lang=&quot;rs&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;unsafe&lt;&#x2F;span&gt;&lt;span&gt;(no_mangle)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub extern &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; ! {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{ core::arch::asm!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;wfi&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) }
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For now &lt;code&gt;main&lt;&#x2F;code&gt; just parks each hart in a low-power &lt;code&gt;wfi&lt;&#x2F;code&gt; loop; we don’t handle traps yet, so it just loops. In further posts I will explain how we could add &lt;code&gt;UART&lt;&#x2F;code&gt; to this and print some helpful messages from each core.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;running-on-qemu&quot;&gt;Running on QEMU&lt;&#x2F;h2&gt;
&lt;p&gt;Here comes the juicy part i.e., actually running our kernel and verifying that our kernel boots and runs &lt;code&gt;main&lt;&#x2F;code&gt; function from all 3 cores.&lt;&#x2F;p&gt;
&lt;p&gt;Follow the below steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Checkout my repo at specified commit hash&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span&gt; git clone https:&#x2F;&#x2F;github.com&#x2F;Karthik-d-k&#x2F;xv6rs.git
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span&gt; cd xv6rs&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span&gt; git checkout 99b67fe8db4a7d50033a612a0902c9444caa32c3
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;In terminal 1, Run QEMU&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span&gt; just qemu-gdb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;In terminal 2, Run GDB&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;❯&lt;&#x2F;span&gt;&lt;span&gt; just gdb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Verify our kernel in GDB terminal&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) continue
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Continuing.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;^C               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Press Ctrl+C to interrupt the program and then inspect
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Thread&lt;&#x2F;span&gt;&lt;span&gt; 3 received signal SIGINT, Interrupt.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[Switching&lt;&#x2F;span&gt;&lt;span&gt; to Thread 1.3]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;0x0000000080000020&lt;&#x2F;span&gt;&lt;span&gt; in kernel::main () &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;at&lt;&#x2F;span&gt;&lt;span&gt; kernel&#x2F;src&#x2F;main.rs:23
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;              unsafe { core::arch::asm!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;wfi&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) }
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) info threads
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Id&lt;&#x2F;span&gt;&lt;span&gt;   Target Id                    Frame
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;    Thread 1.1 (CPU#0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;running&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;0x0000000080000020&lt;&#x2F;span&gt;&lt;span&gt; in kernel::main ()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;at&lt;&#x2F;span&gt;&lt;span&gt; kernel&#x2F;src&#x2F;main.rs:23
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;    Thread 1.2 (CPU#1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;running&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;0x0000000080000020&lt;&#x2F;span&gt;&lt;span&gt; in kernel::main ()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;at&lt;&#x2F;span&gt;&lt;span&gt; kernel&#x2F;src&#x2F;main.rs:23
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; 3    Thread 1.3 (CPU#2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;running&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;0x0000000080000020&lt;&#x2F;span&gt;&lt;span&gt; in kernel::main ()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;at&lt;&#x2F;span&gt;&lt;span&gt; kernel&#x2F;src&#x2F;main.rs:23
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) thread 1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[Switching&lt;&#x2F;span&gt;&lt;span&gt; to thread 1 (Thread 1.1)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#0  0x0000000080000020 in kernel::main () at kernel&#x2F;src&#x2F;main.rs:23
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;              unsafe { core::arch::asm!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;wfi&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) }
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) info reg pc tp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pc&lt;&#x2F;span&gt;&lt;span&gt;             0x80000020       0x80000020 &amp;lt;kernel::main+4&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tp&lt;&#x2F;span&gt;&lt;span&gt;             0x0      0x0
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) thread 2
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[Switching&lt;&#x2F;span&gt;&lt;span&gt; to thread 2 (Thread 1.2)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#0  0x0000000080000020 in kernel::main () at kernel&#x2F;src&#x2F;main.rs:23
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;              unsafe { core::arch::asm!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;wfi&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) }
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) info reg pc tp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pc&lt;&#x2F;span&gt;&lt;span&gt;             0x80000020       0x80000020 &amp;lt;kernel::main+4&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tp&lt;&#x2F;span&gt;&lt;span&gt;             0x1      0x1
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) thread 3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[Switching&lt;&#x2F;span&gt;&lt;span&gt; to thread 3 (Thread 1.3)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#0  0x0000000080000020 in kernel::main () at kernel&#x2F;src&#x2F;main.rs:23
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;              unsafe { core::arch::asm!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;wfi&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) }
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gdb&lt;&#x2F;span&gt;&lt;span&gt;) info reg pc tp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pc&lt;&#x2F;span&gt;&lt;span&gt;             0x80000020       0x80000020 &amp;lt;kernel::main+4&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tp&lt;&#x2F;span&gt;&lt;span&gt;             0x2      0x2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Each core&#x2F;thread&#x2F;hart is looping at &lt;code&gt;main&lt;&#x2F;code&gt; and its respective &lt;code&gt;tp&lt;&#x2F;code&gt; registers are set to &lt;code&gt;0&#x2F;1&#x2F;2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;unpriv&#x2F;unpriv-index.html&quot;&gt;RISC-V Unprivileged Spec&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;priv&#x2F;priv-index.html&quot;&gt;RISC-V Privileged Spec&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mit-pdos&#x2F;xv6-riscv-book&quot;&gt;xv6 RISC-V Book&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mit-pdos&#x2F;xv6-riscv&quot;&gt;xv6 RISC-V Source code&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Karthik-d-k&#x2F;xv6rs&quot;&gt;My xv6rs repo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
