<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Virtualization on entangledDEV</title>
        <link>/tags/virtualization/</link>
        <description>Recent content in Virtualization on entangledDEV</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Sun, 01 Feb 2026 00:09:25 -0600</lastBuildDate><atom:link href="/tags/virtualization/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>101 Guide To Microcontroller Programming Inside Virtual Machines</title>
            <link>/p/101-guide-to-microcontroller-programming-inside-virtual-machines/</link>
            <pubDate>Mon, 25 Nov 2024 03:21:54 +0000</pubDate>
            <guid>/p/101-guide-to-microcontroller-programming-inside-virtual-machines/</guid>
            <description>&lt;h1 id=&#34;introduction&#34;&gt;&lt;a href=&#34;#introduction&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Introduction&#xA;&lt;/h1&gt;&lt;p&gt;Hey everyone, I&amp;rsquo;m back with a new entry. This time, I&amp;rsquo;d like to guide you on how to create a simple hello world program for the ESP32-C6 inside a Virtual Machine.&lt;/p&gt;&#xA;&lt;p&gt;Having all the toolchain inside a VM is a great way to unclutter your host machine. Programming inside a VM or containers for web development is quite common, but for microcontrollers, it&amp;rsquo;s a thing I don&amp;rsquo;t encounter that often.&lt;/p&gt;&#xA;&lt;h1 id=&#34;what-we-need&#34;&gt;&lt;a href=&#34;#what-we-need&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;What we need&#xA;&lt;/h1&gt;&lt;p&gt;For this tutorial, we will need:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Fedora Server 41 ARM&lt;/li&gt;&#xA;&lt;li&gt;UTM&lt;/li&gt;&#xA;&lt;li&gt;ESP32-C6&lt;/li&gt;&#xA;&lt;li&gt;USB-C cable&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;creating-the-virtual-machine&#34;&gt;&lt;a href=&#34;#creating-the-virtual-machine&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Creating the Virtual Machine&#xA;&lt;/h1&gt;&lt;p&gt;Let&amp;rsquo;s start by creating the Virtual Machine. To archive this, you need a software capable of virtualizing your OS environment. Get UTM from the macOS Apple Store or directly from their &lt;a class=&#34;link&#34; href=&#34;https://mac.getutm.app&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;website&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;We also need to get the ISO we are going to use to create the VM. In this tutorial, we are using Fedora Server. Download the ARM ISO from &lt;a class=&#34;link&#34; href=&#34;https://fedoraproject.org/server/download&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;We will follow similar steps to install the OS similar to the ones on &lt;a class=&#34;link&#34; href=&#34;/p/emulating-ubuntu-server-x86_64-on-macos-arm64/&#34; &gt;this post&lt;/a&gt; I made some time ago. We can follow along, with the difference that &lt;strong&gt;we are selecting Virtualize this time&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Once the OS is ready and SSH is working, let&amp;rsquo;s install the dependencies!&lt;/p&gt;&#xA;&lt;h1 id=&#34;installing-dependencies-inside-the-vm&#34;&gt;&lt;a href=&#34;#installing-dependencies-inside-the-vm&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Installing dependencies inside the VM&#xA;&lt;/h1&gt;&lt;p&gt;Once you&amp;rsquo;re inside the VM, let&amp;rsquo;s run the following commands:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Update the virtual OS&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo dnf update -y&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Installing the needed software&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo dnf install -y python3 python3-pip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Install the udev needed to connect to the microcontrollers&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sudo tee /etc/udev/rules.d/99-platformio-udev.rules&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Install PlatformIO Core CLI&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py python3 get-platformio.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&#xA;&lt;p&gt;We are using the PlatformIO CLI because the graphical interface installed by the plugin doesn&amp;rsquo;t work by default inside the VM. As a workaround, you could run &lt;code&gt;pio home --host 0.0.0.0 --port 8008&lt;/code&gt; to access the VSCode plugin GUI interface from your host browser.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h1 id=&#34;creating-our-basic-project-template&#34;&gt;&lt;a href=&#34;#creating-our-basic-project-template&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Creating our basic project template&#xA;&lt;/h1&gt;&lt;p&gt;Once we have finished installing the tooling, we can start creating our hello world project.&lt;/p&gt;&#xA;&lt;p&gt;As a first step, let&amp;rsquo;s activate the Python environment created by PlatformIO, to achieve that run:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Activate the Python environment for PlatformIO&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; ~/.platformio/penv/bin/activate&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then let&amp;rsquo;s create our project, navigate to the directory where you want to host the project, and run the following:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Find the name of your microcontroller from the supported list, copy this name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pio boards &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;s2&#34;&gt;&amp;#34;YOUR_BOARD_NAME_HERE&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# We use pio to create the basic template project&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pio project init --project-dir . --board &lt;span class=&#34;s2&#34;&gt;&amp;#34;YOUR_BOARD_NAME_HERE&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Open your project in VSCode&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;code .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As simple as that, we have our base project ready for us, now let&amp;rsquo;s do some code!&lt;/p&gt;&#xA;&lt;h1 id=&#34;programming-the-hello-world&#34;&gt;&lt;a href=&#34;#programming-the-hello-world&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Programming the Hello World&#xA;&lt;/h1&gt;&lt;p&gt;Once you have opened the project, open the file called &lt;code&gt;main.c&lt;/code&gt; located inside &lt;code&gt;/src/&lt;/code&gt; and add the following:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;freertos/FreeRTOS.h&amp;#34;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;#34;freertos/task.h&amp;#34;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;app_main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Hello world&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;vTaskDelay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;portTICK_PERIOD_MS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&#xA;&lt;p&gt;The ESP32-C6 is an ARM device, so we are using the Espressif framework instead of the Arduino framework. Check with your manufacturer the type of architecture your board uses.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This program will print to the serial bus the string &lt;code&gt;Hello world\n&lt;/code&gt; every second.&lt;/p&gt;&#xA;&lt;p&gt;We also need to specify the baud rate so that we can monitor the output correctly. Open the file called &lt;code&gt;platformio.ini&lt;/code&gt; and append at the end the following line:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;monitor_speed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;115200&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With all this done, we are one step closer to seeing our awesome code working!&lt;/p&gt;&#xA;&lt;h1 id=&#34;compiling-flashing-and-monitoring-the-microcontroller&#34;&gt;&lt;a href=&#34;#compiling-flashing-and-monitoring-the-microcontroller&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Compiling, flashing, and monitoring the microcontroller&#xA;&lt;/h1&gt;&lt;p&gt;Now it&amp;rsquo;s time to connect our board via USB to the VM:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Connect the board using USB to your host machine.&lt;/li&gt;&#xA;&lt;li&gt;Open the VM window in UTM and, in the top right, press the USB plug icon and connect your board to the VM.&lt;/li&gt;&#xA;&lt;li&gt;Check that the board is read by Fedora by running &lt;code&gt;lsusb&lt;/code&gt;. You should see the same name that appeared on the UTM menu.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;We can use the PlatformIO extension to make the next steps easier. &lt;a class=&#34;link&#34; href=&#34;https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Install the extension inside the VM&lt;/a&gt;. After reloading, you will see at the bottom left these 3 icons: check mark, right arrow, and electric plug.&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/microcontroller-programming-inside-vm/pio-buttons.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;PIO Buttons&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;Now let&amp;rsquo;s do the final steps!&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Press the check mark to build the project.&lt;/li&gt;&#xA;&lt;li&gt;Press the right arrow to flash your board (some boards may need to press some buttons on the board to activate the flash mode).&lt;/li&gt;&#xA;&lt;li&gt;Press the electric plug icon to see the &lt;code&gt;hello world&lt;/code&gt; string being sent to the serial monitor every second!&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Congratulations, now you can start developing inside a VM for your microcontrollers.&lt;/p&gt;&#xA;&lt;h1 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Conclusion&#xA;&lt;/h1&gt;&lt;p&gt;Developing for microcontrollers inside a virtual machine not only helps keep your host system clean and organized but also creates a portable and reproducible development environment. By following this guide, you’ve set up a Fedora Server VM with all the necessary tools to program an ESP32-C6, created a basic “Hello World” project, and successfully flashed it to your board.&lt;/p&gt;&#xA;&lt;p&gt;This approach combines the flexibility of modern tools like PlatformIO with the advantages of virtualization, providing a robust setup for any microcontroller project. Whether you’re just starting with embedded systems or looking for a cleaner workflow, this method proves that virtual machines are a practical solution for microcontroller development.&lt;/p&gt;&#xA;&lt;p&gt;Now that you’ve mastered the basics, you can explore more complex projects, experiment with different boards, or even automate your setup further. Happy coding, and enjoy building your next microcontroller masterpiece!&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
