<?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>/categories/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="/categories/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><item>
            <title>Emulating Ubuntu Server X86_64 on macOS ARM64</title>
            <link>/p/emulating-ubuntu-server-x86_64-on-macos-arm64/</link>
            <pubDate>Tue, 19 Nov 2024 07:31:29 +0000</pubDate>
            <guid>/p/emulating-ubuntu-server-x86_64-on-macos-arm64/</guid>
            <description>&lt;p&gt;ARM processors are becoming more ubiquitous thanks to the introduction of Apple Silicon and Qualcomm Snapdragon. These new processors offer great performance, silent operation, and all-day battery life. On the other hand, not all software is ported to this new architecture, so there could be cases when we need to run or program x86_64 devices.&lt;/p&gt;&#xA;&lt;p&gt;To solve this problem, we have several tools at our disposal. In this post, let&amp;rsquo;s explore one solution to emulate and run x86_64 software.&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;ul&gt;&#xA;&lt;li&gt;An ARM64 machine. In our case, any Apple Silicon Mac would suffice.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://mac.getutm.app&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;UTM App&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Any x86_64 OS ISO. In our case, we&amp;rsquo;re installing &lt;a class=&#34;link&#34; href=&#34;https://ubuntu.com/download/server&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Ubuntu Server 24.10&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;installing-utm&#34;&gt;&lt;a href=&#34;#installing-utm&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Installing UTM&#xA;&lt;/h1&gt;&lt;p&gt;The piece of software that will be doing the work for us is called UTM. This is a macOS app that uses QEMU under the hood for virtualization and emulation.&lt;/p&gt;&#xA;&lt;p&gt;We can get this software 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; or directly from the macOS App Store. I find the former option the best.&lt;/p&gt;&#xA;&lt;p&gt;Choose the option that best suits your needs.&lt;/p&gt;&#xA;&lt;h1 id=&#34;creating-the-emulated-virtual-machine&#34;&gt;&lt;a href=&#34;#creating-the-emulated-virtual-machine&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Creating the emulated Virtual Machine&#xA;&lt;/h1&gt;&lt;p&gt;Once we have UTM installed, let&amp;rsquo;s download the ISO of the operating system we want to emulate. In our case, Ubuntu Server 24.10.&lt;/p&gt;&#xA;&lt;p&gt;Next, let&amp;rsquo;s open UTM and click on &lt;code&gt;Create a New Virtual Machine&lt;/code&gt;. Here, we just need to select emulation, select the downloaded ISO, and configure the virtualized hardware. The process is quite straightforward.&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/emulate-x86-on-arm/utm-step1.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;Step 1&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/emulate-x86-on-arm/utm-step2.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;Step 2&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/emulate-x86-on-arm/utm-step3.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;Step 3&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/emulate-x86-on-arm/utm-step4.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;Step 4&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/emulate-x86-on-arm/utm-step5.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;Step 5&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/emulate-x86-on-arm/utm-step6.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;Step 6&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;/posts/emulate-x86-on-arm/utm-step7.png&#34;&#xA;        loading=&#34;lazy&#34;&#xA;        &#xA;            alt=&#34;Step 7&#34;&#xA;        &#xA;    &gt;&lt;/p&gt;&#xA;&lt;p&gt;In the last screen, you can view the summary of the VM. If this looks good to you, press Create and start the VM on the main UTM window.&lt;/p&gt;&#xA;&lt;p&gt;This will start the normal installation of the selected OS using the provided ISO.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a good idea to install OpenSSH for Ubuntu Server.&lt;/p&gt;&#xA;&lt;h1 id=&#34;configuring-ssh&#34;&gt;&lt;a href=&#34;#configuring-ssh&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Configuring SSH&#xA;&lt;/h1&gt;&lt;p&gt;Once we are logged into our VM, we can start configuring SSH. This will allow us to access our VM from our host OS and connect via VSCode to start programming.&lt;/p&gt;&#xA;&lt;p&gt;First, we need to create our SSH key. For that, we can follow the GitHub tutorial &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Once we have the SSH key ready, we can connect to the VM.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The previously added SSH server list is located in &lt;code&gt;~/.ssh/config&lt;/code&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;On VM, get the IP address using &lt;code&gt;ip a&lt;/code&gt;. The IP should look similar to &lt;code&gt;inet 192.168.1.10/24&lt;/code&gt; (we don&amp;rsquo;t need the ending &lt;code&gt;/24&lt;/code&gt; part, just the numbers).&lt;/li&gt;&#xA;&lt;li&gt;On macOS terminal, shh into the vm machine using &lt;code&gt;ssh username@vm_ip_address&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;If your VM doesn&amp;rsquo;t have OpenSSL installed, run the following inside your VM &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install openssh-server &amp;amp;&amp;amp; sudo systemctl start ssh &amp;amp;&amp;amp; sudo systemctl enable ssh &amp;amp;&amp;amp; sudo systemctl status ssh&lt;/code&gt;. This will install SSH, run it, enable it on startup, and check its current status.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h1 id=&#34;coding-an-asm-example-with-vscode&#34;&gt;&lt;a href=&#34;#coding-an-asm-example-with-vscode&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Coding an ASM example with VSCode&#xA;&lt;/h1&gt;&lt;p&gt;Now it&amp;rsquo;s time to do some x86_64 ASM to verify that our system is working properly.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Open VSCode and click on the lower left blue icon &lt;code&gt;&amp;gt;&amp;lt;&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Select &lt;code&gt;+ Add New SSH Host...&lt;/code&gt; and add your VM host parameters using this structure &lt;code&gt;ssh username@vm_ip_address&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Select the configuration file to save your new host (the first option is okay).&lt;/li&gt;&#xA;&lt;li&gt;Once the host is added, click on &lt;code&gt;Connect&lt;/code&gt;. (On macOS, you may need to give VSCode permission to access the network, allow it, and press retry).&lt;/li&gt;&#xA;&lt;li&gt;Wait for the VSCode server to install on the VM.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Now that everything is ready, let&amp;rsquo;s make a hello world!&lt;/p&gt;&#xA;&lt;p&gt;Open VSCode integrated terminal (&lt;kbd&gt;CMD&lt;/kbd&gt; + &lt;kbd&gt;BACKTICK&lt;/kbd&gt;) and create a new file called &lt;code&gt;hello.asm&lt;/code&gt; (use &lt;code&gt;touch hello.asm&lt;/code&gt; to create the file and &lt;code&gt;code hello.asm&lt;/code&gt; to open the file on VSCode) with the following content:&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-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;section&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.data&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;msg&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;World&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0xA&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;; Message to print with newline&#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;nf&#34;&gt;len&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;equ&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;msg&lt;/span&gt;              &lt;span class=&#34;c1&#34;&gt;; Length of the message&#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;nf&#34;&gt;section&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;.text&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;global&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;_start&lt;/span&gt;                &lt;span class=&#34;c1&#34;&gt;; Entry point for the program&#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;nl&#34;&gt;_start:&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;mov&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;                   &lt;span class=&#34;c1&#34;&gt;; sys_write system call (1)&#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;nf&#34;&gt;mov&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;rdi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;                   &lt;span class=&#34;c1&#34;&gt;; File descriptor (stdout)&#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;nf&#34;&gt;mov&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;rsi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;msg&lt;/span&gt;                 &lt;span class=&#34;c1&#34;&gt;; Address of the message&#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;nf&#34;&gt;mov&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;rdx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;len&lt;/span&gt;                 &lt;span class=&#34;c1&#34;&gt;; Length of the message&#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;nf&#34;&gt;syscall&lt;/span&gt;                      &lt;span class=&#34;c1&#34;&gt;; Make the system call&#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;nf&#34;&gt;mov&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;60&lt;/span&gt;                  &lt;span class=&#34;c1&#34;&gt;; sys_exit system call (60)&#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;nf&#34;&gt;xor&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;rdi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;rdi&lt;/span&gt;                 &lt;span class=&#34;c1&#34;&gt;; Exit code 0&#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;nf&#34;&gt;syscall&lt;/span&gt;                      &lt;span class=&#34;c1&#34;&gt;; Make the system call&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Before continuing, install the assembler using &lt;code&gt;sudo apt install nasm&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Now let&amp;rsquo;s run the program!&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;# Assembling the code&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nasm -f elf64 hello.asm -o hello.o&#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;# Linking the code&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ld hello.o -o hello&#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;# Running the code&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./hello&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If all went well, you should see on the integrated terminal the text &lt;code&gt;Hello, World!&lt;/code&gt;. Congratulations, your emulated x86_64 system is working correctly!&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;ARM processors have revolutionized the computing landscape with their efficiency, performance, and battery life, making them an excellent choice for modern devices. However, their growing adoption doesn&amp;rsquo;t eliminate the need to run or develop software for the x86_64 architecture. With tools like UTM, we can easily emulate x86_64 systems on ARM-based devices, such as Apple Silicon Macs.&lt;/p&gt;&#xA;&lt;p&gt;This post guided you through the process of setting up UTM, creating a virtual machine, configuring SSH, and even running an x86_64 assembly program. By following these steps, you&amp;rsquo;ve not only learned how to emulate a different architecture but also created a functional environment for programming and development.&lt;/p&gt;&#xA;&lt;p&gt;The flexibility of emulation tools bridges the gap between architectures, ensuring that developers can maintain productivity regardless of the hardware they are using. This workflow demonstrates how we can adapt to and leverage the best of both ARM and x86_64 worlds. Happy coding!&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
