<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ARM64 on entangledDEV</title>
        <link>/tags/arm64/</link>
        <description>Recent content in ARM64 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/arm64/index.xml" rel="self" type="application/rss+xml" /><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>
