<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.8.5">Jekyll</generator><link href="https://www.malachid.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.malachid.com/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-01-18T17:31:46-08:00</updated><id>https://www.malachid.com/feed.xml</id><title type="html">malachid</title><subtitle>Malachi de &amp;AElig;lfweald
</subtitle><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><entry><title type="html">Upgrade Framework with NVIDIA</title><link href="https://www.malachid.com/blog/2025-12-26-fw-nvidia/" rel="alternate" type="text/html" title="Upgrade Framework with NVIDIA" /><published>2025-12-26T18:56:48-08:00</published><updated>2025-12-26T18:56:48-08:00</updated><id>https://www.malachid.com/blog/fw-nvidia</id><content type="html" xml:base="https://www.malachid.com/blog/2025-12-26-fw-nvidia/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#ordering-process-and-timeline&quot; id=&quot;markdown-toc-ordering-process-and-timeline&quot;&gt;Ordering Process and Timeline&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#upgrading-the-power-adapter&quot; id=&quot;markdown-toc-upgrading-the-power-adapter&quot;&gt;Upgrading the Power Adapter&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#upgrading-the-firmware&quot; id=&quot;markdown-toc-upgrading-the-firmware&quot;&gt;Upgrading the Firmware&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#replace-fwupd&quot; id=&quot;markdown-toc-replace-fwupd&quot;&gt;Replace fwupd&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#upgrade-keyboard-firmware&quot; id=&quot;markdown-toc-upgrade-keyboard-firmware&quot;&gt;Upgrade Keyboard Firmware&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#update-bios&quot; id=&quot;markdown-toc-update-bios&quot;&gt;Update BIOS&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#replace-hardware&quot; id=&quot;markdown-toc-replace-hardware&quot;&gt;Replace Hardware&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#original-performance&quot; id=&quot;markdown-toc-original-performance&quot;&gt;Original Performance&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#upgrade-screen&quot; id=&quot;markdown-toc-upgrade-screen&quot;&gt;Upgrade Screen&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#upgrade-gpu&quot; id=&quot;markdown-toc-upgrade-gpu&quot;&gt;Upgrade GPU&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#install-drivers&quot; id=&quot;markdown-toc-install-drivers&quot;&gt;Install Drivers&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#ubuntu-2404&quot; id=&quot;markdown-toc-ubuntu-2404&quot;&gt;Ubuntu 24.04&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#windows-11&quot; id=&quot;markdown-toc-windows-11&quot;&gt;Windows 11&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#performance-comparison&quot; id=&quot;markdown-toc-performance-comparison&quot;&gt;Performance Comparison&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#external-g-sync-monitor&quot; id=&quot;markdown-toc-external-g-sync-monitor&quot;&gt;External G-SYNC Monitor&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusion&quot; id=&quot;markdown-toc-conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;When I purchased the &lt;a href=&quot;/blog/2024-03-24-framework16/&quot;&gt;Framework 16 &lt;/a&gt; in July of 2023,
it came with the AMD Radeon™ RX 7700S in the expansion bay.  I had been hoping for an NVIDIA GPU, but that was
not available at the time.&lt;/p&gt;

&lt;p&gt;Some of you might ask why I would opt for NVIDIA over the AMD (ATI) GPU.  Enough people have commented on it that
it’s worth at least touching on briefly.&lt;/p&gt;

&lt;p&gt;The first reason is that my primary external monitor is the Asus Rog Swift PG35VQ.  This is a G-SYNC monitor.  I have
been buying NVIDIA products for quite some time.  The last ATI GPU that I bought was the All-in-Wonder cards. That was
decades ago.  As such, I also have not been buying Freesync monitors.&lt;/p&gt;

&lt;p&gt;The second reason is AI compatability. When I built my desktop in 2017-2018, it was using a GTX 1080 Ti card. That card
is quite old by todays standards - and yet it was easier to get things like Stable Diffusion working on it than on the
Framework 16 with Radeon GPU.  My eight year old desktop should not be my goto for AI workloads when I have newer machines.&lt;/p&gt;

&lt;p&gt;As such, I decided to replace the Radeon with the NVIDIA GeForce RTX 5070.&lt;/p&gt;

&lt;h2 id=&quot;ordering-process-and-timeline&quot;&gt;Ordering Process and Timeline&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Date&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;26 August 2025&lt;/td&gt;
      &lt;td&gt;Down payment on Power Adapter - 240W - US/Canada (Batch 2)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;26 August 2025&lt;/td&gt;
      &lt;td&gt;Down payment on Framework Laptop 16 Graphics Module (NVIDIA® GeForce RTX™ 5070) (Batch 1)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20 November 2025&lt;/td&gt;
      &lt;td&gt;Final payment of Framework Laptop 16 Graphics Module (NVIDIA® GeForce RTX™ 5070)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;23 November 2025&lt;/td&gt;
      &lt;td&gt;Final payment on Power Adapter - 240W - US/Canada&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;24 November 2025&lt;/td&gt;
      &lt;td&gt;Delivery of Framework Laptop 16 Graphics Module (NVIDIA® GeForce RTX™ 5070)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;28 November 2025&lt;/td&gt;
      &lt;td&gt;Delivery of Power Adapter - 240W - US/Canada&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;18 December 2025&lt;/td&gt;
      &lt;td&gt;Order of Framework Laptop Display Kit (2nd Gen)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20 December 2025&lt;/td&gt;
      &lt;td&gt;Delivery of Framework Laptop Display Kit (2nd Gen)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The down payment for the power adapter was almost the entire purchase price.&lt;/p&gt;

&lt;p&gt;Ordering the display kit was tricky since they always sold out quickly. I received multiple emails telling me they were
in stock, but they were out of stock by the time I could get to the order page.  I finally got it in December.  As such,
I waited to do the upgrade until I had all parts in hand.&lt;/p&gt;

&lt;h2 id=&quot;upgrading-the-power-adapter&quot;&gt;Upgrading the Power Adapter&lt;/h2&gt;

&lt;p&gt;I am currently running my OS via the modules, with the NVME reserved for my work drive (git repos, etc).  As such, I have
a module for Ubuntu 24.04, Windows 11, Arch, nixOS, Ventoy, etc.  As opposed to prior methods of dual booting, I am enjoying
this method as Windows never attempts to overwrite Grub.&lt;/p&gt;

&lt;p&gt;I have the power profile set to Balanced and have the BIOS set to a 60% limit.  Since I always have it plugged in, I never
see the battery go below 60%.  That is, until recently.  Starting a few months ago, the battery would drop to 47% while
playing Elder Scrolls Online in Windows.&lt;/p&gt;

&lt;p&gt;I upgraded the power adapter from 180 watt to 240 watt first.  With just that change, the battery no longer drops below
60% while playing the game.&lt;/p&gt;

&lt;h2 id=&quot;upgrading-the-firmware&quot;&gt;Upgrading the Firmware&lt;/h2&gt;

&lt;p&gt;I have not been very consistent keeping my BIOS up to date.&lt;/p&gt;

&lt;p&gt;We can see this in Linux by running:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;lshw dmidecode &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; clear &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dmidecode | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-A3&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Vendor:\|Product:'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;lshw &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; cpu | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-A3&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'product:\|vendor:'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This resulted in&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  Vendor: INSYDE Corp.
  Version: 03.05
  Release Date: 11/13/2024
  Address: 0xE0000
       product: AMD Ryzen 9 7940HS w/ Radeon 780M Graphics
       vendor: Advanced Micro Devices &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;AMD]
       physical &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;: 4
       bus info: cpu@0
       version: 25.116.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here we can see that we are on BIOS 03.05, not 04.02 as required.
According to &lt;a href=&quot;https://knowledgebase.frame.work/en_us/framework-laptop-16-bios-and-driver-releases-amd-ryzen-7040-series-BkeqkVovp?utm_campaign=2025-11-18-fl16-software-update%20%2801KACFQKKVXQW7AXS2FWZP4E7J%29&amp;amp;utm_medium=email&amp;amp;utm_source=Framework%20Laptop%20software%20update%20email%20subscriptions%20list&amp;amp;_kx=EP8BrR3ekd3kEQV90C6rJJRbO_2Dv3WoiC-qrvLn-k8.LNYsui&quot;&gt;this doc&lt;/a&gt;,
we have to update the keyboard firmware first.&lt;/p&gt;

&lt;p&gt;As you can see there were some dependencies that needed to be addressed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The new GPU requires BIOS 4.02 (I was on 3.05)&lt;/li&gt;
  &lt;li&gt;BIOS 4.02 requires Keyboard firmware 0.31 (I forgot to check what version I was on)&lt;/li&gt;
  &lt;li&gt;The BIOS upgrade required fwupd 2.0.16 (which was only available via SNAP, I had APT version 1.9.31 installed)&lt;/li&gt;
  &lt;li&gt;The SNAP version of fwupd has some open bugs that prevent it from accessing certain files&lt;/li&gt;
  &lt;li&gt;Upgrading the keyboard firmware theoretically needed BIOS 4.01 or higher (again, I was on 3.05)&lt;/li&gt;
  &lt;li&gt;The USB-PD on the new GPU also needs newer firmware (0.0.22) which it gets by doing a BIOS update, but we are supposed to install the BIOS before the hardware&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After much trial and error, the process that I went through was:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Replace the APT fwupd with the SNAP fwupd&lt;/li&gt;
  &lt;li&gt;Manually install the keyboard firmware to 0.31&lt;/li&gt;
  &lt;li&gt;Manually install the numpad firmware to 0.31&lt;/li&gt;
  &lt;li&gt;Update the BIOS to 4.02&lt;/li&gt;
  &lt;li&gt;Replace the hardware&lt;/li&gt;
  &lt;li&gt;Update the GPU USB-PD firmware&lt;/li&gt;
  &lt;li&gt;Re-install the BIOS update&lt;/li&gt;
  &lt;li&gt;Install the GPU drivers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s walk through one step at a time.&lt;/p&gt;

&lt;h3 id=&quot;replace-fwupd&quot;&gt;Replace fwupd&lt;/h3&gt;

&lt;p&gt;Since the APT version of fwupd was too old to work, we have to switch to the SNAP version. To be honest, I would have preferred 
to stick with the APT version - but not at the risk of not being able to update the laptop.&lt;/p&gt;

&lt;p&gt;We can confirm that the APT version is too old:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-cache policy fwupd
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; password &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;malachi: 
fwupd:
  Installed: 1.9.31-0ubuntu1~24.04.1
  Candidate: 1.9.31-0ubuntu1~24.04.1
  Version table:
     1.9.33-0ubuntu1~24.04.1ubuntu1 100
        100 http://archive.ubuntu.com/ubuntu noble-proposed/main amd64 Packages
 &lt;span class=&quot;k&quot;&gt;***&lt;/span&gt; 1.9.31-0ubuntu1~24.04.1 500
        500 http://us.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     1.9.16-1 500
        500 http://us.archive.ubuntu.com/ubuntu noble/main amd64 Packages
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The framework page says it requires fwupd 2.0.16 or later.&lt;/p&gt;

&lt;p&gt;To switch to the SNAP version:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt remove fwupd
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;snap &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;fwupd &lt;span class=&quot;nt&quot;&gt;--classic&lt;/span&gt;
fwupdmgr refresh &lt;span class=&quot;nt&quot;&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I might not have needed to, but at this point I rebooted just to clear out anything that might have been running.&lt;/p&gt;

&lt;h3 id=&quot;upgrade-keyboard-firmware&quot;&gt;Upgrade Keyboard Firmware&lt;/h3&gt;

&lt;p&gt;If we run&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fwupdmgr get-updates &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; fwupdmgr update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We can see the BIOS is available:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;      
╔══════════════════════════════════════════════════════════════════════════════╗
║ Upgrade System Firmware from 0.0.3.5 to 0.0.4.2?                             ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Enhancements and Fixes:                                                      ║
║                                                                              ║
║ • Added support for the NVIDIA® GeForce RTX™ 5070.                           ║
║ • Integrated the NVIDIA DR and VK keys to support the NVIDIA G-SYNC          ║
║ feature (requires a 2nd Gen Display kit).                                    ║
║ • Added support for the NVIDIA Advanced Optimus feature (requires a 2nd      ║
║ Gen Display kit).                                                            ║
║ • Updated the 7040 Series STT table.                                         ║
║ • Updated the standalone detection user interface (UI).                      ║
║ • Updated the Framework Input Module application.                            ║
║ • Updated the PD firmware to 0x22 for NVIDIA® GeForce RTX™ 5070.             ║
║ • Enabled the USCI 2.0 feature.                                              ║
║ • Fixed the issue causing PROCHOT to occur when the system was under         ║
║ heavy load.                                                                  ║
║ • Fixed an issue where the CPU became locked at 0.55 GHz during Furmark      ║
║ and CPU burn stress tests.                                                   ║
║ • Fixed an issue where the screen would flash when switching between two     ║
║ EPR adapters.                                                                ║
║ • Fixed an issue where the Supervisor Password incorrectly displayed &quot;Not    ║
║ Installed&quot; after the user had successfully set the password.                 ║
║ • Fixed an issue where the system always displayed an &quot;invalid supervisor    ║
║ password&quot; error when the user set TPM to Hidden and set the supervisor       ║
║ password within the same BIOS session.                                       ║
║ • Fixed an issue where the Wooting 80HE Keyboard did not function while      ║
║ in the BIOS.                                                                 ║
║ • Fixed an issue where the system would flash a black screen during DDS.     ║
║                                                                              ║
║ Laptop 16 (AMD Ryzen 7040 Series) must remain plugged into a power source    ║
║ for the duration of the update to avoid damage.                              ║
╚══════════════════════════════════════════════════════════════════════════════╝
Perform operation? [Y|n]: n
Devices with the latest available firmware version:
 • Fingerprint Sensor
 • UEFI dbx
Devices with no available firmware updates:
 • DisplayPort Expansion Card
 • KEK CA
 • SBAT
 • USB2.1 Hub
 • WD BLACK SN850X 4000GB
 • frame.work-LaptopAMDKEK
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;However, the keyboard is not listed in the firmware.  The official documentation said that it would update automatically
when running that command, however, our current BIOS is too old to support it.&lt;/p&gt;

&lt;p&gt;At this stage, I tried a couple different ways to install the firmware.&lt;/p&gt;

&lt;p&gt;I downloaded the &lt;code class=&quot;highlighter-rouge&quot;&gt;.cab&lt;/code&gt; files and tried to install them manually. I tried with both &lt;code class=&quot;highlighter-rouge&quot;&gt;fwupdmgr local-install&lt;/code&gt; and
by putting them in &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/snap/fwupd/common/share/fwupd/remotes.d/vendor/firmware/&lt;/code&gt;. You can see
&lt;a href=&quot;https://github.com/fwupd/fwupd/issues/6730&quot;&gt;Failed to open cab file error when local install is executed on Snap version of fwupd&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;The UF2 method showed a lot more promise.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Download the &lt;a href=&quot;https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.3.1/framework_ansi_default_v0.3.1.uf2&quot;&gt;ANSI Keyboard file&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Download the &lt;a href=&quot;https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.3.1/framework_numpad_default_v0.3.1.uf2&quot;&gt;Numpad file&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Slide touchpad down until the input deck powers off (backlights turn off)&lt;/li&gt;
  &lt;li&gt;Hold the two buttons (left and right alt for the keyboard, keys 1 and 6 for numpad) while sliding the touchpad back into place&lt;/li&gt;
  &lt;li&gt;The keyboard/numpad is now in bootloader mode. Use the touchpad to drag the .uf2 file onto the RPI-2 drive&lt;/li&gt;
  &lt;li&gt;The keyboard/numpad will auto update itself and restart&lt;/li&gt;
&lt;/ol&gt;

&lt;p class=&quot;message&quot;&gt;&lt;strong&gt;Attention&lt;/strong&gt; DO NOT UPDATE BOTH KEYBOARD AND NUMPAD AT THE SAME TIME. If they are both in bootloader mode, you can’t distinguish between them.&lt;/p&gt;

&lt;p&gt;That process seemed to go pretty smoothly and was very quick!&lt;/p&gt;

&lt;p&gt;How do I validate that the keyboard firmware was installed correctly?
If I run:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsusb &lt;span class=&quot;nt&quot;&gt;-vd&lt;/span&gt; 32ac:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output shows:
Shows a lot of output, but in it we can see:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Bus 001 Device 014: ID 32ac:0012 Framework Laptop 16 Keyboard Module - ANSI
Couldn&lt;span class=&quot;s1&quot;&gt;'t open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass            0 [unknown]
  bDeviceSubClass         0 [unknown]
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x32ac Framework
  idProduct          0x0012 Laptop 16 Keyboard Module - ANSI
  bcdDevice            0.31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Bus 001 Device 015: ID 32ac:0014 Framework Laptop 16 Numpad Module
Couldn&lt;span class=&quot;s1&quot;&gt;'t open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass            0 [unknown]
  bDeviceSubClass         0 [unknown]
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x32ac Framework
  idProduct          0x0014 Laptop 16 Numpad Module
  bcdDevice            0.31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that the &lt;a href=&quot;https://knowledgebase.frame.work/keyboard-firmware-update-framework-laptop-16-r1LayV4Age&quot;&gt;Framework Page&lt;/a&gt; says &lt;code class=&quot;highlighter-rouge&quot;&gt;v0.3.1&lt;/code&gt; but
the firmware says &lt;code class=&quot;highlighter-rouge&quot;&gt;0.31&lt;/code&gt;. I have noticed a lot of inconsistencies in the documentation with regard to dots and extra zeros.&lt;/p&gt;

&lt;h3 id=&quot;update-bios&quot;&gt;Update BIOS&lt;/h3&gt;

&lt;p&gt;Now, we can try to update the BIOS.&lt;/p&gt;

&lt;p&gt;We’ll run the same command from earlier:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fwupdmgr get-updates &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; fwupdmgr update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted with a few Y/N questions.&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Uploading firmware reports helps hardware vendors to quickly identify failing and successful updates on real devices.
Review and upload report now? (Requires internet connection) [Y|n]: n
Do you want to disable this feature for future updates? [y|N]: n
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you choose to upload the report, it will fail: 
&lt;a href=&quot;https://github.com/fwupd/fwupd/issues/9585&quot;&gt;For the snap version of fwupd since v2.0.17, an error message is shown after an update is installed and a reboot is required. Most likely, snapd needs to grant rw permission for fwupd to write the /run/reboot* files.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This appears to be a bug in the snap version of fwupd.  It’s OK, we can skip the report for now and upload it later.&lt;/p&gt;

&lt;p&gt;Once the command finishes, it is &lt;em&gt;queued up&lt;/em&gt; for install. I ran the command multiple times, and it seemed to queue up the BIOS update multiple times.&lt;/p&gt;

&lt;p&gt;Reboot the laptop and the BIOS update should start. It may reboot a few times (see my previous comment).&lt;/p&gt;

&lt;p&gt;Once it has finished booting back into the OS, we can check the BIOS version:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fwupdmgr get-updates | &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /sys/class/dmi/id/bios_version
04.02
Idle…: 0%
No updates available
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I re-ran the &lt;code class=&quot;highlighter-rouge&quot;&gt;fwupdmgr&lt;/code&gt; and let it upload the reports. It shows there are no updates now.&lt;/p&gt;

&lt;p&gt;Surprisingly, it still does not show the keyboard or numpad.&lt;/p&gt;

&lt;h2 id=&quot;replace-hardware&quot;&gt;Replace Hardware&lt;/h2&gt;

&lt;p&gt;Now we will start replacing the hardware.
Before we do that, let’s capture some performance for comparison.&lt;/p&gt;

&lt;h3 id=&quot;original-performance&quot;&gt;Original Performance&lt;/h3&gt;

&lt;p&gt;I wanted to compare the performance of the old GPU and the new GPU.  I didn’t want to run the same Geekbench or Cinebench tests as everyone else.
As I mentioned before, the ability to easily install some hardware (like Stable Diffusion) makes this almost like comparing apples to oranges.
That being said, there was one easy test we can run:&lt;/p&gt;

&lt;p&gt;Let’s just check Ollama. We’ll use the same install, same model, same search (though rebooting). Really, we are just comparing ROCm to CUDA.&lt;/p&gt;

&lt;p&gt;On the Radeon/ROCm:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ollama run &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt; llama3.2:1b
What is the proper way to use the Rust programming language to write a promiscuous mode driver?
...
total duration:       14.576339717s
load duration:        73.155187ms
prompt &lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;count:    45 token&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
prompt &lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;duration: 38.804071ms
prompt &lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;rate:     1159.67 tokens/s
&lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;count:           1171 token&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;duration:        13.525496642s
&lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;rate:            86.58 tokens/s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ll revisit this later.&lt;/p&gt;

&lt;h3 id=&quot;upgrade-screen&quot;&gt;Upgrade Screen&lt;/h3&gt;

&lt;p&gt;Next, we’ll upgrade the screen.&lt;/p&gt;

&lt;p&gt;Framework is really good about their tutorials. Following &lt;a href=&quot;https://guides.frame.work/Guide/Display/284?lang=en&quot;&gt;this tutorial&lt;/a&gt;
was a breeze.  The only thing I did differently than what they showed is that I used the spunger end of my framework screwdriver
to get under the corner of the screen. I couldn’t lift it with my fingernails.&lt;/p&gt;

&lt;h3 id=&quot;upgrade-gpu&quot;&gt;Upgrade GPU&lt;/h3&gt;

&lt;p&gt;For the GPU, I followed &lt;a href=&quot;https://guides.frame.work/Guide/Expansion+Bay+Module/290?lang=en&quot;&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My module was mislabeled.  While the shipping box said it was Nvidia, the sticker on the GPU said it was a Radeon.  At the risk of
affecting my warranty, I wrote on the sticker to make sure that down the road I knew what it really was.&lt;/p&gt;

&lt;p&gt;When re-installing the interposer, I was surprised that the sticker was placed to be read upside down. Also, it wasn’t fully attached.&lt;/p&gt;

&lt;p&gt;On boot it asked me to upgrade the dGPU firmware. It said it was at 0.0.21 and it expected 0.0.22.
There was a QR on the screen to take you to &lt;a href=&quot;https://knowledgebase.frame.work/en_us/updating-usb-pd-firmware-on-your-graphics-module-S1Um_pvRll&quot;&gt;these instructions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It allows you to boot anyway so that you can fix it.&lt;/p&gt;

&lt;p&gt;It tells you that you need to install BIOS 4.02 with the GPU connected.  This is an interesting thing to note because their instructions
said to install the GPU after installing the BIOS.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fwupdmgr get-updates &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; fwupdmgr update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Showed no updates available.&lt;/p&gt;

&lt;p&gt;I tried&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fwupdmgr refresh &lt;span class=&quot;nt&quot;&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;But it had lost the Wi-Fi password.&lt;/p&gt;

&lt;p&gt;Re-entering that, re-refreshing, re-updating… still no updates&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fwupdmgr reinstall
0.  Cancel
1.  a6ac74eb9d266e92632936d19976d755b043b55c &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Fingerprint Sensor&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
2.  7010981714ee5c9258de42216cae163ef272c7ab &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;System Firmware&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
3.  362301da643102b9f38477387e2193e57abaa590 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;UEFI dbx&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Choose device &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0-3]: 2
╔══════════════════════════════════════════════════════════════════════════════╗
║ Reinstall System Firmware to 0.0.4.2?                                        ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Enhancements and Fixes:                                                      ║
║                                                                              ║
║ • Added support &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the NVIDIA® GeForce RTX™ 5070.                           ║
║ • Integrated the NVIDIA DR and VK keys to support the NVIDIA G-SYNC          ║
║ feature &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;requires a 2nd Gen Display kit&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;                                    ║
║ • Added support &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the NVIDIA Advanced Optimus feature &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;requires a 2nd      ║
║ Gen Display kit&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;                                                            ║
║ • Updated the 7040 Series STT table.                                         ║
║ • Updated the standalone detection user interface &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;UI&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;                      ║
║ • Updated the Framework Input Module application.                            ║
║ • Updated the PD firmware to 0x22 &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;NVIDIA® GeForce RTX™ 5070.             ║
║ • Enabled the USCI 2.0 feature.                                              ║
║ • Fixed the issue causing PROCHOT to occur when the system was under         ║
║ heavy load.                                                                  ║
║ • Fixed an issue where the CPU became locked at 0.55 GHz during Furmark      ║
║ and CPU burn stress tests.                                                   ║
║ • Fixed an issue where the screen would flash when switching between two     ║
║ EPR adapters.                                                                ║
║ • Fixed an issue where the Supervisor Password incorrectly displayed &lt;span class=&quot;s2&quot;&gt;&quot;Not    ║
║ Installed&quot;&lt;/span&gt; after the user had successfully &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;the password.                 ║
║ • Fixed an issue where the system always displayed an &lt;span class=&quot;s2&quot;&gt;&quot;invalid supervisor    ║
║ password&quot;&lt;/span&gt; error when the user &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;TPM to Hidden and &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;the supervisor       ║
║ password within the same BIOS session.                                       ║
║ • Fixed an issue where the Wooting 80HE Keyboard did not &lt;span class=&quot;k&quot;&gt;function while&lt;/span&gt;      ║
║ &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;the BIOS.                                                                 ║
║ • Fixed an issue where the system would flash a black screen during DDS.     ║
║                                                                              ║
║ Laptop 16 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;AMD Ryzen 7040 Series&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; must remain plugged into a power &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt;    ║
║ &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the duration of the update to avoid damage.                              ║
╚══════════════════════════════════════════════════════════════════════════════╝
Perform operation? &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Y|n]: 
Waiting…                 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;***************************************&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
Failed to create file “/run/reboot-required.ER04H3”: Permission denied
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;That error is the previously identified one caused by us needing to use the SNAP version instead of the APT version.&lt;/p&gt;

&lt;p&gt;Reboot allowed the BIOS to be updated. We can see PD3 updated to &lt;code class=&quot;highlighter-rouge&quot;&gt;0.0.22&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-drivers&quot;&gt;Install Drivers&lt;/h2&gt;

&lt;p&gt;So far I have updated Ubuntu and Windows. I have not yet updated NixOS or Arch.&lt;/p&gt;

&lt;h3 id=&quot;ubuntu-2404&quot;&gt;Ubuntu 24.04&lt;/h3&gt;

&lt;p&gt;Opening the Additional Drivers UI, I can see that we are currently using &lt;code class=&quot;highlighter-rouge&quot;&gt;xserver-xorg-video-nouveau&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I switched it to &lt;code class=&quot;highlighter-rouge&quot;&gt;nvidia-driver-580-open&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt; didn’t detect the driver until I rebooted.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nvidia-smi
Thu Dec 25 12:55:39 2025       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.95.05              Driver Version: 580.95.05      CUDA Version: 13.0     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|&lt;span class=&quot;o&quot;&gt;=========================================&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;========================&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;======================&lt;/span&gt;|
|   0  NVIDIA GeForce RTX 5070 ...    Off |   00000000:01:00.0 Off |                  N/A |
| N/A   40C    P0             17W /  100W |      15MiB /   8151MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|&lt;span class=&quot;o&quot;&gt;=========================================================================================&lt;/span&gt;|
|    0   N/A  N/A            5287      G   /usr/lib/xorg/Xorg                        4MiB |
+-----------------------------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;windows-11&quot;&gt;Windows 11&lt;/h3&gt;

&lt;p&gt;I downloaded the Windows drivers from the BIOS 4.02 page.&lt;/p&gt;

&lt;p&gt;Easy install and reboot. That being said, when launching a game there was no longer an indication that it switched to the GPU.  Previously,
the AMD popup would tell me it was switching to the external GPU.&lt;/p&gt;

&lt;p&gt;There are a couple Nvidia tray icons.&lt;/p&gt;

&lt;p&gt;One of them showed the Epic launcher was using the GPU when I tried launching a game.&lt;/p&gt;

&lt;p&gt;Another one was the NVidia App.  If you launch that, you can login and download newer (by a month) drivers than was provided by Framework.&lt;/p&gt;

&lt;p&gt;From the App, on the System tab, I can see that the display mode is “Auto (Integrated Graphics)”&lt;/p&gt;

&lt;p&gt;By turning on the overlay, you can tell when games are using it because you’ll briefly get the Alt-Z tooltip on launch.  This is similar to
the previous AMD behavior.&lt;/p&gt;

&lt;h2 id=&quot;performance-comparison&quot;&gt;Performance Comparison&lt;/h2&gt;

&lt;p&gt;Back in Linux, we grab the new performance numbers using the same commands:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;total duration:       4.717006368s
load duration:        80.50099ms
prompt &lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;count:    45 token&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
prompt &lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;duration: 11.463198ms
prompt &lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;rate:     3925.61 tokens/s
&lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;count:           930 token&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;duration:        4.219326541s
&lt;span class=&quot;nb&quot;&gt;eval &lt;/span&gt;rate:            220.41 tokens/s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;How did it compare?&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Metric&lt;/th&gt;
      &lt;th&gt;AMD&lt;/th&gt;
      &lt;th&gt;NVIDIA&lt;/th&gt;
      &lt;th&gt;Comparison&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Total Duration (sec)&lt;/td&gt;
      &lt;td&gt;14.576339717&lt;/td&gt;
      &lt;td&gt;4.219&lt;/td&gt;
      &lt;td&gt;~3.45x faster&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Load Duration (ms)&lt;/td&gt;
      &lt;td&gt;73.155187&lt;/td&gt;
      &lt;td&gt;80.5&lt;/td&gt;
      &lt;td&gt;roughly same&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Prompt Eval Count (tokens)&lt;/td&gt;
      &lt;td&gt;45&lt;/td&gt;
      &lt;td&gt;45&lt;/td&gt;
      &lt;td&gt;same&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Prompt Eval Duration (ms)&lt;/td&gt;
      &lt;td&gt;38.804071&lt;/td&gt;
      &lt;td&gt;11.46&lt;/td&gt;
      &lt;td&gt;~3.39x faster&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Prompt Eval Rate (token/s)&lt;/td&gt;
      &lt;td&gt;1159.67&lt;/td&gt;
      &lt;td&gt;3925.61&lt;/td&gt;
      &lt;td&gt;~3.39x more&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Eval Count (tokens)&lt;/td&gt;
      &lt;td&gt;1171&lt;/td&gt;
      &lt;td&gt;930&lt;/td&gt;
      &lt;td&gt;roughly same&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Eval Duration (sec)&lt;/td&gt;
      &lt;td&gt;13.525496642&lt;/td&gt;
      &lt;td&gt;4.219&lt;/td&gt;
      &lt;td&gt;~3.2x faster&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Eval Rate (token/s)&lt;/td&gt;
      &lt;td&gt;86.58&lt;/td&gt;
      &lt;td&gt;220.41&lt;/td&gt;
      &lt;td&gt;~2.55x more&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;This is a significant improvement.&lt;/p&gt;

&lt;h2 id=&quot;external-g-sync-monitor&quot;&gt;External G-SYNC Monitor&lt;/h2&gt;

&lt;p&gt;I mentioned earlier that I was using an Asus Rog Swift PG35VQ.  I am connecting to it via DP using the Framework DP Module.&lt;/p&gt;

&lt;p&gt;Testing whether G-SYNC was working on the external monitor was a little tricky.&lt;/p&gt;

&lt;p&gt;In Linux, I checked the &lt;code class=&quot;highlighter-rouge&quot;&gt;nvidia-settings&lt;/code&gt; app.  It showed that the GPU was set to &lt;code class=&quot;highlighter-rouge&quot;&gt;On-Demand Mode&lt;/code&gt;. There was, however, no
G-SYNC settings like I am used to seeing on my desktop. On the monitor OSD screen, it said it was in G-SYNC mode and
at 3440x1440@180Hz.  I did not have the 200Hz overclock option enabled.  It did not appear to matter whether the DP module
was plugged into the side of the laptop or directly into the GPU. The monitor saw it the same either way, as did &lt;code class=&quot;highlighter-rouge&quot;&gt;nvidia-settings&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On Windows, it was a similar situation. The tray icon didn’t show that any monitor was connected even though it was displaying on it.
I didn’t try plugging directly into the GPU there because let’s me honest, I do not need my cat to try to sit on the DP module.
The monitor still showed that it was in G-SYNC mode at 3440x1440@180Hz. I did need to go into the Windows System settings and tell it
to only show the external monitor when avaialble. That allowed it to auto-scale to the full size.&lt;/p&gt;

&lt;p&gt;In the end I was not able to verify G-SYNC on the laptop side, but the monitor did indicate that it was using it.  I should have tested
plugging it into the monitor before installing the hardware.  I seem to recall it was stuck at 59Hz on the AMD GPU, but… I’m not sure.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Upgrading everything took the better part of a day.  If I had been keeping my BIOS updated all along, I think it easily would have
cut the time in half.  The hardware changes went pretty smoothly.  Most of the time was due to trying to figure out why the keyboard
didn’t show up in the BIOS update with fwupdmgr.&lt;/p&gt;

&lt;p&gt;The UF2 process of updating the keyboard and numpad firmware was interesting as well.&lt;/p&gt;

&lt;p&gt;While I only did performance analysis in Ollama, the combination of that and the ability to install software that is only CUDA-compatible
makes this upgrade a no-brainer for me.&lt;/p&gt;

&lt;p&gt;There was one gotcha on the ordering process. Ideally, you would upgrade the display kit, power adapter and GPU all at the same time. 
Unfortunately, the display kit is often out of stock.  Hopefully they improve the stock for that component.&lt;/p&gt;

&lt;p&gt;If they ever release the touchscreen, I suspect that will just be a new display kit that can be swapped in.&lt;/p&gt;

&lt;p&gt;I guess one final note: there is no noticeable difference in size. The laptop still fits in my laptop bag.&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="framework" /><summary type="html"></summary></entry><entry><title type="html">How model choice affects your Tool Calling</title><link href="https://www.malachid.com/blog/2025-04-06-rig-ollama/" rel="alternate" type="text/html" title="How model choice affects your Tool Calling" /><published>2025-04-06T13:14:51-07:00</published><updated>2025-04-06T13:14:51-07:00</updated><id>https://www.malachid.com/blog/rig-ollama</id><content type="html" xml:base="https://www.malachid.com/blog/2025-04-06-rig-ollama/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#local&quot; id=&quot;markdown-toc-local&quot;&gt;Local&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#software&quot; id=&quot;markdown-toc-software&quot;&gt;Software&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#rig-example&quot; id=&quot;markdown-toc-rig-example&quot;&gt;RIG Example&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#diagnosis&quot; id=&quot;markdown-toc-diagnosis&quot;&gt;Diagnosis&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#llama321b&quot; id=&quot;markdown-toc-llama321b&quot;&gt;llama3.2:1b&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#qwen25latest&quot; id=&quot;markdown-toc-qwen25latest&quot;&gt;qwen2.5:latest&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#gemma34b&quot; id=&quot;markdown-toc-gemma34b&quot;&gt;gemma3:4b&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#michaelnealedeepseek-r1-gooselatest&quot; id=&quot;markdown-toc-michaelnealedeepseek-r1-gooselatest&quot;&gt;michaelneale/deepseek-r1-goose:latest&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#llama318b-instruct-q4_0&quot; id=&quot;markdown-toc-llama318b-instruct-q4_0&quot;&gt;llama3.1:8b-instruct-q4_0&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#updating-the-example&quot; id=&quot;markdown-toc-updating-the-example&quot;&gt;Updating the Example&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#caveat&quot; id=&quot;markdown-toc-caveat&quot;&gt;Caveat&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusions&quot; id=&quot;markdown-toc-conclusions&quot;&gt;Conclusions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;h3 id=&quot;local&quot;&gt;Local&lt;/h3&gt;

&lt;p&gt;I am a fan of running things locally.&lt;/p&gt;

&lt;p&gt;Previously, I had been running a box with 12 onboard SATA drives ( there is a pic &lt;a href=&quot;/blog/2017-09-16-welcome-to-odin/#serveris-2007&quot;&gt;here&lt;/a&gt; ).&lt;/p&gt;

&lt;p&gt;Recently I built a &lt;a href=&quot;/blog/2024-05-27-turingpi2/&quot;&gt;k3s cluster&lt;/a&gt; for my local cabinet, which I really need to spend more time with.&lt;/p&gt;

&lt;p&gt;I’ve been testing various frameworks.  I have been trying to focus on those that will work with Ollama locally (or perhaps GGUF files directly).&lt;/p&gt;

&lt;p&gt;My end goal will be to host a NVidia DGX Spark in my cabinet and have everything local connect to it.
My &lt;a href=&quot;/blog/2024-03-24-framework16/&quot;&gt;Framework&lt;/a&gt; works well for smaller models using ROCm; but the Spark should allow me to use larger models.
You’ll likely be wondering why I chose the NVidia box instead of the Framework desktop.  This is purely because I wanted Nvidia/CUDA.  I wanted it for my laptop as well, but it is not available yet.  Some models don’t work well on AMD GPUs.&lt;/p&gt;

&lt;h3 id=&quot;software&quot;&gt;Software&lt;/h3&gt;

&lt;p&gt;I am mostly interested in a multi-agent system.  Ideally, one that can run 24x7.  This makes local control even more important because I don’t want
to pay the cost of it running all the time in the cloud.&lt;/p&gt;

&lt;p&gt;I plan on using it to assist with some dev tasks, research, home automation, whatever.&lt;/p&gt;

&lt;p&gt;As such, I have been testing different agent systems.&lt;/p&gt;

&lt;p&gt;When testing Junie, it does a really good job of writing up a list of tasks to complete.  Unfortunately, if it gets any errors completing those tasks, it gets a bit stuck. As such, it’s not yet to the point of being autonomous.&lt;/p&gt;

&lt;p&gt;Goose works really well.  It’s open source and written in Rust.  The biggest problem I have with Goose is that every time I connect it to Ollama, the tools just respond with the json rather than doing any work.  It works fine with Gemini (other than rate limits); but that’s online.&lt;/p&gt;

&lt;p&gt;So today, we are looking at &lt;a href=&quot;https://rig.rs/&quot;&gt;RIG&lt;/a&gt;.  It is open source, written in Rust and has a lot of examples.  Today we will be looking at just one of those examples.&lt;/p&gt;

&lt;h2 id=&quot;rig-example&quot;&gt;RIG Example&lt;/h2&gt;

&lt;p&gt;The RIG example we are going to look at today is &lt;a href=&quot;https://github.com/0xPlaygrounds/rig/blob/main/rig-core/examples/ollama_streaming_with_tools.rs&quot;&gt;ollama_streaming_with_tools.rs&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;anyhow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;streaming&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream_to_stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;completion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ToolDefinition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;providers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;streaming&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StreamingPrompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;serde&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;serde_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[derive(Deserialize)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationArgs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[derive(Debug,&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;thiserror&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;Error)]&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;#[error(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Math error&quot;&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MathError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;Serialize)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Adder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Adder&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;add&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MathError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;definition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ToolDefinition&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ToolDefinition&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;add&quot;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.to_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Add x and y together&quot;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.to_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;json!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The first number to add&quot;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The second number to add&quot;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;Serialize)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Subtract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Subtract&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;'static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;subtract&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MathError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;definition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ToolDefinition&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;serde_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;json!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;subtract&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Subtract y from x (i.e.: x - y)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;parameters&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The number to subtract from&quot;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The number to subtract&quot;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;.expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Tool Definition&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.x&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[tokio&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;main]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;anyhow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;tracing_subscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// Create agent with a single context prompt and two tools&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator_agent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;providers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;ollama&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;.agent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;llama3.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;.preamble&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;You are a calculator here to help the user perform arithmetic 
            operations. Use the tools provided to answer the user's question. 
            make your answer long, so we can test the streaming functionality, 
            like 20 words&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;.max_tokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;.tool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Adder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;.tool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Subtract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;.build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Calculate 2 - 5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator_agent&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.stream_prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Calculate 2 - 5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.await&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;stream_to_stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;calculator_agent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.await&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the crux of the app is asking the LLM to use a &lt;code class=&quot;highlighter-rouge&quot;&gt;Subtract&lt;/code&gt; tool.
In theory, it should take &lt;code class=&quot;highlighter-rouge&quot;&gt;2 - 5&lt;/code&gt; and return &lt;code class=&quot;highlighter-rouge&quot;&gt;-3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What do we actually see?&lt;/p&gt;

&lt;p&gt;When I run it locally:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Calculate 2 - 5
Response: 2025-04-06T20:48:03.629415Z  INFO rig: Calling tool subtract with args:
&lt;span class=&quot;s2&quot;&gt;&quot;{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;}&quot;&lt;/span&gt;
Error: ToolCallError: JsonError: invalid &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;: string &lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;, expected i32 at line 1 column 8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So what are we seeing here?
We told Ollama that &lt;code class=&quot;highlighter-rouge&quot;&gt;2&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;5&lt;/code&gt; were numbers (&lt;code class=&quot;highlighter-rouge&quot;&gt;i32&lt;/code&gt; specifically) and they were given back to RIG as Strings.&lt;/p&gt;

&lt;p&gt;Is Ollama or RIG at fault here?&lt;/p&gt;

&lt;h2 id=&quot;diagnosis&quot;&gt;Diagnosis&lt;/h2&gt;

&lt;p&gt;Let’s try calling Ollama directly without RIG in the mix.&lt;/p&gt;

&lt;h3 id=&quot;llama321b&quot;&gt;llama3.2:1b&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST http://localhost:11434/api/chat &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{
  &quot;model&quot;: &quot;llama3.2:1b&quot;,
  &quot;messages&quot;: [
    {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;You are a math assistant. Use the `subtract` tool for arithmetic.&quot;},
    {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Calculate 5 minus 3.&quot;}
  ],
  &quot;tools&quot;: [
    {
      &quot;name&quot;: &quot;subtract&quot;,
      &quot;description&quot;: &quot;Subtract two numbers.&quot;,
      &quot;parameters&quot;: {
        &quot;type&quot;: &quot;object&quot;,
        &quot;properties&quot;: {
          &quot;a&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; },
          &quot;b&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; }
        }
      }
    }
  ]
}'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;model&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;llama3.2:1b&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;created_at&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;2025-04-06T19:12:25.886010847Z&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;role&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;assistant&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;numeric&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;subtract&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: {&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;}}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done_reason&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;stop&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done&quot;&lt;/span&gt;:true,&lt;span class=&quot;s2&quot;&gt;&quot;total_duration&quot;&lt;/span&gt;:374119253,&lt;span class=&quot;s2&quot;&gt;&quot;load_duration&quot;&lt;/span&gt;:13042547,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_count&quot;&lt;/span&gt;:151,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_duration&quot;&lt;/span&gt;:117861289,&lt;span class=&quot;s2&quot;&gt;&quot;eval_count&quot;&lt;/span&gt;:26,&lt;span class=&quot;s2&quot;&gt;&quot;eval_duration&quot;&lt;/span&gt;:241922157&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When called directly with cURL, we can see that the returned parameters are json strings.&lt;/p&gt;

&lt;p&gt;Let’s try another model.&lt;/p&gt;

&lt;h3 id=&quot;qwen25latest&quot;&gt;qwen2.5:latest&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST http://localhost:11434/api/chat &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{
  &quot;model&quot;: &quot;qwen2.5:latest&quot;,
  &quot;messages&quot;: [
    {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;You are a math assistant. Use the `subtract` tool for arithmetic.&quot;},
    {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Calculate 5 minus 3.&quot;}
  ],
  &quot;tools&quot;: [
    {
      &quot;name&quot;: &quot;subtract&quot;,
      &quot;description&quot;: &quot;Subtract two numbers.&quot;,
      &quot;parameters&quot;: {
        &quot;type&quot;: &quot;object&quot;,
        &quot;properties&quot;: {
          &quot;a&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; },
          &quot;b&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; }
        }
      }
    }
  ]
}'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;model&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;qwen2.5:latest&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;created_at&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;2025-04-06T19:24:35.087296724Z&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;role&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;assistant&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;tool_calls&quot;&lt;/span&gt;:[&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;function&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;subtract&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;arguments&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minuend&quot;&lt;/span&gt;:5,&lt;span class=&quot;s2&quot;&gt;&quot;subtrahend&quot;&lt;/span&gt;:3&lt;span class=&quot;o&quot;&gt;}}}]}&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done&quot;&lt;/span&gt;:false&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;model&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;qwen2.5:latest&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;created_at&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;2025-04-06T19:24:35.137474283Z&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;role&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;assistant&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done_reason&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;stop&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done&quot;&lt;/span&gt;:true,&lt;span class=&quot;s2&quot;&gt;&quot;total_duration&quot;&lt;/span&gt;:12999461211,&lt;span class=&quot;s2&quot;&gt;&quot;load_duration&quot;&lt;/span&gt;:12002129024,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_count&quot;&lt;/span&gt;:139,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_duration&quot;&lt;/span&gt;:42131461,&lt;span class=&quot;s2&quot;&gt;&quot;eval_count&quot;&lt;/span&gt;:30,&lt;span class=&quot;s2&quot;&gt;&quot;eval_duration&quot;&lt;/span&gt;:949711483&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Well, this is much worse.  Qwen changed the name of our parameters.&lt;/p&gt;

&lt;h3 id=&quot;gemma34b&quot;&gt;gemma3:4b&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST http://localhost:11434/api/chat &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{
  &quot;model&quot;: &quot;gemma3:4b&quot;,
  &quot;messages&quot;: [
    {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;You are a math assistant. Use the `subtract` tool for arithmetic.&quot;},
    {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Calculate 5 minus 3.&quot;}
  ],
  &quot;tools&quot;: [
    {
      &quot;name&quot;: &quot;subtract&quot;,
      &quot;description&quot;: &quot;Subtract two numbers.&quot;,
      &quot;parameters&quot;: {
        &quot;type&quot;: &quot;object&quot;,
        &quot;properties&quot;: {
          &quot;a&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; },
          &quot;b&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; }
        }
      }
    }
  ]
}'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;error&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;registry.ollama.ai/library/gemma3:4b does not support tools&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Oops, gemma doesn’t even support tool calling.  Let’s try another.&lt;/p&gt;

&lt;h3 id=&quot;michaelnealedeepseek-r1-gooselatest&quot;&gt;michaelneale/deepseek-r1-goose:latest&lt;/h3&gt;

&lt;p&gt;DeepSeek will not run on the FW16 / ROCm without core dumping.
This version was recommended by Goose specifically for tool calling.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST http://localhost:11434/api/chat &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{
  &quot;model&quot;: &quot;michaelneale/deepseek-r1-goose:latest&quot;,
  &quot;messages&quot;: [
    {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;You are a math assistant. Use the `subtract` tool for arithmetic.&quot;},
    {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Calculate 5 minus 3.&quot;}
  ],
  &quot;tools&quot;: [
    {
      &quot;name&quot;: &quot;subtract&quot;,
      &quot;description&quot;: &quot;Subtract two numbers.&quot;,
      &quot;parameters&quot;: {
        &quot;type&quot;: &quot;object&quot;,
        &quot;properties&quot;: {
          &quot;a&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; },
          &quot;b&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; }
        }
      }
    }
  ]
}'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;model&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;michaelneale/deepseek-r1-goose:latest&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;created_at&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;2025-04-06T19:23:02.932426378Z&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;role&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;assistant&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;tool_calls&quot;&lt;/span&gt;:[&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;function&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;subtract&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;arguments&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;a&quot;&lt;/span&gt;:5,&lt;span class=&quot;s2&quot;&gt;&quot;b&quot;&lt;/span&gt;:3&lt;span class=&quot;o&quot;&gt;}}}]}&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done&quot;&lt;/span&gt;:false&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;model&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;michaelneale/deepseek-r1-goose:latest&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;created_at&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;2025-04-06T19:23:05.558074544Z&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;role&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;assistant&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done_reason&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;stop&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done&quot;&lt;/span&gt;:true,&lt;span class=&quot;s2&quot;&gt;&quot;total_duration&quot;&lt;/span&gt;:54412886209,&lt;span class=&quot;s2&quot;&gt;&quot;load_duration&quot;&lt;/span&gt;:20797813483,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_count&quot;&lt;/span&gt;:158,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_duration&quot;&lt;/span&gt;:718908948,&lt;span class=&quot;s2&quot;&gt;&quot;eval_count&quot;&lt;/span&gt;:394,&lt;span class=&quot;s2&quot;&gt;&quot;eval_duration&quot;&lt;/span&gt;:32893678846&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This one had the correct response but was very &lt;em&gt;very&lt;/em&gt; slow.&lt;/p&gt;

&lt;h3 id=&quot;llama318b-instruct-q4_0&quot;&gt;llama3.1:8b-instruct-q4_0&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST http://localhost:11434/api/chat &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{
  &quot;model&quot;: &quot;llama3.1:8b-instruct-q4_0&quot;,
  &quot;messages&quot;: [
    {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;You are a math assistant. Use the `subtract` tool for arithmetic.&quot;},
    {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Calculate 5 minus 3.&quot;}
  ],
  &quot;tools&quot;: [
    {
      &quot;name&quot;: &quot;subtract&quot;,
      &quot;description&quot;: &quot;Subtract two numbers.&quot;,
      &quot;parameters&quot;: {
        &quot;type&quot;: &quot;object&quot;,
        &quot;properties&quot;: {
          &quot;a&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; },
          &quot;b&quot;: { &quot;type&quot;: &quot;integer&quot;, &quot;format&quot;: &quot;i32&quot; }
        }
      }
    }
  ]
}'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;model&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;llama3.1:8b-instruct-q4_0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;created_at&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;2025-04-06T19:26:24.56003022Z&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;role&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;assistant&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;tool_calls&quot;&lt;/span&gt;:[&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;function&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;subtract&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;arguments&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;a&quot;&lt;/span&gt;:5,&lt;span class=&quot;s2&quot;&gt;&quot;b&quot;&lt;/span&gt;:3&lt;span class=&quot;o&quot;&gt;}}}]}&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done&quot;&lt;/span&gt;:false&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;model&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;llama3.1:8b-instruct-q4_0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;created_at&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;2025-04-06T19:26:24.584434326Z&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;:&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;role&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;assistant&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done_reason&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;stop&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;done&quot;&lt;/span&gt;:true,&lt;span class=&quot;s2&quot;&gt;&quot;total_duration&quot;&lt;/span&gt;:12760865597,&lt;span class=&quot;s2&quot;&gt;&quot;load_duration&quot;&lt;/span&gt;:12037184762,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_count&quot;&lt;/span&gt;:154,&lt;span class=&quot;s2&quot;&gt;&quot;prompt_eval_duration&quot;&lt;/span&gt;:41198083,&lt;span class=&quot;s2&quot;&gt;&quot;eval_count&quot;&lt;/span&gt;:19,&lt;span class=&quot;s2&quot;&gt;&quot;eval_duration&quot;&lt;/span&gt;:681068100&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This one has the correct response and is fast.
Let’s try to use this one.&lt;/p&gt;

&lt;h2 id=&quot;updating-the-example&quot;&gt;Updating the Example&lt;/h2&gt;

&lt;p&gt;Switching the agent line in the example: &lt;code class=&quot;highlighter-rouge&quot;&gt;.agent(&quot;llama3.1:8b-instruct-q4_0&quot;)&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Calculate 2 - 5
Response: 2025-04-06T20:55:47.720048Z  INFO rig: Calling tool subtract with args:
&lt;span class=&quot;s2&quot;&gt;&quot;{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:2,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:5}&quot;&lt;/span&gt;

Result: &lt;span class=&quot;nt&quot;&gt;-3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is great! It works!&lt;/p&gt;

&lt;h2 id=&quot;caveat&quot;&gt;Caveat&lt;/h2&gt;

&lt;p&gt;Let’s just try doing &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo run&lt;/code&gt; a few more times without any code changes.&lt;/p&gt;

&lt;p&gt;I tried running it 10 more times.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;9 times it got the right result&lt;/li&gt;
  &lt;li&gt;1 time it got &lt;code class=&quot;highlighter-rouge&quot;&gt;3&lt;/code&gt; instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;-3&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should be noted that I thought to try this because I did see it respond with the strings instead of numbers ONCE during testing.&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;We were able to diagnose why it wasn’t work and fix it.&lt;/p&gt;

&lt;p&gt;Not all models are the equal - even if they say they support tool calling.&lt;/p&gt;

&lt;p&gt;We should follow best coding practices and code defensively against it being the wrong type.&lt;/p&gt;

&lt;p&gt;We could ask it to run more than once and then pick the most frequent answer; however this could become problematic if the tool is doing things like filesystem changes or filing taxes.&lt;/p&gt;

&lt;p&gt;I think the next steps will be:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Try to set the temperature to 1&lt;/li&gt;
  &lt;li&gt;Modify the prompt to encourage the correct answer&lt;/li&gt;
  &lt;li&gt;Maybe a custom model, model template or training&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="rust" /><summary type="html"></summary></entry><entry><title type="html">Building a k3s cluster on Turing Pi 2</title><link href="https://www.malachid.com/blog/2024-05-27-turingpi2/" rel="alternate" type="text/html" title="Building a k3s cluster on Turing Pi 2" /><published>2024-05-27T11:31:59-07:00</published><updated>2024-05-27T11:31:59-07:00</updated><id>https://www.malachid.com/blog/turingpi2</id><content type="html" xml:base="https://www.malachid.com/blog/2024-05-27-turingpi2/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#turing-pi-2&quot; id=&quot;markdown-toc-turing-pi-2&quot;&gt;Turing Pi 2&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#kubernetes&quot; id=&quot;markdown-toc-kubernetes&quot;&gt;Kubernetes&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#k3s&quot; id=&quot;markdown-toc-k3s&quot;&gt;K3S&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#timeline&quot; id=&quot;markdown-toc-timeline&quot;&gt;Timeline&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#specs&quot; id=&quot;markdown-toc-specs&quot;&gt;Specs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#build-log&quot; id=&quot;markdown-toc-build-log&quot;&gt;Build Log&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#sliger-cx2137b&quot; id=&quot;markdown-toc-sliger-cx2137b&quot;&gt;Sliger CX2137b&lt;/a&gt;        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#modify-the-case&quot; id=&quot;markdown-toc-modify-the-case&quot;&gt;Modify the case&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rack-ears&quot; id=&quot;markdown-toc-rack-ears&quot;&gt;Rack Ears&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#noctua-nf-a8-pwm&quot; id=&quot;markdown-toc-noctua-nf-a8-pwm&quot;&gt;Noctua NF-A8 PWM&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#enhance-enp-8345-l-ovt&quot; id=&quot;markdown-toc-enhance-enp-8345-l-ovt&quot;&gt;Enhance ENP-8345-L-OVT&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rk1&quot; id=&quot;markdown-toc-rk1&quot;&gt;RK1&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#extenders&quot; id=&quot;markdown-toc-extenders&quot;&gt;Extenders&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#final-internal-touches&quot; id=&quot;markdown-toc-final-internal-touches&quot;&gt;Final Internal Touches&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rack-rails-attempt&quot; id=&quot;markdown-toc-rack-rails-attempt&quot;&gt;Rack Rails attempt&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#connecting&quot; id=&quot;markdown-toc-connecting&quot;&gt;Connecting&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#bmc&quot; id=&quot;markdown-toc-bmc&quot;&gt;BMC&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#accessing-the-bmc&quot; id=&quot;markdown-toc-accessing-the-bmc&quot;&gt;Accessing the BMC&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#flashing-nodes&quot; id=&quot;markdown-toc-flashing-nodes&quot;&gt;Flashing Nodes&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#tpi&quot; id=&quot;markdown-toc-tpi&quot;&gt;tpi&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#interjection-from-the-future&quot; id=&quot;markdown-toc-interjection-from-the-future&quot;&gt;Interjection from the Future&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#setting-up-the-nodes&quot; id=&quot;markdown-toc-setting-up-the-nodes&quot;&gt;Setting up the Nodes&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#software-install&quot; id=&quot;markdown-toc-software-install&quot;&gt;Software Install&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#k3s-1&quot; id=&quot;markdown-toc-k3s-1&quot;&gt;k3s&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#helm&quot; id=&quot;markdown-toc-helm&quot;&gt;Helm&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#metallb&quot; id=&quot;markdown-toc-metallb&quot;&gt;MetalLB&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#longhorn&quot; id=&quot;markdown-toc-longhorn&quot;&gt;Longhorn&lt;/a&gt;        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#test-longhorn&quot; id=&quot;markdown-toc-test-longhorn&quot;&gt;Test Longhorn&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#argocd&quot; id=&quot;markdown-toc-argocd&quot;&gt;ArgoCD&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#login&quot; id=&quot;markdown-toc-login&quot;&gt;Login&lt;/a&gt;        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#testing-argo&quot; id=&quot;markdown-toc-testing-argo&quot;&gt;Testing Argo&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusion&quot; id=&quot;markdown-toc-conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;When I think about what my motivation is for building a k3s cluster on the Turing Pi 2, I feel like the question can be broken down a bit.&lt;/p&gt;

&lt;h3 id=&quot;turing-pi-2&quot;&gt;Turing Pi 2&lt;/h3&gt;

&lt;p&gt;Let’s start with why I chose to back the Turing Pi 2.&lt;/p&gt;

&lt;p&gt;I backed their &lt;a href=&quot;https://www.kickstarter.com/projects/turingpi/turing-pi-cluster-board?ref=ksr_email_backer_backer_confirmation&quot;&gt;Kickstarter&lt;/a&gt; within 17 minutes of launch.
Now, I admit that at one time I might have been considered a serial contributor (thus the Superbacker label), but I have mellowed down a bit over time.&lt;/p&gt;

&lt;p&gt;I had been considering different ways of running compute nodes in my Sysracks 32U rack.  Having multiple mounted on a single board, with a single power supply and
network cable seemed like an efficient use of my outlets.&lt;/p&gt;

&lt;p&gt;Originally, I had intended to mix-n-match different types of compute nodes on the board.  Maybe some Jetson modules, etc.&lt;/p&gt;

&lt;h3 id=&quot;kubernetes&quot;&gt;Kubernetes&lt;/h3&gt;

&lt;p&gt;The next question is why I chose to run Kubernetes on the cluster.&lt;/p&gt;

&lt;p&gt;There are various options you could do with a cluster.  It could be dedicated entirely to Home Assistant for example.  Or perhaps a homemade MMO. Or an MPI cluster.&lt;/p&gt;

&lt;p&gt;I was planning on replacing Google Home (which has gotten worse over time) with Home Assistant; so that option might make sense.  Running Home Assistant inside of 
Kubernetes comes with some restrictions w/ re to the add-ons.&lt;/p&gt;

&lt;p&gt;I was already using Docker and Docker Compose.  Having somewhere local I could deploy things would be nice.  Local specifically, because I didn’t want to deploy to 
the cloud for some of the items (like my financial records).&lt;/p&gt;

&lt;p&gt;Work uses Kubernetes.  I never interact with it, but it would be good to expand my skillset.  I tried running minik8s on my laptop, but feel like that was a bit of 
a mess.  There are other options like Kind and minikube; but why tie up the local laptop?&lt;/p&gt;

&lt;h3 id=&quot;k3s&quot;&gt;K3S&lt;/h3&gt;

&lt;p&gt;So which version of Kubernetes to use?&lt;/p&gt;

&lt;p&gt;This one was actually a fairly easy decision. The &lt;a href=&quot;https://docs.turingpi.com/docs/turing-pi2-kubernetes-installation0&quot;&gt;Turing Pi documentation&lt;/a&gt; had some guides for
setting up k3s.  Admittedly, they were geared towards running DietPi on the RaspberryPi, which I was not going to be doing - but it still gave me some guidance.&lt;/p&gt;

&lt;h2 id=&quot;timeline&quot;&gt;Timeline&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Date&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Activity&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;13 May 2022&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;TuringPi sent me an email about the upcoming lanuch&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;16 May 2022&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;I backed the project on Kickstarter&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;23 Dec 2022&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;TuringPi.com account created, Original KS prices increased&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;14 Apr 2023&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Delivery of Turing Pi 2 board w/o Compute Modules&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;19 Jul 2023&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Charged for the 16GB Compute Modules&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;26 Jul 2023&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Offered upgrade to 32GB, Charged for new price&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;12 Feb 2024&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Delivery of RK1 Compute Modules and Heatsinks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;08 May 2024&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Ordered parts to start rackmounting&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;20 May 2024&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Case assembled&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;24 May 2024&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Rails attempted and rejected&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;26 May 2024&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Cluster ready&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;So as you can see, this process was just over 2 years in the making!&lt;/p&gt;

&lt;h2 id=&quot;specs&quot;&gt;Specs&lt;/h2&gt;

&lt;p&gt;There are 4 RK1 modules.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Type&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Amount/RK1&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Total&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Cores&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;8&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;32&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;TOPS&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;6&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;24&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;RAM&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;32 GB&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;128 GB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;TDP&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;7W&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;28W&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Storage&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 TB&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4 TB&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;build-log&quot;&gt;Build Log&lt;/h2&gt;

&lt;h3 id=&quot;sliger-cx2137b&quot;&gt;Sliger CX2137b&lt;/h3&gt;

&lt;p&gt;Choosing a chassis was not as trivial as I expected.  If you are looking to do an ATX build, there are a lot of options. In my case, I needed a 2U Mini-ITX that would
not shut down when idle power was low.  This meant that the case and PSU options were intricately intertwined.&lt;/p&gt;

&lt;p&gt;Jeff Geerling had &lt;a href=&quot;https://youtu.be/RijuRF0ITdE?si=dftXlYrNgntZZlgr&quot;&gt;used a MyElectronics&lt;/a&gt; case.  I had seriously considered that for some time.  They had a few
options.  The reason I chose to not go with their cases came down to the fact that I didn’t want to mount the NVME under the motherboard, and wanted them to be accessible.
While they had cases designed with the Turing Pi 2 in mind, and one even had a hole for the PicoPSU - there was no room to mount anything extra.&lt;/p&gt;

&lt;p&gt;The second issue I had was that a lot of the Mini-ITX cases did not have compatible rail kits that would work on the Sysracks cabinet.&lt;/p&gt;

&lt;p&gt;The Sliger CX2137b is a 2U enclosure with optional rail kit that was long enough for my cabinet. More on this later.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/TbnFJq4NeemLnkRe8&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240519_114407.jpg&quot; alt=&quot;Case Front&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;https://photos.app.goo.gl/HMKq7B5vNmx9yn3r9&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240519_114419.jpg&quot; alt=&quot;Case Back&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;https://photos.app.goo.gl/BMaRwoD27aDdSg7w8&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240519_114622.jpg&quot; alt=&quot;Case Inside&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The cable that can be seen there contains:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Front Power SW&lt;/li&gt;
  &lt;li&gt;Front Power LED&lt;/li&gt;
  &lt;li&gt;USB3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The IO Shield that came with the Turing Pi 2 fits the case; but more on that later.&lt;/p&gt;

&lt;h4 id=&quot;modify-the-case&quot;&gt;Modify the case&lt;/h4&gt;

&lt;p&gt;Before I start mounting things into the case, I need to make some modifications to it.  This is because the BMC SD card and the NVME for each node are all located
on the bottom of the Turing Pi 2.  While I understand that this was done to save space, and is not a big deal for small desktop plastic enclosures, it is not ideal
for live modifications to a rack-mounted kubernetes cluster.&lt;/p&gt;

&lt;p&gt;As such, I purchased an SD Card Extender and 4 NVME extenders.&lt;/p&gt;

&lt;p&gt;The one downside to these boards is that provided &lt;strong&gt;NO&lt;/strong&gt; mounting options at all. No screw holes, etc.&lt;/p&gt;

&lt;p&gt;The solution I came up with was to use PCB feet on 3 of the 4 sides of each carrier board.  I needed to then mount these to the case.&lt;/p&gt;

&lt;p&gt;It didn’t turn out quite as clean as I would have liked, but it is at least working.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/9Qc3nzuYeF8j4dVn9&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240519_130844.jpg&quot; alt=&quot;Taping to Drill&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;https://photos.app.goo.gl/4cCn8aDDVHanKYvT8&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240519_143743.jpg&quot; alt=&quot;Holes Drilled&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After drilling the holes, I made sure to install the PCI covers before installing the NVME.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/mJN9C96LXdWGZ7YB7&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240519_145300.jpg&quot; alt=&quot;PCI Covers Installed&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I was able to mount the NVME carrier boards.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/rswxnyorLBFqXLrS6&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240519_151549.jpg&quot; alt=&quot;NVME Carrier Boards Mounted&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’re likely wondering why they aren’t straight.&lt;/p&gt;

&lt;p&gt;Turns out I wasn’t careful enough when measuring and the drill slipped a little.&lt;br /&gt;
On top of that, the surface under the tape didn’t end up being flat. I have to console myself with not being able to see it once mounted.&lt;/p&gt;

&lt;p&gt;Maybe someday I’ll replace the case and redo it by drilling from the other side instead.&lt;/p&gt;

&lt;p&gt;I used M4 bolts that I had on hand for mounting the feet.  I don’t like that they aren’t flush with the bottom of the case,
so I’ll have to be careful not to mount another chassis directly under it for now.&lt;/p&gt;

&lt;h3 id=&quot;rack-ears&quot;&gt;Rack Ears&lt;/h3&gt;

&lt;p&gt;I installed the rack ears next.  Or at least, I should say I installed them for the first time.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/cMDaq3U57wmuQCnn6&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_192747.jpg&quot; alt=&quot;Rack Ears&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Turns out that the provided screws &lt;em&gt;suck&lt;/em&gt; for holding the ears on.  They fell out and the ears fell off multiple times.&lt;/p&gt;

&lt;p&gt;For reasons that will become obvious later, I eventually gave up on the provided screws and replaced them with my own M4x12 bolts.&lt;/p&gt;

&lt;p&gt;I was going to install the rack rails next, but since they were greasy/oily I decided to do them later.&lt;/p&gt;

&lt;h3 id=&quot;noctua-nf-a8-pwm&quot;&gt;Noctua NF-A8 PWM&lt;/h3&gt;

&lt;p&gt;I used 3 of the Noctua NF-A8 PWM fans.&lt;/p&gt;

&lt;p&gt;Airflow direction was printed on the fans.  Make sure all your labels are facing the same way.  Even though I was checking, I mounted one
backwards and had to redo it.&lt;/p&gt;

&lt;p&gt;There was the question of metal or rubber screws.  It came with both.&lt;/p&gt;

&lt;p&gt;I tried to use the rubber ones first, but was unable to get them through the hole in the case, so switched to the metal screws instead.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/NG4JtbLLxpEsj5bRA&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_195553.jpg&quot; alt=&quot;Fans&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am providing a PWM Controller that has two fan connectors, but using 3 fans.  As such, I put a y-cable (included with the fans) on the
two near the NVME.&lt;/p&gt;

&lt;h3 id=&quot;enhance-enp-8345-l-ovt&quot;&gt;Enhance ENP-8345-L-OVT&lt;/h3&gt;

&lt;p&gt;I have been checking out the &lt;a href=&quot;https://www.youtube.com/@overtekltd2212&quot;&gt;Overtek youtube channel&lt;/a&gt; where he does PSU teardowns. I bought the 
Enhance ENP-8345-L-OVT 450w FlexPSU from him.  He did the Sunon fan mod on it.  We had discussed the Noctua mod, but he said it would not
work as well on low idle power.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/5dWkaQsUMEiDHzDdA&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_201740_redacted.jpg&quot; alt=&quot;PSU&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;https://photos.app.goo.gl/vhyopR4q5tbKwHoV7&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_201843.jpg&quot; alt=&quot;PSU Headers&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The loom set had multiple cables.  I only attached the one needed for ATX Power, which I would later attach to the MB.&lt;/p&gt;

&lt;p class=&quot;message&quot;&gt;&lt;strong&gt;Attention&lt;/strong&gt; This connection on the Turing Pi 2 was a bit loose causing power to fluctuate. Check it carefully. It doesn’t clip well on the MB side.&lt;/p&gt;

&lt;p&gt;The PSU was a really tight fit under the drive cage.  I had originally planned on mounting the PWM controller in that drive cage; but due
to the fit and vent holes in the PSU, I removed the drive cage.&lt;/p&gt;

&lt;h3 id=&quot;rk1&quot;&gt;RK1&lt;/h3&gt;

&lt;p&gt;Next up was to prepare the Turing Pi 2 itself.&lt;/p&gt;

&lt;p&gt;There is an HDMI Switch onboard.  I just confirmed that all dip switches were set to OFF for use with the RK1 modules.&lt;/p&gt;

&lt;p&gt;I installed the heatsink/fans onto the RK1 modules.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/Gz72EfEUmXQZNmbq8&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_212244.jpg&quot; alt=&quot;Attach Heatsinks&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then mounted the RK1 modules onto the Turing and attached their individual fan cables.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/cKwRNrHk6g7sXXcd9&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_213005.jpg&quot; alt=&quot;Attach RK1&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;extenders&quot;&gt;Extenders&lt;/h3&gt;

&lt;p&gt;As a reminder, both the BMC SD Card and the NVME for each node are inaccessible once mounted to the case.&lt;br /&gt;
As such, I am using extenders.&lt;/p&gt;

&lt;p&gt;You can see how they attach here.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/uioMKL2QjHJkhCTP9&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_214147.jpg&quot; alt=&quot;Extender Attachment&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These NVME cables are much to bulky and raise the entire board up.  As a result, I had to remove the IO Shield from the case
and raise the entire Turing board up with spacers.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/w9oX3Tak7D6EX886A&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_221545.jpg&quot; alt=&quot;NVME Extended&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;final-internal-touches&quot;&gt;Final Internal Touches&lt;/h3&gt;

&lt;p&gt;I attached the PSU to the Turing MB.&lt;/p&gt;

&lt;p&gt;I attached the case USB to the Node4-USB3 header.&lt;/p&gt;

&lt;p&gt;I attached the front panel power switch and LED.&lt;/p&gt;

&lt;p&gt;Then it was time for the PWM Controller.  I needed to have some of these other cables in place to better determine where it would fit.
I had put a thermistor under the middle of the Turing.  It would control the one fan near the PSU and Turing MB.
The other thermistor is in the middle of the NVME drives. It would control the fan near the NVME as well as the fan between the NVME and the Turing MB.
I also attached their buzzer, which in hindsight was maybe not a good idea since I didn’t bother configuring the PWM controller. I really need to do that.
For power, I used two leads from the Turing 12v Fan header to power the PWM controller. The PWM Controller itself is mounted with sticky standoffs.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/iNHfVRtBSiGaCYsQ6&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_223618.jpg&quot; alt=&quot;Fan Controller&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The headers on the PWM Controller are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;left side
    &lt;ul&gt;
      &lt;li&gt;thermistor for Turing&lt;/li&gt;
      &lt;li&gt;thermistor for NVME&lt;/li&gt;
      &lt;li&gt;Buzzer&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;right side
    &lt;ul&gt;
      &lt;li&gt;PSU/Turing Fan&lt;/li&gt;
      &lt;li&gt;Turing/NVME Fans&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I attached the NVME drives to the carrier boards.&lt;/p&gt;

&lt;p&gt;Taped the SD Card carrier to the case (temporarily).&lt;/p&gt;

&lt;p&gt;Inserted the battery.&lt;/p&gt;

&lt;p&gt;Some minor cable management.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/XmtbVNTvxWTdiQjG8&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240520_225954.jpg&quot; alt=&quot;Cable Managed&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;rack-rails-attempt&quot;&gt;Rack Rails attempt&lt;/h3&gt;

&lt;p&gt;I got the &lt;code class=&quot;highlighter-rouge&quot;&gt;26&quot; slides for 28&quot; to 46&quot; rack post spacing&lt;/code&gt; rack rail kit with the Sliger 2U chassis.  As such, they did fit the case itself fairly well.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/amg4JeqhVurDWFdq7&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240524_181613.jpg&quot; alt=&quot;Rail Kit&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I mounted them into my Sysracks cabinet, I was able to mount them to all 4 posts.  They were not as easy as some Ready Rails, for example,
but it was doable.&lt;/p&gt;

&lt;p&gt;When I went to slide the chassis into the rails, it seemed to work at first.  The problem was once the chassis reached where the ears would normally mount.  It wasn’t
wide enough.  Just barely, but both sides hit.  It needed a few more mm on both sides to fit.  I spent a good hour trying to figure something out.  The
chassis &lt;em&gt;or&lt;/em&gt; the rails fit, but not both.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/wYxhUYgPQucAx9A89&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240524_193701.jpg&quot; alt=&quot;Too Wide&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what to do?  I really want it on rails.  How else am I going to tweak the PWM or swap out a node or NVME without downtime?
However, that can be a tomorrow problem.  For today, I just need it mounted.&lt;/p&gt;

&lt;p&gt;I removed the rails from the cabinet and committed to mounting via the rack ears for today.&lt;/p&gt;

&lt;p&gt;Given that the rack ears kept falling off, I was not about to mount them to the cabinet using them with the stock screws.
I replaced them with M4x12 bolts and that worked pretty well.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/T9fd9dDBnXQjKB6r6&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/P_20240524_202410.jpg&quot; alt=&quot;Mounted&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;connecting&quot;&gt;Connecting&lt;/h3&gt;

&lt;p&gt;I attached the network from Turing Pi 2 to the Patch Panel; then from the Patch Panel to the Unifi.&lt;/p&gt;

&lt;p&gt;I attached the power from the Turing Pi 2 to an unswitched outlet on the battery backup.  Hmmm, I’m going to have to change that.
I guess it’s time to consolidate the two wifi routers so I can steal their outlet.  Tomorrow-ish.&lt;/p&gt;

&lt;p&gt;If anyone comes across this post, the correct power cable for the Enhance ENP-8345-L-OVT is &lt;code class=&quot;highlighter-rouge&quot;&gt;NEMA 5-15P to IEC-320-C13&lt;/code&gt;. 
I accidentally got the wrong one the first time.&lt;/p&gt;

&lt;h2 id=&quot;bmc&quot;&gt;BMC&lt;/h2&gt;

&lt;p&gt;It took a few tries to turn it on.  It wasn’t clear to me what was going on, but here’s what I figure out.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;While the BMC is booting, the power button doesn’t really do anything.&lt;/li&gt;
  &lt;li&gt;BMC can take 15-30 seconds to boot.&lt;/li&gt;
  &lt;li&gt;If the power doesn’t come on by itself, you need to hold the power button down for a few seconds for it to boot the nodes.&lt;/li&gt;
  &lt;li&gt;Turning off the power does not power off the BMC. You either need to press the BMC Reset (hard without the rails) or pull the power.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;accessing-the-bmc&quot;&gt;Accessing the BMC&lt;/h3&gt;

&lt;p&gt;First I tried accessing it via https://turingpi.local/ and then https://turingpi/.  I was not having much luck with either initially.&lt;/p&gt;

&lt;p&gt;Checking the Unifi dashboard, I could see that turing.localdomain as well as the mac address of each node had an IP address on the local network.
Grabbing the IP address for the BMC, I was able to open the web ui.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/vFvE2gBbchbtsSkz6&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/initial_bmc_connection.png&quot; alt=&quot;Original BMC&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UI did not look like the one in the documentation.  It did not specify what version of the firmware it was either.&lt;/p&gt;

&lt;p&gt;I tried upgrading the firmware via the web ui.  It did not work.&lt;/p&gt;

&lt;p&gt;I tried ssh to the BMC, but the credentials didn’t work.  This seemed to indicate it was on the older firmware.&lt;/p&gt;

&lt;p&gt;It seems that the board was shipped with the 1.x firmware.  For some reason, I thought it
had been shipped with the 2.x firmware.  That also explains why the PWM fan header is not populated.&lt;/p&gt;

&lt;p&gt;I actually spent a lot of time trying to troubleshoot this that I think I wouldn’t have, had the rack rails have worked.
I pulled the chassis out of the cabinet while still attached to the network and power.&lt;/p&gt;

&lt;p&gt;I tried to flash the BMC from the SD Card, but that didn’t work.  The BMC never got into the flashing state.&lt;/p&gt;

&lt;p&gt;I tried connecting the UART/TTL cable, but at first there was just no output.
One Amazon review said that they had to swap pins.  Worth a shot.  I swapped the &lt;em&gt;labeled&lt;/em&gt; TXD and RXD pins and got a line of text at power up.
I pressed the BMC reset with these pins swapped and started getting output.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mount: mounting /dev/mmcblk0p1 on /mnt/sdcard/ failed: No such file or directory&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Maybe the SD card was corrupted?  I reflashed the SD Card, but it did no good.&lt;/p&gt;

&lt;p&gt;Using the serial console, I enabled SSH.  I tried copying the SDCard contents manually to mmcblk0.&lt;/p&gt;

&lt;p&gt;Turns out, Amazon got me again. the SD Card extender cable was the problem.  Removing that and plugging the SD card in directly allowed flashing.
The unfortunate side effect of that is that I had to unmount the board to do it, and will again if I need access to the SD card. Not ideal.&lt;/p&gt;

&lt;p&gt;Now https://turingpi/ worked.&lt;/p&gt;

&lt;h3 id=&quot;flashing-nodes&quot;&gt;Flashing Nodes&lt;/h3&gt;

&lt;p&gt;I flashed Ubuntu Server 24.04 from &lt;a href=&quot;https://github.com/Joshua-Riek/ubuntu-rockchip&quot;&gt;this repo&lt;/a&gt; to all four nodes.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/5HTkzzvvaTuDxESX6&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/flashing_nodes.png&quot; alt=&quot;Flashing Nodes&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I noticed that the nodes no longer showed up in Unifi.&lt;/p&gt;

&lt;h2 id=&quot;tpi&quot;&gt;tpi&lt;/h2&gt;

&lt;p&gt;I installed tpi with &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo install tpi&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Running &lt;code class=&quot;highlighter-rouge&quot;&gt;tpi info --host turingpi&lt;/code&gt; allowed me to see both the BMC firmware version and IP address.
The hostname later changed when I set a fixed name and IP in Unifi.&lt;/p&gt;

&lt;p&gt;Based on &lt;a href=&quot;https://docs.turingpi.com/docs/tpi-uart&quot;&gt;these instructions&lt;/a&gt;, I was able to use tpi to access the serial console of each node.&lt;/p&gt;

&lt;h3 id=&quot;interjection-from-the-future&quot;&gt;Interjection from the Future&lt;/h3&gt;

&lt;p&gt;Originally, the BMC and all nodes were on the same network as the rest of the house (well, technically, the rest of the wired network).
I went in and created a VLAN for the Kubernetes cluster and assigned it to that port on Unifi. I even wiped out the cluster and recreated it.
We’ll just pretend that I did that before booting up the BMC the first time.&lt;/p&gt;

&lt;h3 id=&quot;setting-up-the-nodes&quot;&gt;Setting up the Nodes&lt;/h3&gt;

&lt;p&gt;First, we ssh into the BMC with &lt;code class=&quot;highlighter-rouge&quot;&gt;ssh root@turingpi&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We then turn off the power to all nodes via the web ui.  This is so we can monitor the boot up.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Node 1: /dev/ttyS2
Node 2: /dev/ttyS1
Node 3: /dev/ttyS4
Node 4: /dev/ttyS5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From inside the BMC SSH session, we can access Node 1 with &lt;code class=&quot;highlighter-rouge&quot;&gt;picocom /dev/ttyS2 -b 115200&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, power on node 1 from the web ui.&lt;/p&gt;

&lt;p&gt;When it powers on, it will ask for the username/password.  We’ll use the default &lt;code class=&quot;highlighter-rouge&quot;&gt;ubuntu/ubuntu&lt;/code&gt;, then be required to set a new password.
This would be different if we had used the desktop ubuntu image.&lt;/p&gt;

&lt;p&gt;Then it’s time to run the apt update/upgrade.&lt;/p&gt;

&lt;p&gt;Since I am running Ubuntu Server, I did not enable the CPU Govenor.  I may consider it later, if it is running too hot.&lt;/p&gt;

&lt;p&gt;Then, we need to setup the NVME. We can see the drive with &lt;code class=&quot;highlighter-rouge&quot;&gt;lsblk&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fdisk -l /dev/nvme0n1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I modified &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hostname&lt;/code&gt; and called it &lt;code class=&quot;highlighter-rouge&quot;&gt;turing-node1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I then modified &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; and added entries for all 4 nodes.
I also went into Unifi and set them all as Fixed IP.  I also set the dns name in Unifi.
The IPs aren’t in order, but they won’t change.&lt;/p&gt;

&lt;p&gt;Last, reboot via the web ui while still connected to picocom.&lt;/p&gt;

&lt;p&gt;I couldn’t get picocom to exit, so I closed my terminal to close it. Repeat for Nodes 2-4.&lt;/p&gt;

&lt;h2 id=&quot;software-install&quot;&gt;Software Install&lt;/h2&gt;

&lt;p&gt;Next, we need to install some software.&lt;/p&gt;

&lt;p&gt;I created a git repo and cloned it into Node1.  I plan on keeping charts/deployments/etc in there.&lt;/p&gt;

&lt;h3 id=&quot;k3s-1&quot;&gt;k3s&lt;/h3&gt;

&lt;p&gt;For the following commands, &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;NODE1&amp;gt;&lt;/code&gt; refers to the IP address of &lt;code class=&quot;highlighter-rouge&quot;&gt;turing-node1&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;TOKEN&amp;gt;&lt;/code&gt; refers to an auto-generated token (I used Bitwarden to make it).&lt;/p&gt;

&lt;p&gt;On Node 1:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-sfL&lt;/span&gt; https://get.k3s.io | sh &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; - &lt;span class=&quot;nt&quot;&gt;--write-kubeconfig-mode&lt;/span&gt; 644 &lt;span class=&quot;nt&quot;&gt;--disable&lt;/span&gt; servicelb &lt;span class=&quot;nt&quot;&gt;--token&lt;/span&gt; &amp;lt;TOKEN&amp;gt; &lt;span class=&quot;nt&quot;&gt;--node-ip&lt;/span&gt; &amp;lt;NODE1&amp;gt; &lt;span class=&quot;nt&quot;&gt;--disable-cloud-controller&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--disable&lt;/span&gt; local-storage
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then on Nodes 2-4:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-sfL&lt;/span&gt; https://get.k3s.io | &lt;span class=&quot;nv&quot;&gt;K3S_URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;https://&amp;lt;NODE1&amp;gt;:6443 &lt;span class=&quot;nv&quot;&gt;K3S_TOKEN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;lt;TOKEN&amp;gt; sh -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Update labels on Node 1:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl label nodes turing-node1 kubernetes.io/role&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker
kubectl label nodes turing-node2 kubernetes.io/role&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker  
kubectl label nodes turing-node3 kubernetes.io/role&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker  
kubectl label nodes turing-node4 kubernetes.io/role&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker

kubectl label nodes turing-node1 node-type&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker  
kubectl label nodes turing-node2 node-type&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker  
kubectl label nodes turing-node3 node-type&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker  
kubectl label nodes turing-node4 node-type&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;worker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;helm&quot;&gt;Helm&lt;/h3&gt;

&lt;p&gt;Create a kubernetes config:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;KUBECONFIG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;~/.kube/config
&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; ~/.kube 2&amp;gt; /dev/null
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;k3s kubectl config view &lt;span class=&quot;nt&quot;&gt;--raw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$KUBECONFIG&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;chmod &lt;/span&gt;600 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$KUBECONFIG&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Append the output of &lt;code class=&quot;highlighter-rouge&quot;&gt;echo &quot;KUBECONFIG=$KUBECONFIG&quot;&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/environment&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we can install Helm.
I actually stored this inside the git repo mentioned earlier.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;helm  
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;helm  
curl &lt;span class=&quot;nt&quot;&gt;-fsSL&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
&lt;span class=&quot;nb&quot;&gt;chmod &lt;/span&gt;700 get_helm.sh
./get_helm.sh
helm version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;metallb&quot;&gt;MetalLB&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;helm repo add metallb https://metallb.github.io/metallb
helm search repo metallb
helm upgrade &lt;span class=&quot;nt&quot;&gt;--install&lt;/span&gt; metallb metallb/metallb &lt;span class=&quot;nt&quot;&gt;--create-namespace&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--namespace&lt;/span&gt; metallb-system &lt;span class=&quot;nt&quot;&gt;--wait&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unifi gave us a range of IPs for our VLAN. I assigned the very first one as static for the BMC.  As such, we will offset the start range for MetalLB by one.&lt;/p&gt;

&lt;p&gt;For below, we will use &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START&amp;gt;&lt;/code&gt; to reference one more than Unifi said the range started at, and &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;END&amp;gt;&lt;/code&gt; for the end of the range Unifi identified.&lt;/p&gt;

&lt;p&gt;Create &lt;code class=&quot;highlighter-rouge&quot;&gt;metallb/deployment.yaml&lt;/code&gt; inside our repo&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;metallb.io/v1beta1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;IPAddressPool&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default-pool&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;metallb-system&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;addresses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;lt;START&amp;gt;-&amp;lt;END&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;metallb.io/v1beta1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;L2Advertisement&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;metallb-system&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ipAddressPools&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default-pool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now, we apply it.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl apply &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; deployment.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, we’ll verify that traefik is taking the first IP in our range (&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START&amp;gt;&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl describe svc traefik &lt;span class=&quot;nt&quot;&gt;--namespace&lt;/span&gt; kube-system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And we can verify that http://&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START&amp;gt;&lt;/code&gt; shows the generic 404 not found&lt;/p&gt;

&lt;h3 id=&quot;longhorn&quot;&gt;Longhorn&lt;/h3&gt;

&lt;p&gt;First we need to setup the NVME drives. For each node:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;nfs-common open-iscsi util-linux
&lt;span class=&quot;nb&quot;&gt;sudo mkdir&lt;/span&gt; /storage
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mkfs.ext4 /dev/nvme0n1
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;su - root
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/dev/nvme0n1 /storage ext4 defaults 0 0&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;tee&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; /etc/fstab
&lt;span class=&quot;nb&quot;&gt;exit
sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For this section, we will use &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START+1&amp;gt;&lt;/code&gt; to define the IP address 1 higher than the start of the MetalLB/Traffic &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, on Node 1 we will install Longhorn to &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START+1&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;helm repo add longhorn https://charts.longhorn.io
helm &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;longhorn longhorn/longhorn &lt;span class=&quot;nt&quot;&gt;--namespace&lt;/span&gt; longhorn-system &lt;span class=&quot;nt&quot;&gt;--create-namespace&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; defaultSettings.defaultDataPath&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/storage&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; service.ui.loadBalancerIP&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;START+1&amp;gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--set&lt;/span&gt; service.ui.type&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LoadBalancer&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Wait for everything to be running:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; longhorn-system get pod
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Verify StorageClass is present&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl get storageclass
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Open http://&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START+1&amp;gt;&lt;/code&gt; and Longhorn UI should be accessible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should show that it is indeed on &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START+1&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl describe svc &lt;span class=&quot;nt&quot;&gt;--namespace&lt;/span&gt; longhorn-system longhorn-frontend
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://photos.app.goo.gl/3hzL4H6YwMcub7nS8&quot;&gt;&lt;img src=&quot;/assets/img/turingpi2/longhorn.png&quot; alt=&quot;Longhorn&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;test-longhorn&quot;&gt;Test Longhorn&lt;/h4&gt;

&lt;p&gt;Create &lt;code class=&quot;highlighter-rouge&quot;&gt;longhorn/pvc_test.yaml&lt;/code&gt; in our repo&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;  
&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;v1&lt;/span&gt;  
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;PersistentVolumeClaim&lt;/span&gt;  
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test-pvc&lt;/span&gt;  
  &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default&lt;/span&gt;  
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  
  &lt;span class=&quot;na&quot;&gt;accessModes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ReadWriteOnce&lt;/span&gt;  
  &lt;span class=&quot;na&quot;&gt;storageClassName&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;longhorn&lt;/span&gt;  
  &lt;span class=&quot;na&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  
    &lt;span class=&quot;na&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  
      &lt;span class=&quot;na&quot;&gt;storage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;10Mi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Apply it:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl apply &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; pvc_test.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Verify that it worked:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl get pvc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that it also shows up in the Longhorn UI.&lt;/p&gt;

&lt;p&gt;Cleanup our test:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl delete &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; pvc_test.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;argocd&quot;&gt;ArgoCD&lt;/h3&gt;

&lt;p&gt;On node 1:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl create namespace argocd
kubectl apply &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, we will wait for it to complete&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl get pods &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For this next section, we will use &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START+2&amp;gt;&lt;/code&gt; to refer to the IP address 2 above the MetalLB &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We are going to give &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START+2&amp;gt;&lt;/code&gt; to Argo.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl patch service argocd-server &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd &lt;span class=&quot;nt&quot;&gt;--patch&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{ &quot;spec&quot;: { &quot;type&quot;: &quot;LoadBalancer&quot;, &quot;loadBalancerIP&quot;: &quot;&amp;lt;START+2&amp;gt;&quot; } }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;login&quot;&gt;Login&lt;/h3&gt;

&lt;p&gt;Create &lt;code class=&quot;highlighter-rouge&quot;&gt;argocd/get_credentials.sh&lt;/code&gt; in our repo.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;http://&amp;lt;START+2&amp;gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Username=admin&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PASS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;kubectl &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd get secret argocd-initial-admin-secret &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;jsonpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{.data.password}&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;base64&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Password=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PASS&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run the following to commit it and run the script:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;chmod &lt;/span&gt;744 get_credentials.sh
./get_credentials
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Open http://&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START+2&amp;gt;&lt;/code&gt; and enter the supplied credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;testing-argo&quot;&gt;Testing Argo&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Add the files from &lt;a href=&quot;https://gitlab.com/vstrycek/turingpi-error-pages&quot;&gt;this repo&lt;/a&gt; into &lt;code class=&quot;highlighter-rouge&quot;&gt;traefik/error-pages&lt;/code&gt; in your GitOps repo from before&lt;/li&gt;
  &lt;li&gt;Go into &lt;code class=&quot;highlighter-rouge&quot;&gt;Settings | Repositories&lt;/code&gt; and add our your repo from before
    &lt;ul&gt;
      &lt;li&gt;Use the SSH key you created on Node 1&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Go into &lt;code class=&quot;highlighter-rouge&quot;&gt;Applications | Create Application&lt;/code&gt; (or &lt;code class=&quot;highlighter-rouge&quot;&gt;New App&lt;/code&gt; if it isn’t your first one)
    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Application Name: error-pages
Project Name: default
Sync Policy: Manual
Auto-Create Namespace: &quot;check&quot;
Repository URL(GIT): &amp;lt;your gitops repo url&amp;gt;
Revision: HEAD
Path: traefik/error-pages
Cluster URL: https://kubernetes.default.svc
Namespace: error-pages
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Find the traefik IP address:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl describe svc traefik &lt;span class=&quot;nt&quot;&gt;--namespace&lt;/span&gt; kube-system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;We can see it is at &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Open http://&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;START&amp;gt;&lt;/code&gt; and we can now shows a better 404 error page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enable CLI from the GUI&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl patch role argocd-server &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd &lt;span class=&quot;nt&quot;&gt;--type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;json &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'[{&quot;op&quot;: &quot;add&quot;, &quot;path&quot;: &quot;/rules/-&quot;, &quot;value&quot;: {&quot;apiGroups&quot;: [&quot;&quot;], &quot;resources&quot;: [&quot;pods/exec&quot;], &quot;verbs&quot;: [&quot;create&quot;]}}]'&lt;/span&gt;
kubectl patch configmap argocd-cm &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{&quot;data&quot;: {&quot;exec.enabled&quot;: &quot;true&quot;}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Next we will delete and restart the running pods&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl delete pods &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd &lt;span class=&quot;nt&quot;&gt;--field-selector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;status.phase&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Running
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then wait for them to get into the Running state&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kubectl get pod &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; argocd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;While this is just scratching the surface, I now have a 24x7 Kubernetes cluster running in its own VLAN that I can experiment and learn with.&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="kubernetes" /><summary type="html"></summary></entry><entry><title type="html">Framework 16: Better, Faster, Stronger</title><link href="https://www.malachid.com/blog/2024-03-24-framework16/" rel="alternate" type="text/html" title="Framework 16: Better, Faster, Stronger" /><published>2024-03-24T19:43:03-07:00</published><updated>2024-03-24T19:43:03-07:00</updated><id>https://www.malachid.com/blog/framework16</id><content type="html" xml:base="https://www.malachid.com/blog/2024-03-24-framework16/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#ordering-process-and-timeline&quot; id=&quot;markdown-toc-ordering-process-and-timeline&quot;&gt;Ordering Process and Timeline&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#unboxing-experience&quot; id=&quot;markdown-toc-unboxing-experience&quot;&gt;Unboxing Experience&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#build-comparison-to-fw13&quot; id=&quot;markdown-toc-build-comparison-to-fw13&quot;&gt;Build Comparison to FW13&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#modules&quot; id=&quot;markdown-toc-modules&quot;&gt;Modules&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#os-install&quot; id=&quot;markdown-toc-os-install&quot;&gt;OS Install&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#windows-11&quot; id=&quot;markdown-toc-windows-11&quot;&gt;Windows 11&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#ubuntu-2204&quot; id=&quot;markdown-toc-ubuntu-2204&quot;&gt;Ubuntu 22.04&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#switching-between-oss&quot; id=&quot;markdown-toc-switching-between-oss&quot;&gt;Switching between OS’s&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#issues&quot; id=&quot;markdown-toc-issues&quot;&gt;Issues?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;When I purchased my &lt;a href=&quot;/blog/2021-08-16-framework/&quot;&gt;original framework&lt;/a&gt;,
I was pretty happy with the modularity of the new machine.  Even so, I was downgrading from a
larger touchscreen and keypad.&lt;/p&gt;

&lt;p&gt;A lot of people don’t like either of those features.  I was using both, a lot.&lt;/p&gt;

&lt;p&gt;So when Framework said that they had a new model that had a bigger screen, numpad and with connectivity
that would allow later support for touchscreens, I was all in.&lt;/p&gt;

&lt;p&gt;On top of that, the new machine would be AMD instead of Intel.&lt;/p&gt;

&lt;p&gt;If I am completely honest, I would rather have NVIDIA for the graphics; but on this newer model,
the graphics can be swapped out - so we’ll see if that comes about.&lt;/p&gt;

&lt;h2 id=&quot;ordering-process-and-timeline&quot;&gt;Ordering Process and Timeline&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Date&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;18 July 2023&lt;/td&gt;
      &lt;td&gt;Pre-Order FW16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8 March 2024&lt;/td&gt;
      &lt;td&gt;Confirmation email that they are preparing batch 4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;13 March 2024&lt;/td&gt;
      &lt;td&gt;Credit Card showed Pending Authorization&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;14 March 2024&lt;/td&gt;
      &lt;td&gt;Shipping Notification that it should arrive on 3/18&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;18 March 2024&lt;/td&gt;
      &lt;td&gt;Order Received&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;What did I order?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Framework Laptop 16 DIY Edition (AMD Ryzen™ 7040 Series)
    &lt;ul&gt;
      &lt;li&gt;System: Ryzen™ 9 7940HS&lt;/li&gt;
      &lt;li&gt;Expansion Bay Module: Graphics Module (AMD Radeon™ RX 7700S)&lt;/li&gt;
      &lt;li&gt;Power Adapter: 180W Power Adapter&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Power Adapter Region: US / CA&lt;/li&gt;
  &lt;li&gt;Expansion Bay: Expansion Bay Shell
    &lt;ul&gt;
      &lt;li&gt;not using this, but have it for a backup in case I am dealing with repairs&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Memory: DDR5-5600 - 64GB (2 x 32GB)&lt;/li&gt;
  &lt;li&gt;Storage: WD_BLACK™ SN850X NVMe™- M.2 2280 - 4TB
    &lt;ul&gt;
      &lt;li&gt;no 2230 at this time, though I do have long term plans for that&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Keyboard: RGB US English&lt;/li&gt;
  &lt;li&gt;Laptop Bezel: Framework Laptop 16 Bezel - Black&lt;/li&gt;
  &lt;li&gt;Numpad: Numpad Module&lt;/li&gt;
  &lt;li&gt;2x USB-A Expansion Card&lt;/li&gt;
  &lt;li&gt;2x USB-C Expansion Card&lt;/li&gt;
  &lt;li&gt;DisplayPort (2nd Gen) Expansion Card&lt;/li&gt;
  &lt;li&gt;HDMI (3rd Gen) Expansion Card&lt;/li&gt;
  &lt;li&gt;Audio Expansion Card&lt;/li&gt;
  &lt;li&gt;2x Spacer: Black
    &lt;ul&gt;
      &lt;li&gt;When I ordered these, there was no picture or description. I thought they may fit next to the touchpad, but they only replace the numpad.&lt;/li&gt;
      &lt;li&gt;I can hold on to them in case I am dealing with numpad repairs.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Accessories &amp;amp; Tools: Poster, patch, and sticker sheet illustrated by Stephen Maurice Graham&lt;/li&gt;
  &lt;li&gt;Accessories &amp;amp; Tools: Starfield™ Premium Edition game code (only with configurations that include a Graphics Module)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might be wondering why I ordered extra ports when I already have them for the FW13. I’m likely
going to repurpose that machine for my girlfriend, so I thought I should get some additional modules.&lt;/p&gt;

&lt;p&gt;Surprisingly, that didn’t occur to me when it came to the boot drives.  I was planning on reusing my
existing ones, forgetting that I need them active at the same time in order to read install instructions.&lt;/p&gt;

&lt;p&gt;So, I also ordered after the fact:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2x 1TB Expansion Card&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To top it off, my existing Slappa laptop bag is apparently too large to be taking on the various international
flights I have done recently.  I went ahead and bought a new laptop bag to hold it as well.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Elements Backpack Pro&lt;/li&gt;
  &lt;li&gt;Elements Tech Case&lt;/li&gt;
  &lt;li&gt;Zip Clutch&lt;/li&gt;
  &lt;li&gt;Zip Pouch&lt;/li&gt;
  &lt;li&gt;HUB Keychain&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;unboxing-experience&quot;&gt;Unboxing Experience&lt;/h2&gt;

&lt;p&gt;I won’t bore you with the whole unboxing experience that I am sure you have seen everywhere else by now. 
Let me just say that they did a really good job of having a place for everything.  Here’s a couple pics to show
you what I mean.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework16/P_20240319_182819.jpg&quot; alt=&quot;First Impression&quot; /&gt; &lt;img src=&quot;/assets/img/framework16/P_20240319_182959.jpg&quot; alt=&quot;Paperwork&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework16/P_20240319_183049.jpg&quot; alt=&quot;Big items&quot; /&gt; &lt;img src=&quot;/assets/img/framework16/P_20240319_183123.jpg&quot; alt=&quot;Accessories&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework16/P_20240319_183229.jpg&quot; alt=&quot;Laptop&quot; /&gt; &lt;img src=&quot;/assets/img/framework16/P_20240319_183307.jpg&quot; alt=&quot;Memory and Shell&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework16/P_20240319_183435.jpg&quot; alt=&quot;Power&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;build-comparison-to-fw13&quot;&gt;Build Comparison to FW13&lt;/h2&gt;

&lt;p&gt;Compared to the 5 screws on the FW13, there are 17 on the FW16.  You might think I’d immediately say that the FW16 is 
harder to disassemble; however, that’s not the case.&lt;/p&gt;

&lt;p&gt;Hear me out.&lt;/p&gt;

&lt;p&gt;With the FW13, there are only 5 screws, however you have to turn the machine upside down and take the screws out of the
bottom of the machine, then turn it over and finish the disassembly.  While yes, there are more screws on the FW16, you
don’t have to turn the laptop over (repeatedly if it isn’t unscrewed enough) meaning that the base of the laptop is sturdy
during the entire assembly.  I found that comforting.&lt;/p&gt;

&lt;p&gt;Where I did find some difficulty was in removing and reattaching the trackpad.  It didn’t feel like it was lined up 
properly because it seemed to be sticking over the edge too much; while at the same time overlapping the top row. It was
correct, so I imagine it will just take getting used to.  That being said, detaching and re-attaching the touchpad on
the FW16 doesn’t involve any inconvenient cables like the FW13.&lt;/p&gt;

&lt;p&gt;The DIY model came with the graphics module already attached.  I have not tried removing and reattaching the Interposer.
This was an area that caused some confusion though. The Expansion Bay Shell Interposer and the Graphics Module Interposer
go into the same location but are not the same item.  As such, ordering the DIY with both the bare expansion and the graphics
module results in a spare piece being shipped to you with no instructions during the install guide.  It’s there in case
you switch to the other module.&lt;/p&gt;

&lt;p&gt;The FW13 also had a finicky wifi module needing attached.  This came pre-attached in the FW16 DIY module.  I have not tried
removing it yet.&lt;/p&gt;

&lt;p&gt;The magnets were both a help and a hindrance.  They help put everything in place and ensure they are aligned. When removing
items, it will take some time to figure out the best way to remove them without exerting undue pressure anywhere.  They have
small tabs to hold onto, but I found just trying to lift there wasn’t always easy.&lt;/p&gt;

&lt;h2 id=&quot;modules&quot;&gt;Modules&lt;/h2&gt;

&lt;p&gt;The choice about where to put modules is a little more finicky than on the FW13.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://knowledgebase.frame.work/en_us/expansion-card-slot-functionality-on-framework-laptop-16-rkUjGm7cn?_gl=1*a2cbxv*sg_ga4w_production_ga*MjA4MjAxNzE3MS4xNzEwOTg4OTUx*sg_ga4w_production_ga_PYG8X65YJJ*MTcxMTMzNjkxMS41LjAuMTcxMTMzNjkxMS42MC4wLjA.&quot;&gt;&lt;img src=&quot;/assets/img/framework16/modules.png&quot; alt=&quot;Module Configuration&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first glance, you’ll notice that there are certain ports you should not use for USB-A.&lt;/p&gt;

&lt;p&gt;There are also some ports that don’t support HDMI or DP.&lt;/p&gt;

&lt;p&gt;Only two of the ports support USB4.&lt;/p&gt;

&lt;p&gt;So what I ended up with:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Left (Back at Top)&lt;/th&gt;
      &lt;th&gt;Right (Back at Top)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1. USB-C&lt;/td&gt;
      &lt;td&gt;4. USB-C/Power&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2. USB-A&lt;/td&gt;
      &lt;td&gt;5. 1TB OS Boot Drive&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3. Audio&lt;/td&gt;
      &lt;td&gt;6. USB-A&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;I rarely need the DP or HDMI unless I am on a work trip.  When I am, I can replace the USB-C or USB-A on the left side for the display output.&lt;/p&gt;

&lt;p&gt;I also have a few of the FW13 modules, so I can swap an extra USB-C into one of the USB-A slots if I need to.  Generally, for Android development,
I am using a &lt;a href=&quot;https://nomadgoods.com/products/universal-kevlar-cable-usb-c&quot;&gt;modular cable&lt;/a&gt; to connect the phone.&lt;/p&gt;

&lt;h2 id=&quot;os-install&quot;&gt;OS Install&lt;/h2&gt;

&lt;p&gt;You might recall from my FW13 that I do not install the OS to the NVME.  I know it would be faster, but I also know that the
chances of a Windows update breaking Grub during that process are far from zero.  As such, I am using the NVME for things like
git repos, compilation, etc.  I am then using the 1TB modules as the OS drives.&lt;/p&gt;

&lt;p&gt;I had decided I would start with both Ubuntu and Windows 11.  I’ll likely install Arch on another module later, like
I did last time.  I don’t expect to use Windows for much, but I play some games that need it.&lt;/p&gt;

&lt;p&gt;Before installing any OS, hit F2 repeatedly to get into the BIOS and change the UEFI settings from &lt;code class=&quot;highlighter-rouge&quot;&gt;Auto&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;Last&lt;/code&gt;.
This makes sure that the most recently attached USB shows up as first in the boot order.&lt;/p&gt;

&lt;p&gt;As a side note, I decided to leave Secure Boot enabled.&lt;/p&gt;

&lt;h3 id=&quot;windows-11&quot;&gt;Windows 11&lt;/h3&gt;

&lt;p&gt;The most frustrating part of the whole process was getting the license key. I tried originally buying it from Framework 
directly, however their Digital Delivery process is severely flawed.  After placing an order for a digital delivery, it took
half an hour for them to grant me access to the code.  I was not patient enough to wait that long, especially when reviews
online said others waited over a week.  When the digital delivery wasn’t available after multiple refreshes, I sent a message
to support; then gave up and ordered it directly from Microsoft.  They had their own issues, charging me twice and then
reimbursing once; but at least I had the code within seconds instead of some unknowable time in the future.  While two of
the charges did get reversed, paying $600 in one night for Windows licensing was a hard pill to swallow since Linux is my
daily driver.&lt;/p&gt;

&lt;p&gt;Using Rufus to create the boot drive was OK, because I had access to a Windows machine to create it from.  I kind of wish the
&lt;a href=&quot;https://guides.frame.work/Guide/Windows+11+Installation+on+the+Framework+Laptop+16+DIY+Edition/305?_gl=1*15zpkou*sg_ga4w_production_ga*MjEyODYyMTQyMi4xNzEwNjE1OTM2*sg_ga4w_production_ga_PYG8X65YJJ*MTcxMDk3MzQ0Ny42LjEuMTcxMDk3MzQ2MC40Ny4wLjA.&quot;&gt;Framework documentation&lt;/a&gt; 
had secondary instructions for those not already on Windows.&lt;/p&gt;

&lt;p&gt;I just used a small USB-C dongle for the installer, and tried to install Windows.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework16/P_20240320_160830.jpg&quot; alt=&quot;USB Error&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To get past this, I found a link to &lt;a href=&quot;https://decryptingtechnology.blogspot.com/2015/09/install-windows-10-on-usb-external-hard.html&quot;&gt;this blog post&lt;/a&gt; in the Framework forums.
It took a few tries to get it working, because multiple partitions listed were too small to install Windows 11.  In general, I set the Windows drive to about 900GB and 
doubled everything else except the msr partition.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Recovery Image : made 8192 instead of 4096&lt;/li&gt;
  &lt;li&gt;SYSTEM : made 200 instead of 100&lt;/li&gt;
  &lt;li&gt;Windows RE : it was only 350mb in the docs, but the image was 697mb. I set it to 1gb.&lt;/li&gt;
  &lt;li&gt;Windows : he had set it to 250gb. I went ahead and set it to 900gb.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing to take note of - if you try more than once, don’t make any assumptions.  The drive letters for everything change every time you start over.&lt;/p&gt;

&lt;p&gt;Once I followed that tutorial, I tried to continue with the install.  The Framework documentation said to choose &lt;code class=&quot;highlighter-rouge&quot;&gt;I don't have Internet&lt;/code&gt; so you can install the Wifi drivers.
Unfortunately, that was not an option.  For that, I followed the instructions &lt;a href=&quot;https://pureinfotech.com/bypass-internet-connection-install-windows-11/&quot;&gt;on this post&lt;/a&gt; to enable
that option.  Specifically, opening up a command prompt and entering &lt;code class=&quot;highlighter-rouge&quot;&gt;OOBE\BYPASSNRO&lt;/code&gt;.  This gives that option back to the dialog so that you can continue.&lt;/p&gt;

&lt;p&gt;The Framework docs mention setting the system name.  That didn’t come up automatically.  To set that, go into &lt;code class=&quot;highlighter-rouge&quot;&gt;System &amp;gt; Settings &amp;gt; About&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One last note about Windows, you have to hold the &lt;code class=&quot;highlighter-rouge&quot;&gt;SHIFT&lt;/code&gt; button when clicking Shutdown, or it only pretends to shutdown.  That’s even more important for me
since I’ll be removing the OS drive.&lt;/p&gt;

&lt;h3 id=&quot;ubuntu-2204&quot;&gt;Ubuntu 22.04&lt;/h3&gt;

&lt;p&gt;If I was willing to wait a few weeks, I would have likely installed 24.04 instead.  I was a bit impatient, however.&lt;/p&gt;

&lt;p&gt;Now, while all of the support docs appear to be on &lt;a href=&quot;https://frame.work/laptop-16-support&quot;&gt;this page&lt;/a&gt;, that Linux page is not helpful.
Instead, you want to go to the end of the &lt;code class=&quot;highlighter-rouge&quot;&gt;DIY Edition quick start guide&lt;/code&gt; and click on the &lt;a href=&quot;https://guides.frame.work/Guide/Ubuntu+22.04+LTS+Installation+on+the+Framework+Laptop+16/306&quot;&gt;Ubuntu link&lt;/a&gt;
from there.&lt;/p&gt;

&lt;p&gt;So a couple first steps:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Making the installation media&lt;/li&gt;
  &lt;li&gt;Swapping the 1TB module for a new empty one&lt;/li&gt;
  &lt;li&gt;Change the BIOS Linux Audio Compatibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Normally, I would use ZFS.  For this build, I used LVM.  I figured if I decided to upgrade from a 1TB drive to a 2TB drive, it would make it easier.&lt;/p&gt;

&lt;p&gt;During the install reboot process, it came up with the questions about the MOK.  I did enroll the MOK, but I was on the screen waiting to figure out
which keys I should enroll.  I was looking at the other machine trying to figure out where I saw that documentation.  It timed out and continued without
me enrolling any of the keys, so… I guess it’s fine?&lt;/p&gt;

&lt;p&gt;After install, I think the biggest problem so far has been Steam. Framework has &lt;a href=&quot;https://github.com/FrameworkComputer/dri_prime1-detection?tab=readme-ov-file#steam-game-setup-instructions-for-ubuntu-22043-lts-long-term-support---one-nvme-drive&quot;&gt;this doc&lt;/a&gt;
that tells you how to pass extra parameters to individual games; but the bigger problem was that no game would launch.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;snap&lt;/code&gt; version would add Steam to the tray and add game entries into the Apps Menu; but would not launch games&lt;/li&gt;
  &lt;li&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;.deb&lt;/code&gt; version would add a tray icon for Steam, but that was as much as it could do&lt;/li&gt;
  &lt;li&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;flatpak&lt;/code&gt; version actually works pretty well; it just doesn’t add entries into the Apps Menu for individual games.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I haven’t tried adding the FW change yet because it took so much trial and error just to get Steam to work at all.&lt;/p&gt;

&lt;h2 id=&quot;switching-between-oss&quot;&gt;Switching between OS’s&lt;/h2&gt;

&lt;p&gt;So what does it take for me to switch between Ubuntu and Windows?&lt;/p&gt;

&lt;p&gt;Simple. Turn off the machine, swap the 1TB module, turn on the machine.&lt;/p&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;Neither is aware that the other one exists, or tries to interfere with the other.&lt;/p&gt;

&lt;h2 id=&quot;issues&quot;&gt;Issues?&lt;/h2&gt;

&lt;p&gt;What issues have I seen so far?&lt;/p&gt;

&lt;p&gt;In general it seems to be working pretty well so far.  I tried running ESO from the Windows 1TB module. I’ve done compilation in Linux.&lt;/p&gt;

&lt;p&gt;The printer was auto-detected and added, whereas in the past I always had to download proprietary drivers to get it working.&lt;/p&gt;

&lt;p&gt;The fingerprint reader technically works, though I need to look into why it asks me for my password after logging me in.&lt;/p&gt;

&lt;p&gt;I did have one unusual issue today.  I tried to launch Chrome and the machine freaked out. Chrome wouldn’t launch.  I tried checking dmesg, and the screen sheared in half.
I tried starting Brave and it also wouldn’t launch.  The temps said it was around 45℃, so it shouldn’t have been too hot.  I closed everything, and during that process, a few
things were flashing.  Upon reboot, everything was working fine and the temps were about 56℃.  Not sure what had happened, but definitely going to keep an eye on that.&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="framework" /><summary type="html"></summary></entry><entry><title type="html">Upgrading the frame.work boot drive</title><link href="https://www.malachid.com/blog/2022-11-25-fw1tb/" rel="alternate" type="text/html" title="Upgrading the frame.work boot drive" /><published>2022-11-25T20:39:39-08:00</published><updated>2022-11-25T20:39:39-08:00</updated><id>https://www.malachid.com/blog/fw1tb</id><content type="html" xml:base="https://www.malachid.com/blog/2022-11-25-fw1tb/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#upgrading&quot; id=&quot;markdown-toc-upgrading&quot;&gt;Upgrading&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#no-boot-device&quot; id=&quot;markdown-toc-no-boot-device&quot;&gt;No boot device&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;If you have read the &lt;a href=&quot;/blog/2021-08-16-framework/&quot;&gt;prior frame.work post&lt;/a&gt;,
you would know that I chose to use the external USB modules for the boot drive(s) of various
OSes and share the internal NVME for a workspace.&lt;/p&gt;

&lt;p&gt;I had initially started with the boot OS being a 250gb drive.  Due to one program taking up
half that space, I decided it was time to upgrade it.&lt;/p&gt;

&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;

&lt;p&gt;I bought a new &lt;a href=&quot;https://frame.work/products/storage-expansion-card?v=FRACCFBZ0A&quot;&gt;1tb USB drive from frame.work&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I ended up following the &lt;a href=&quot;https://wolfgang-ziegler.com/blog/migrate-linux-to-larger-ssd&quot;&gt;instructions from Wolfgang Ziegler&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To recap:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I ran &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo lshw -class disk -class storage -short&lt;/code&gt; to verify that the old 250gb drive was &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sda&lt;/code&gt; and the new 1tb drive was &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sdb&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;I became root with &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo su - root&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;I ran &lt;code class=&quot;highlighter-rouge&quot;&gt;pv &amp;lt; /dev/sda &amp;gt; /dev/sdb&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;and wait… and wait… at least there was a progress bar&lt;/li&gt;
  &lt;li&gt;I ran &lt;code class=&quot;highlighter-rouge&quot;&gt;gdisk&lt;/code&gt;, choosing &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sdb&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;w&lt;/code&gt;rite, &lt;code class=&quot;highlighter-rouge&quot;&gt;Y&lt;/code&gt;es, and &lt;code class=&quot;highlighter-rouge&quot;&gt;Y&lt;/code&gt;es&lt;/li&gt;
  &lt;li&gt;At this point there was a little divergence from the article. I tried removing the old drive and booting on the new one. It did boot, but the &lt;code class=&quot;highlighter-rouge&quot;&gt;/&lt;/code&gt; filesystem was read-only.&lt;/li&gt;
  &lt;li&gt;After trying a few things (random commands, replugging, rebooting), something eventually clicked. I don’t honestly know what did the trick.&lt;/li&gt;
  &lt;li&gt;Now, I was rebooted as myself with the 1tb now reporting as &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sda&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;I ran &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo gparted&lt;/code&gt; and resized the used partition to take up the remainder of the space.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And everything seemed to be working…&lt;/p&gt;

&lt;h2 id=&quot;no-boot-device&quot;&gt;No boot device&lt;/h2&gt;

&lt;p&gt;Hours later, I got a blue screen on boot:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Default Boot Device Missing or Boot Failed
Insert Recovery Media and Hit any key
Then Select 'Boot Manager' to choose a new Boot Device or to Boot Recovery Media
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This kind of reminded me of the &lt;a href=&quot;/blog/2021-09-11-arch.work/&quot;&gt;problem I had&lt;/a&gt;
switching back and forth between Ubuntu and Arch Linux.&lt;/p&gt;

&lt;p&gt;I tried various BIOS settings, rebooting it, various keyboard keys…&lt;/p&gt;

&lt;p&gt;What finally got it working again was:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Unplug the 1tb drive&lt;/li&gt;
  &lt;li&gt;Power up to this disappointing blue screen&lt;/li&gt;
  &lt;li&gt;Plug in the 1tb drive&lt;/li&gt;
  &lt;li&gt;Hit OK&lt;/li&gt;
  &lt;li&gt;When the new screen came up, they cursors didn’t work; just hit Enter&lt;/li&gt;
  &lt;li&gt;Once it boots, just run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo update-grub&lt;/code&gt; (not sure if it was really necessary).&lt;/li&gt;
  &lt;li&gt;Reboot once more to make sure everything is OK&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="framework" /><summary type="html"></summary></entry><entry><title type="html">error[E0716]: temporary value dropped while borrowed</title><link href="https://www.malachid.com/blog/2022-11-18-e0716/" rel="alternate" type="text/html" title="error[E0716]: temporary value dropped while borrowed" /><published>2022-11-18T21:37:28-08:00</published><updated>2022-11-18T21:37:28-08:00</updated><id>https://www.malachid.com/blog/e0716</id><content type="html" xml:base="https://www.malachid.com/blog/2022-11-18-e0716/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#situation&quot; id=&quot;markdown-toc-situation&quot;&gt;Situation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#recreating-the-issue&quot; id=&quot;markdown-toc-recreating-the-issue&quot;&gt;Recreating the Issue&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#loading-some-fake-data&quot; id=&quot;markdown-toc-loading-some-fake-data&quot;&gt;Loading some Fake Data&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#initial-main-function&quot; id=&quot;markdown-toc-initial-main-function&quot;&gt;Initial &lt;code class=&quot;highlighter-rouge&quot;&gt;main&lt;/code&gt; Function&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#initial-cargo-build&quot; id=&quot;markdown-toc-initial-cargo-build&quot;&gt;Initial &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo&lt;/code&gt; build&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#trying-the-suggested-let-binding&quot; id=&quot;markdown-toc-trying-the-suggested-let-binding&quot;&gt;Trying the suggested &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; binding&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#fixing-the-issue&quot; id=&quot;markdown-toc-fixing-the-issue&quot;&gt;Fixing the Issue&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;situation&quot;&gt;Situation&lt;/h2&gt;

&lt;p&gt;You get a warning (IDE or Cargo) that tells you to consider using a &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;
to fix your error… then you notice that the line in question is already
using a &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;.  What’s going on?&lt;/p&gt;

&lt;h2 id=&quot;recreating-the-issue&quot;&gt;Recreating the Issue&lt;/h2&gt;

&lt;p&gt;First, let’s setup a simple situation that recreates the issue.&lt;/p&gt;

&lt;h3 id=&quot;loading-some-fake-data&quot;&gt;Loading some Fake Data&lt;/h3&gt;

&lt;p&gt;First, we’ll load some fake data.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/e0716/fake-data.png&quot; alt=&quot;fake-data.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The contents of this function don’t matter so much; but make the sample easier to illustrate.&lt;/p&gt;

&lt;h3 id=&quot;initial-main-function&quot;&gt;Initial &lt;code class=&quot;highlighter-rouge&quot;&gt;main&lt;/code&gt; Function&lt;/h3&gt;

&lt;p&gt;So we write a main function to grab that data, unwrap it and just print out the first key/value pairs.&lt;/p&gt;

&lt;p&gt;Note that we are using the &lt;code class=&quot;highlighter-rouge&quot;&gt;nightly&lt;/code&gt; toolchain to enable the &lt;code class=&quot;highlighter-rouge&quot;&gt;.first_key_value()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Here, we see our first confusing suggestion.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/e0716/ide-1.png&quot; alt=&quot;ide-1.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s telling us to consider using a &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; on the line that is already using a &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;initial-cargo-build&quot;&gt;Initial &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo&lt;/code&gt; build&lt;/h3&gt;

&lt;p&gt;What does cargo tell us?  Maybe it’s better?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/e0716/cargo-1.png&quot; alt=&quot;cargo-1.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Cargo is a bit more descriptive about why it is a problem.  It seems the value is dropped
at the end of the &lt;code class=&quot;highlighter-rouge&quot;&gt;unwrap&lt;/code&gt; call.  Further down though, we can see a confusing suggestion
about the &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;.  Well, let’s just try it.&lt;/p&gt;

&lt;h3 id=&quot;trying-the-suggested-let-binding&quot;&gt;Trying the suggested &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; binding&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/e0716/ide-2.png&quot; alt=&quot;ide-2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As expected, delegating it to another variable does not actually impact the error. I am not
sure why cargo and the IDE are suggesting it.&lt;/p&gt;

&lt;h2 id=&quot;fixing-the-issue&quot;&gt;Fixing the Issue&lt;/h2&gt;

&lt;p&gt;If the cargo suggestion does not work, how do we fix it?&lt;/p&gt;

&lt;p&gt;If we think about the fact that both cargo and the IDE both suggested introducing a &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;
statement, we might see that it is still possible.&lt;/p&gt;

&lt;p&gt;In this example, we make the function call on one line, then add an &lt;code class=&quot;highlighter-rouge&quot;&gt;if let&lt;/code&gt; on the next line.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/e0716/ide-3.png&quot; alt=&quot;ide-3.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By replacing the &lt;code class=&quot;highlighter-rouge&quot;&gt;expect&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;if let&lt;/code&gt;, the error goes away.&lt;/p&gt;

&lt;p&gt;The app will now run. Sometimes it will print the first key/value pair and sometimes,
because of our chaos, it will say that it failed to load any data.&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="rust" /><summary type="html"></summary></entry><entry><title type="html">frame.work: The Promise of an Upgrade</title><link href="https://www.malachid.com/blog/2022-08-05-framework-upgrade/" rel="alternate" type="text/html" title="frame.work: The Promise of an Upgrade" /><published>2022-08-05T21:07:02-07:00</published><updated>2022-08-05T21:07:02-07:00</updated><id>https://www.malachid.com/blog/framework-upgrade</id><content type="html" xml:base="https://www.malachid.com/blog/2022-08-05-framework-upgrade/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#timeline&quot; id=&quot;markdown-toc-timeline&quot;&gt;Timeline&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#upgrading-the-mainboard&quot; id=&quot;markdown-toc-upgrading-the-mainboard&quot;&gt;Upgrading the Mainboard&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#upgrading-the-cnc-top-cover&quot; id=&quot;markdown-toc-upgrading-the-cnc-top-cover&quot;&gt;Upgrading the CNC Top Cover&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#end-result&quot; id=&quot;markdown-toc-end-result&quot;&gt;End Result&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;I previously discussed in &lt;a href=&quot;/blog/2021-08-16-framework/&quot;&gt;frame.work: First Impressions&lt;/a&gt;
my new laptop and my motivations for using it.&lt;/p&gt;

&lt;p&gt;One of the key promises of this laptop is that it is user serviceable and upgradable.&lt;/p&gt;

&lt;p&gt;You can see the available components &lt;a href=&quot;https://frame.work/marketplace&quot;&gt;here&lt;/a&gt;, as well as
their &lt;a href=&quot;https://guides.frame.work/c/Framework_Laptop&quot;&gt;Replacement Guides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m not generally an Intel user, but they do not have an AMD option yet. As such, when
presented with the initial set of CPU options I was not already familiar with the various
product lines.  I chose to go with the &lt;code class=&quot;highlighter-rouge&quot;&gt;Intel® Core™ i5-1135G7&lt;/code&gt; originally, partially for the
64GB ram support but also because I set a budget and tried to stick with it.&lt;/p&gt;

&lt;p&gt;So when it came time a year later to try to upgrade the system, I decided to stay with the
&lt;code class=&quot;highlighter-rouge&quot;&gt;i5&lt;/code&gt; product line. Specifically, I upgraded to the &lt;code class=&quot;highlighter-rouge&quot;&gt;i5-1240P&lt;/code&gt;.  Slightly slower but many
more cores - so should be good.&lt;/p&gt;

&lt;p&gt;I also chose to replace the top cover.  That one was a little more tricky to justify. They
said the new one was CNC machined and more robust, so… why not?&lt;/p&gt;

&lt;p&gt;Upgrading both costs &lt;a href=&quot;https://frame.work/products/12-gen-intel-upgrade-kit?v=FRUPGRDKIT01&quot;&gt;$538&lt;/a&gt;
plus $18 shipping.&lt;/p&gt;

&lt;h2 id=&quot;timeline&quot;&gt;Timeline&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Pre-Order available on 19 May 2022&lt;/li&gt;
  &lt;li&gt;Waitlist item in stock 21 July 2022&lt;/li&gt;
  &lt;li&gt;Placed the order on 21 July 2022&lt;/li&gt;
  &lt;li&gt;Order shipped 2 Aug 2022&lt;/li&gt;
  &lt;li&gt;Delivered 4 Aug 2022&lt;/li&gt;
  &lt;li&gt;Assembled/Upgraded 4 Aug 2022&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;upgrading-the-mainboard&quot;&gt;Upgrading the Mainboard&lt;/h2&gt;

&lt;p&gt;The first surprise was that the QR code on the box was not valid. I’ll need to reach out
to frame.work about that.  I was, however, able to find the &lt;a href=&quot;https://guides.frame.work/Guide/Mainboard+Replacement+Guide/79?lang=en&quot;&gt;Mainboard replacement guide&lt;/a&gt; in
the above link.&lt;/p&gt;

&lt;p&gt;I was going to grab some photos of the process, but it was almost exactly the same as the
initial build.&lt;/p&gt;

&lt;p&gt;A few callouts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;On Step 11, Disconnect the Webcam: the black pull tab was under the memory. I just used the spudger to pull it up&lt;/li&gt;
  &lt;li&gt;Step 16, Remove the Mainboard: They said there should be no resistance unless a previous step was missed. When I did it, I temporarily noticed some resistance on the bottom middle even though that screw was already removed.&lt;/li&gt;
  &lt;li&gt;Step 17, Installing the (new) Mainboard: the hardest part there is just keeping all the wires out of the way&lt;/li&gt;
  &lt;li&gt;Step 20, Connecting the Audio Board: that one was a little difficult because there was no way to get leverage to angle the cable correctly. Maybe if it was a little longer, that would be easier.&lt;/li&gt;
  &lt;li&gt;Step 21-24: If you are also installing the CNC Top, you will be &lt;em&gt;undoing&lt;/em&gt; these steps in just a minute&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall it went pretty smoothly.&lt;/p&gt;

&lt;p&gt;At this stage, I started it up to make sure it was working. If I knew what the steps were
going to be for the CNC top, I might have done it slightly differently.&lt;/p&gt;

&lt;h2 id=&quot;upgrading-the-cnc-top-cover&quot;&gt;Upgrading the CNC Top Cover&lt;/h2&gt;

&lt;p&gt;The CNC Top Cover had a QR code on the part - but that QR code didn’t work either.&lt;/p&gt;

&lt;p&gt;Again, turning to the &lt;a href=&quot;https://guides.frame.work/Guide/Top+Cover+Replacement+Guide/118?lang=en&quot;&gt;Top Cover section of the Replacement Guides&lt;/a&gt; above, we are able to move forward.&lt;/p&gt;

&lt;p&gt;A few callouts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Step 5: We’re removing the WiFi module completely. You didn’t spend too much time on it above did you?&lt;/li&gt;
  &lt;li&gt;Similarly, Step 7 disconnects the Display and Webcam cables. I was surprised that we were removing “grounding tape” and not replacing it with a new piece.&lt;/li&gt;
  &lt;li&gt;Step 10, Removing the Webcam… magnetic washers… I had never considered such a thing. Crazy.&lt;/li&gt;
  &lt;li&gt;Step 11, Unscrewing the Top Cover… You think you’ll use these screws again - but in reality you’ll just screw them back into the old top so you don’t loose them. You won’t be using them.&lt;/li&gt;
  &lt;li&gt;Step 12, Installing the Top Cover… This section is not quite complete or accurate. Instead of screwing in the 3 screws on each side, you need to &lt;em&gt;remove&lt;/em&gt; the 4 screws from it first, then reattach using those screws.&lt;/li&gt;
  &lt;li&gt;Step 15, Rerouting the cables… seems easy enough but this is the one step that will bite you the most. If you aren’t careful with this step, the keyboard will not close in Step 20 and you will have to keep readjusting the cable routing&lt;/li&gt;
  &lt;li&gt;Step 16-17, we are redoing the WiFi like we did during the initial build with new wires&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;end-result&quot;&gt;End Result&lt;/h2&gt;

&lt;p&gt;Due to a couple steps like WiFi and cable rerouting, I think I spent about 3 hours doing both upgrades.
Significantly more time than the guides say it will take (they suggest 30-50 minutes).&lt;/p&gt;

&lt;p&gt;The machine feels much snappier.  With the new top cover it looks much cleaner.&lt;/p&gt;

&lt;p&gt;First boot takes a little longer, but there were no problems booting (into Linux).&lt;/p&gt;

&lt;p&gt;I did go into the BIOS and check the settings there.  The only one I really needed to change was
&lt;code class=&quot;highlighter-rouge&quot;&gt;Boot | New Boot Device Priority&lt;/code&gt; from &lt;code class=&quot;highlighter-rouge&quot;&gt;Auto&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;Last&lt;/code&gt;.  This is because I am hot swapping
OS drives on the modules, with the internal nvme being used as a shared non-bootable work / git drive.&lt;/p&gt;

&lt;p&gt;I did also change the Power LED from &lt;code class=&quot;highlighter-rouge&quot;&gt;High&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;Medium&lt;/code&gt; brightness.&lt;/p&gt;

&lt;p&gt;Also, the keyboard backlight wasn’t on anymore.  Fn+Space fixed that.  I kept trying to use
the Fn+F8, but that was the wrong key.&lt;/p&gt;

&lt;p&gt;This is the first time I have been able to make &lt;em&gt;significant&lt;/em&gt; upgrades to a laptop and I think
it really shows how powerful this can be.  Ignoring all other stats - I just upgraded a 
laptop from 4-core/8-thread to 12-core/16-thread.&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="framework" /><summary type="html"></summary></entry><entry><title type="html">Installing Arch on Frame.work</title><link href="https://www.malachid.com/blog/2021-09-11-arch.work/" rel="alternate" type="text/html" title="Installing Arch on Frame.work" /><published>2021-09-11T11:20:52-07:00</published><updated>2021-09-11T11:20:52-07:00</updated><id>https://www.malachid.com/blog/arch.work</id><content type="html" xml:base="https://www.malachid.com/blog/2021-09-11-arch.work/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#hardware-setup&quot; id=&quot;markdown-toc-hardware-setup&quot;&gt;Hardware Setup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#installation&quot; id=&quot;markdown-toc-installation&quot;&gt;Installation&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#verify-efi&quot; id=&quot;markdown-toc-verify-efi&quot;&gt;Verify EFI&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#setup-wifi&quot; id=&quot;markdown-toc-setup-wifi&quot;&gt;Setup Wifi&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#setup-ntp&quot; id=&quot;markdown-toc-setup-ntp&quot;&gt;Setup NTP&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#find-the-drive&quot; id=&quot;markdown-toc-find-the-drive&quot;&gt;Find the Drive&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#partition-the-drive&quot; id=&quot;markdown-toc-partition-the-drive&quot;&gt;Partition the Drive&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#format-the-drive&quot; id=&quot;markdown-toc-format-the-drive&quot;&gt;Format the Drive&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#mount-the-drive&quot; id=&quot;markdown-toc-mount-the-drive&quot;&gt;Mount the Drive&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#initializing-the-system&quot; id=&quot;markdown-toc-initializing-the-system&quot;&gt;Initializing the System&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#chroot&quot; id=&quot;markdown-toc-chroot&quot;&gt;Chroot&lt;/a&gt;        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#set-your-locale&quot; id=&quot;markdown-toc-set-your-locale&quot;&gt;Set your locale&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#setup-your-hostname&quot; id=&quot;markdown-toc-setup-your-hostname&quot;&gt;Setup your hostname&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#init-ramdisk&quot; id=&quot;markdown-toc-init-ramdisk&quot;&gt;Init ramdisk&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#set-a-root-password&quot; id=&quot;markdown-toc-set-a-root-password&quot;&gt;Set a root password&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#install-grub&quot; id=&quot;markdown-toc-install-grub&quot;&gt;Install grub&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#microcode&quot; id=&quot;markdown-toc-microcode&quot;&gt;Microcode&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#exiting-chroot&quot; id=&quot;markdown-toc-exiting-chroot&quot;&gt;Exiting chroot&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#troubleshooting-and-recovery&quot; id=&quot;markdown-toc-troubleshooting-and-recovery&quot;&gt;Troubleshooting and Recovery&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#next-up&quot; id=&quot;markdown-toc-next-up&quot;&gt;Next up&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#switching-between-ubuntu-and-arch&quot; id=&quot;markdown-toc-switching-between-ubuntu-and-arch&quot;&gt;Switching between Ubuntu and Arch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;As I mentioned in &lt;a href=&quot;/blog/2021-08-16-framework/&quot;&gt;frame.work: First Impressions&lt;/a&gt;, my intention with
the frame.work laptop was to multiboot - not with multiple OSes on a single drive, but with swappable drives.&lt;/p&gt;

&lt;p&gt;To that end, the internal NVME is being used to store my work directory (git repos, etc) - which TBH, is where the speed needs
to be since that is where all the builds are.&lt;/p&gt;

&lt;p&gt;The individual OS drives are on swappable (in this case) 250gb modules.&lt;/p&gt;

&lt;p&gt;I am also using Ventoy on a USB-A stick for OS installation.&lt;/p&gt;

&lt;p&gt;I had installed Ubuntu 21.04 on the first 250gb module.  I’ve been using that for about a month, and it has been working
out really well.&lt;/p&gt;

&lt;p&gt;Now, for the second module.  I have decided to install Arch.  For this I was using &lt;code class=&quot;highlighter-rouge&quot;&gt;archlinux-2021.08.01-x86_64.iso&lt;/code&gt;. I know
it’s a month out of date, but I forgot to download a newer iso.&lt;/p&gt;

&lt;p&gt;Like last time, I would normally use ZFS for my filesystem; however, for a single external USB drive I decided not to do that.&lt;/p&gt;

&lt;h2 id=&quot;hardware-setup&quot;&gt;Hardware Setup&lt;/h2&gt;

&lt;p&gt;This was the easy part.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Unplug the power. Is that &lt;em&gt;necessary&lt;/em&gt;?  No clue, but it seemed like a good idea.&lt;/li&gt;
  &lt;li&gt;Remove the 250gb Ubuntu module.&lt;/li&gt;
  &lt;li&gt;Insert a new blank 250gb module.&lt;/li&gt;
  &lt;li&gt;Insert the Ventoy USB.&lt;/li&gt;
  &lt;li&gt;Re-attach power. This step wasn’t strickly necessary as I was at 100% power but I prefer to do OS installs while plugged in.&lt;/li&gt;
  &lt;li&gt;Turn on the power.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During the initial bootup, the Ventoy USB was detected.  I selected the archlinux iso and away we went.&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;In theory, I was following &lt;a href=&quot;https://wiki.archlinux.org/title/Installation_guide&quot;&gt;the official installation guide&lt;/a&gt;, however I did
not have a secondary computer in front of me at the time.  As such, I just took a few notes before doing the above steps and took a go of it.&lt;/p&gt;

&lt;h3 id=&quot;verify-efi&quot;&gt;Verify EFI&lt;/h3&gt;

&lt;p&gt;First, I wanted to make sure I was booted into EFI mode.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; /sys/firmware/efi/efivars
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I saw a directory of files, so… we’re good.&lt;/p&gt;

&lt;h3 id=&quot;setup-wifi&quot;&gt;Setup Wifi&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ip &lt;span class=&quot;nb&quot;&gt;link&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This reported that my wifi device was &lt;code class=&quot;highlighter-rouge&quot;&gt;wlan0&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rfkill list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This reported that nothing was soft or hard blocked.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;iwctl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This puts you into the &lt;code class=&quot;highlighter-rouge&quot;&gt;iwd&lt;/code&gt; interactive configuration.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;device list&lt;/code&gt; returned &lt;code class=&quot;highlighter-rouge&quot;&gt;wlan0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;station wlan0 scan&lt;/code&gt; doesn’t &lt;em&gt;appear&lt;/em&gt; to do anything but…&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;station wlan0 get-networks&lt;/code&gt; then lists the available wifi networks&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;station wlan0 connect MyWifiNetworkName&lt;/code&gt; (obviously not my real wifi name) then asks you for the Wifi password&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;device wlan0 show&lt;/code&gt; confirms everything looks ok&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;station wlan0 show&lt;/code&gt; confirms you are connected. If it says connecting, wait a moment.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;exit&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Confirm you have wifi by running &lt;code class=&quot;highlighter-rouge&quot;&gt;ping archlinux.org&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;setup-ntp&quot;&gt;Setup NTP&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;timedatectl set-ntp &lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;timedatectl status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While you are here, it’s a good time to figure out the correct terminology for your timezone. 
It might seem obvious, but You aren’t going to be selecting “Los Angeles”, for example, like you would in Ubuntu.
You can run &lt;code class=&quot;highlighter-rouge&quot;&gt;timedatactl list-timezones&lt;/code&gt; to find the right one.  For me it was “US/Pacific”.&lt;/p&gt;

&lt;h3 id=&quot;find-the-drive&quot;&gt;Find the Drive&lt;/h3&gt;

&lt;p&gt;Running &lt;code class=&quot;highlighter-rouge&quot;&gt;lsblk&lt;/code&gt; will show you a list of drives.  In my case, it showed a 64gb, 250gb and a 500gb.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The 64gb was the Ventoy USB&lt;/li&gt;
  &lt;li&gt;THe 500gb was the NVME&lt;/li&gt;
  &lt;li&gt;The 250gb was the new drive and already contained a FAT partition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my case, the 250gb drive was &lt;code class=&quot;highlighter-rouge&quot;&gt;sda&lt;/code&gt; (with &lt;code class=&quot;highlighter-rouge&quot;&gt;sda1&lt;/code&gt; already defined).&lt;/p&gt;

&lt;h3 id=&quot;partition-the-drive&quot;&gt;Partition the Drive&lt;/h3&gt;

&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;fdisk /dev/sda&lt;/code&gt;. (in my case).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;m&lt;/code&gt; if you need help&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt; to print the current partitions and confirm you are on the correct partitions&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;d&lt;/code&gt; to delete the only partition currently on the drive&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; to create a new partition and specify the size of at least 260mb. I did &lt;code class=&quot;highlighter-rouge&quot;&gt;+512M&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;t&lt;/code&gt; to change the partition type to &lt;code class=&quot;highlighter-rouge&quot;&gt;EFI&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; to create another partition. Size should be roughly (memory + 2GB). I have 64gb so I did &lt;code class=&quot;highlighter-rouge&quot;&gt;+70GB&lt;/code&gt;. I has debated not doing a swap partition, but if I wanted to hibernate down the road, I didn’t want to have to re-format my drive.&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;t&lt;/code&gt; to change the partition type to &lt;code class=&quot;highlighter-rouge&quot;&gt;Linux swap&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; to create another partition. Let it take the remaining space.&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;t&lt;/code&gt; to change the partition type.  The installation guide said to make it &lt;code class=&quot;highlighter-rouge&quot;&gt;Linux root&lt;/code&gt; however the labels were all cut off on the frame.work display due to the screen size. I ended up using the &lt;code class=&quot;highlighter-rouge&quot;&gt;linux&lt;/code&gt; alias from the bottom of the screen, though I am pretty sure that was not the correct one.  Seems to have worked though.&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;v&lt;/code&gt; to verify that everything is ok; and &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt; if you want to review it.&lt;/li&gt;
  &lt;li&gt;use &lt;code class=&quot;highlighter-rouge&quot;&gt;w&lt;/code&gt; to write the changes to disk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our partitions are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;EFI : /dev/sda1&lt;/li&gt;
  &lt;li&gt;swap : /dev/sda2&lt;/li&gt;
  &lt;li&gt;root : /dev/sda3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;format-the-drive&quot;&gt;Format the Drive&lt;/h3&gt;

&lt;p&gt;First the EFI partition:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkfs.fat &lt;span class=&quot;nt&quot;&gt;-F32&lt;/span&gt; /dev/sda1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then the swap partition:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkswap /dev/sda2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And finally the root partition:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkfs.ext4 /dev/sda3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;mount-the-drive&quot;&gt;Mount the Drive&lt;/h3&gt;

&lt;p&gt;First, we mount the root partition&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mount /dev/sda3 /mnt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then we need to create a place to mount the EFI and mount it.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; /mnt/boot
mount /dev/sda1 /mnt/boot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, enable the swap&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;swapon /dev/sda2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;initializing-the-system&quot;&gt;Initializing the System&lt;/h3&gt;

&lt;p&gt;Review &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/pacman.d/mirrorlist&lt;/code&gt; and make sure it looks reasonable.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pacstrap /mnt base linux linux-firmware nano man-db man-pages texinfo grub efibootmgr intel-ucode iwd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In my case, I forgot &lt;code class=&quot;highlighter-rouge&quot;&gt;iwd&lt;/code&gt; which prevented the new system from being able to connect to the network.  See &lt;a href=&quot;#troubleshooting-and-recovery&quot;&gt;Troubleshooting and Recovery&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Generate the fstab:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;genfstab &lt;span class=&quot;nt&quot;&gt;-U&lt;/span&gt; /mnt &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Review &lt;code class=&quot;highlighter-rouge&quot;&gt;/mnt/etc/fstab&lt;/code&gt; and make sure it looks reasonable.&lt;/p&gt;

&lt;h3 id=&quot;chroot&quot;&gt;Chroot&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;arch-chroot /mnt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;set-your-locale&quot;&gt;Set your locale&lt;/h4&gt;

&lt;p&gt;Based on our earlier &lt;code class=&quot;highlighter-rouge&quot;&gt;timedatectl&lt;/code&gt; query.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-sf&lt;/span&gt; /usr/share/zoneinfo/US/Pacific /etc/location
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Set the hardware clock to UTC&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hwclock &lt;span class=&quot;nt&quot;&gt;--systohc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nano /etc/locale.gen&lt;/code&gt; and uncomment &lt;code class=&quot;highlighter-rouge&quot;&gt;en_US.UTF-8 UTF8&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nano /etc/locale.conf&lt;/code&gt; and add &lt;code class=&quot;highlighter-rouge&quot;&gt;LANG=en_US.UTF-8&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;setup-your-hostname&quot;&gt;Setup your hostname&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nano /etc/hostname&lt;/code&gt; and add a single line that is your new hostname &lt;code class=&quot;highlighter-rouge&quot;&gt;myhostname&lt;/code&gt; or whatever&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then add entries to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;127.0.0.1 localhost
::1       localhost
127.0.1.1 myhostname.localdomain myhostname
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;init-ramdisk&quot;&gt;Init ramdisk&lt;/h4&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkinitcpio &lt;span class=&quot;nt&quot;&gt;-P&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;set-a-root-password&quot;&gt;Set a root password&lt;/h4&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;passwd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;install-grub&quot;&gt;Install grub&lt;/h4&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;grub-install &lt;span class=&quot;nt&quot;&gt;--target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;x86_64-efi &lt;span class=&quot;nt&quot;&gt;--efi-directory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/boot &lt;span class=&quot;nt&quot;&gt;--bootloader-id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;grub &lt;span class=&quot;nt&quot;&gt;--removable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;/boot&lt;/code&gt; is technically &lt;code class=&quot;highlighter-rouge&quot;&gt;/mnt/boot&lt;/code&gt; from earlier. You are inside the chroot.&lt;/p&gt;

&lt;p&gt;The bootloader id of &lt;code class=&quot;highlighter-rouge&quot;&gt;grub&lt;/code&gt; will create (at later steps):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/boot/EFI/grub&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;boot/grub/x86_64-efi/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/boot/grub/grub.cfg&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn’t originally include &lt;code class=&quot;highlighter-rouge&quot;&gt;--removable&lt;/code&gt; but the drive would not show up in the UEFI bootloader after switching OSes.&lt;/p&gt;

&lt;p&gt;Modify &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/default/grub&lt;/code&gt; if needed.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;grub-mkconfig &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;microcode&quot;&gt;Microcode&lt;/h4&gt;

&lt;p&gt;There was a note on the Arch wiki about making some changes to the kernel configuration to support the microcode. As I didn’t have the wiki in front
of me during this process, I’ll probably need to go back and revisit that.&lt;/p&gt;

&lt;h4 id=&quot;exiting-chroot&quot;&gt;Exiting chroot&lt;/h4&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;exit
&lt;/span&gt;umount &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; /mnt
reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this stage, remove install media and login as root.&lt;/p&gt;

&lt;p&gt;You’ll want to continue with &lt;a href=&quot;https://wiki.archlinux.org/title/General_recommendations&quot;&gt;General recommendation&lt;/a&gt;.  I still need to do that myself.&lt;/p&gt;

&lt;h2 id=&quot;troubleshooting-and-recovery&quot;&gt;Troubleshooting and Recovery&lt;/h2&gt;

&lt;p&gt;The first time through, I did not include the &lt;code class=&quot;highlighter-rouge&quot;&gt;iwd&lt;/code&gt; package.  I could not access dhcp, nmcli, iwctl, anything.&lt;/p&gt;

&lt;p&gt;I also couldn’t install any packages.&lt;/p&gt;

&lt;p&gt;So what do you do?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Reboot onto the live iso. On this step, I had to go into the BIOS as the frame.work didn’t seem to allow me to default to the removable USB or reorder the boot entries – just check or uncheck them. To reorder them, you need to use the &lt;code class=&quot;highlighter-rouge&quot;&gt;+&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;-&lt;/code&gt; buttons while highlighting the item in non-Auto mode. Thanks to &lt;a href=&quot;https://community.frame.work/t/dual-boot/3799/18?u=malachid&quot;&gt;lbkNhubert&lt;/a&gt; for the solution.&lt;/li&gt;
  &lt;li&gt;Run the &lt;a href=&quot;#mount-the-drive&quot;&gt;Mount the Drive&lt;/a&gt; steps&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;arch-chroot /mnt&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;pacman -S iwd&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Run the &lt;a href=&quot;#exiting-chroot&quot;&gt;Exiting chroot&lt;/a&gt; steps&lt;/li&gt;
  &lt;li&gt;If you unchecked the boot entry in the BIOS, make sure to re-enable it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I was back into the system, I was able to run &lt;code class=&quot;highlighter-rouge&quot;&gt;iwctl&lt;/code&gt; using the same &lt;a href=&quot;#setup-wifi&quot;&gt;Setup Wifi&lt;/a&gt; steps I did during the installer process.&lt;/p&gt;

&lt;p&gt;One caveat was that &lt;code class=&quot;highlighter-rouge&quot;&gt;systemd-resolve.service&lt;/code&gt; was not running.&lt;br /&gt;
I needed to uncomment the DNS entry in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/systemd/resolved.conf&lt;/code&gt; and add some values to it. I just copied the fallback.&lt;/p&gt;

&lt;p&gt;Then restart the services:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;systemctl restart systemd-resolved.service&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;systemctl restart iwd.service&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s still not always working on bootup - which I’ll need to look into.  Running those two &lt;code class=&quot;highlighter-rouge&quot;&gt;systemctl&lt;/code&gt; lines after startup does get wifi working though.&lt;/p&gt;

&lt;h2 id=&quot;next-up&quot;&gt;Next up&lt;/h2&gt;

&lt;p&gt;Install, customize, configure.&lt;/p&gt;

&lt;h2 id=&quot;switching-between-ubuntu-and-arch&quot;&gt;Switching between Ubuntu and Arch&lt;/h2&gt;

&lt;p&gt;When I went to swap the Arch drive with the Ubuntu one, the BIOS didn’t see any drives.  I tried rebooting multiple times.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;--removable&lt;/code&gt; on grub-install should help with that, however I am not sure that is a long term solution. Maybe I need to modify the grub configuration.  Also, maybe I need to do a similar fix for Ubuntu.&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="framework" /><summary type="html"></summary></entry><entry><title type="html">frame.work: First Impressions</title><link href="https://www.malachid.com/blog/2021-08-16-framework/" rel="alternate" type="text/html" title="frame.work: First Impressions" /><published>2021-08-16T19:54:51-07:00</published><updated>2021-08-18T18:00:16-07:00</updated><id>https://www.malachid.com/blog/framework</id><content type="html" xml:base="https://www.malachid.com/blog/2021-08-16-framework/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#motivation&quot; id=&quot;markdown-toc-motivation&quot;&gt;Motivation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#ordering-process-and-timeline&quot; id=&quot;markdown-toc-ordering-process-and-timeline&quot;&gt;Ordering Process and Timeline&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#unboxing&quot; id=&quot;markdown-toc-unboxing&quot;&gt;Unboxing&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#build&quot; id=&quot;markdown-toc-build&quot;&gt;Build&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#case-screws&quot; id=&quot;markdown-toc-case-screws&quot;&gt;Case Screws&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#removing-the-keyboard&quot; id=&quot;markdown-toc-removing-the-keyboard&quot;&gt;Removing the Keyboard&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#qr-codes&quot; id=&quot;markdown-toc-qr-codes&quot;&gt;QR Codes&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#memory&quot; id=&quot;markdown-toc-memory&quot;&gt;Memory&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#nvme&quot; id=&quot;markdown-toc-nvme&quot;&gt;NVME&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#wifi&quot; id=&quot;markdown-toc-wifi&quot;&gt;WiFi&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#close-up&quot; id=&quot;markdown-toc-close-up&quot;&gt;Close Up&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#what-about-the-&quot; id=&quot;markdown-toc-what-about-the-&quot;&gt;What about the …&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#seriously-why-those-modules&quot; id=&quot;markdown-toc-seriously-why-those-modules&quot;&gt;Seriously, why those modules?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#first-boot&quot; id=&quot;markdown-toc-first-boot&quot;&gt;First boot&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#secure-boot&quot; id=&quot;markdown-toc-secure-boot&quot;&gt;Secure Boot&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#ubuntu-install&quot; id=&quot;markdown-toc-ubuntu-install&quot;&gt;Ubuntu install&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#neofetch&quot; id=&quot;markdown-toc-neofetch&quot;&gt;neofetch&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#first-week&quot; id=&quot;markdown-toc-first-week&quot;&gt;First week…&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#whats-next&quot; id=&quot;markdown-toc-whats-next&quot;&gt;What’s Next?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#update-18aug2021&quot; id=&quot;markdown-toc-update-18aug2021&quot;&gt;Update 18Aug2021&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;My existing laptop was pretty nice. One of the original Dell Precision m3800 CTO Edition Ubuntu laptops.
It has an nVidia Quadro K1100M, 500gb ssd, 16gb ram and 802.11ac.  It ran on an Intel i7-4712HQ (8) @ 2.3 GHz and has
a 3840x2160 touchscreen.  I bought it in 2015.&lt;/p&gt;

&lt;p&gt;Two years later, the video died.  I contacted Dell.  They said I could take it to BestBuy for
warranty repair (even though I bought it directly from Dell).  BestBuy told me that they didn’t
even know what kind of screws used and could not open it.&lt;/p&gt;

&lt;p&gt;Every once in awhile it will work for a short period of time, then it shuts down for a good week or so.&lt;/p&gt;

&lt;p&gt;As such, I have been avoiding turning it on.  I have been planning on opening it up and trying to repair it
myself (maybe redo some thermal paste or swap out some component)… however, being unsure whether I could
repair it without breaking it… I have been postponing it.&lt;/p&gt;

&lt;p&gt;Along comes &lt;a href=&quot;https://frame.work/&quot;&gt;frame.work&lt;/a&gt;.  Not only do they encourage you to open the laptop and repair
it yourself - but they have a “&lt;a href=&quot;https://frame.work/products/laptop-diy-edition&quot;&gt;DIY edition&lt;/a&gt;” which requires you to do some minimal assembly before even using it.&lt;/p&gt;

&lt;p&gt;Sounds good to me!&lt;/p&gt;

&lt;h2 id=&quot;ordering-process-and-timeline&quot;&gt;Ordering Process and Timeline&lt;/h2&gt;

&lt;p&gt;On 13 May 2021, I pre-ordered as part of Batch 1 for $100 down. While waiting, they were
blogging about the device about once a week.&lt;/p&gt;

&lt;p&gt;We’ll get into the why of the components shortly, but the parts were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CPU: Intel® Core™ i5-1135G7&lt;/li&gt;
  &lt;li&gt;Memory: 64GB (2 x 32GB) DDR4-3200&lt;/li&gt;
  &lt;li&gt;Storage: 500GB - WD_BLACK™ SN850 NVMe™&lt;/li&gt;
  &lt;li&gt;WiFi: Intel® Wi-Fi 6E AX210 No vPro®&lt;/li&gt;
  &lt;li&gt;Bezel: Black&lt;/li&gt;
  &lt;li&gt;Keyboard: US English&lt;/li&gt;
  &lt;li&gt;2 USB-C&lt;/li&gt;
  &lt;li&gt;2 USB-A&lt;/li&gt;
  &lt;li&gt;1 DP&lt;/li&gt;
  &lt;li&gt;1 HDMI&lt;/li&gt;
  &lt;li&gt;1 MicroSD&lt;/li&gt;
  &lt;li&gt;3 Storage – 250GB&lt;/li&gt;
  &lt;li&gt;Framework Screwdriver&lt;/li&gt;
  &lt;li&gt;Power Adapter - US/Canada&lt;/li&gt;
  &lt;li&gt;(no OS - DIY Edition)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On 27 July 2021, they sent me a confirmation message stating that they would
charge the remaining $1500 in the next couple days.&lt;/p&gt;

&lt;p&gt;On 29 July 2021, another email from them saying that they had successfully charged the
remaining balance and that the order would ship soon.&lt;/p&gt;

&lt;p&gt;On 31 July 2021, confirmation that it had shipped and provided a tracking number.&lt;/p&gt;

&lt;p&gt;On 8 August 2021, FedEx delivered the package.&lt;/p&gt;

&lt;h2 id=&quot;unboxing&quot;&gt;Unboxing&lt;/h2&gt;

&lt;p&gt;Inside the main delivered box were 1 laptop box, 1 power supply box and two accessories bags.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework/20210808_122310_boxed.jpg&quot; alt=&quot;Boxed&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The laptop box contains the screwdriver/spudger tool and instruction book underneath the laptop.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework/20210808_122401_laptop_box.jpg&quot; alt=&quot;Laptop Box&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This screwdriver is the &lt;em&gt;only&lt;/em&gt; tool you need to repair your laptop.&lt;/p&gt;

&lt;p&gt;It should be noted that later instructions from the Framework Support team encourage you to
use the soft laptop cover as a surface when you open up the laptop to prevent scratches.&lt;/p&gt;

&lt;p&gt;With all of the DIY Edition components laid out. (Yes, we will get to the why on some of those modules)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework/20210808_122847_unboxed.jpg&quot; alt=&quot;Unboxed&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And with the laptop opened up.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/framework/20210808_124446_opened.jpg&quot; alt=&quot;Opened&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;build&quot;&gt;Build&lt;/h2&gt;

&lt;p&gt;I unfortunately forgot to take any photos while adding components.  I might have to go back
and do that retroactively.  In the meantime, here are some notes from the experience.&lt;/p&gt;

&lt;p&gt;Make sure the power is off and modules are removed before altering the build.&lt;/p&gt;

&lt;p&gt;Before you start, scan the QR code inside the module jack.&lt;/p&gt;

&lt;h3 id=&quot;case-screws&quot;&gt;Case Screws&lt;/h3&gt;

&lt;p&gt;There are 5 captive case screws to loosen (not remove) in order to open the case.&lt;/p&gt;

&lt;p&gt;It should be noted that while looking at the bottom of the case, the one on the bottom left
corner will not lift as freely as the rest.  This is intentional to make it easier to get the
laptop open.&lt;/p&gt;

&lt;h3 id=&quot;removing-the-keyboard&quot;&gt;Removing the Keyboard&lt;/h3&gt;

&lt;p&gt;Once the case screws are removed, the keyboard is held on magnetically.&lt;/p&gt;

&lt;p&gt;Flip the laptop over and open the screen like you were going to use it.&lt;/p&gt;

&lt;p&gt;Use the spudger tool to lift the bottom right corner (which is that case screw we talked about
once you flipped the laptop over). Carefully lift around the edge.  If there is too much
resistance, make sure you loosened the 5 case screws.&lt;/p&gt;

&lt;p&gt;When you lift the keyboard, be careful that it is still attached by a cable.  I have seen
some YouTubers lean the keyboard against the screen (which does seem easier), but the
Framework Support team keeps suggesting flipping it the other direction in their instructions.
See my photo above as an example.&lt;/p&gt;

&lt;p&gt;If you need to remove the keyboard entirely, there is one cable with a finger-pull to 
remove it.  For the initial install you do not need to do that.&lt;/p&gt;

&lt;h3 id=&quot;qr-codes&quot;&gt;QR Codes&lt;/h3&gt;

&lt;p&gt;There are QR Codes everywhere.  The first one can be seen inside the module jack before you
even open the case.  Once inside the case, every part is labeled.&lt;/p&gt;

&lt;p&gt;I think these will become much more useful once the marketplace opens up.  For the initial
build, I only used the QR code accessible from the outside of the case.&lt;/p&gt;

&lt;h3 id=&quot;memory&quot;&gt;Memory&lt;/h3&gt;

&lt;p&gt;The memory slots in and has a retention clip on both ends  You’ll notice that one memory
stick faces up and the other down.  Just make sure the retention clips fasten down.&lt;/p&gt;

&lt;h3 id=&quot;nvme&quot;&gt;NVME&lt;/h3&gt;

&lt;p&gt;The NVME is a standard M.2 2280 socket.  This is one location where the screw is not retained
so be careful not to drop it.&lt;/p&gt;

&lt;h3 id=&quot;wifi&quot;&gt;WiFi&lt;/h3&gt;

&lt;p&gt;This is the one component that is not friendly.&lt;/p&gt;

&lt;p&gt;Remove the retaining clip.&lt;/p&gt;

&lt;p&gt;There are two small antennae that you have to clip on.  Luckily, the board is color coded
to the cables.  Once they are on, they do have a tendency to come off if you aren’t careful.&lt;/p&gt;

&lt;p&gt;You also need to re-route the wiring (see the installation instructions for details), then
put the retaining clip back on.&lt;/p&gt;

&lt;p&gt;Of all the reviews I have watched; and my own experience – this is the one piece that could
use some improvement.&lt;/p&gt;

&lt;h2 id=&quot;close-up&quot;&gt;Close Up&lt;/h2&gt;

&lt;p&gt;Lay the keyboard back on and the magnets should align it.&lt;/p&gt;

&lt;p&gt;Close the screen.&lt;/p&gt;

&lt;p&gt;Turn over and screw in the case screws.&lt;/p&gt;

&lt;p&gt;Pick your modules and insert them!  (make sure to include at least one USB-C for power)&lt;/p&gt;

&lt;h2 id=&quot;what-about-the-&quot;&gt;What about the …&lt;/h2&gt;

&lt;p&gt;The motherboard, fan, power supply, speaker, etc can all be replaced as well.  Originally
the DIY Edition was going to come with them uninstalled; but that changed to reduce the 
shipping costs.  They posted &lt;a href=&quot;https://frame.work/blog/the-evolution-of-the-framework-laptop-diy-edition&quot;&gt;a blog&lt;/a&gt; showing how to remove everything.&lt;/p&gt;

&lt;h2 id=&quot;seriously-why-those-modules&quot;&gt;Seriously, why those modules?&lt;/h2&gt;

&lt;p&gt;So I am sure some of those reading this are wondering why I chose this set of modules:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2 USB-C&lt;/li&gt;
  &lt;li&gt;2 USB-A&lt;/li&gt;
  &lt;li&gt;1 DP&lt;/li&gt;
  &lt;li&gt;1 HDMI&lt;/li&gt;
  &lt;li&gt;1 MicroSD&lt;/li&gt;
  &lt;li&gt;3 Storage – 250GB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Especially since there are only 4 jacks?&lt;/p&gt;

&lt;p&gt;Let’s work through it.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1 USB-C will be needed to power/charge the device&lt;/li&gt;
  &lt;li&gt;1 DP, 1 HDMI, 1 MicroSD will likely rarely be used - but in case I need them, I have them.&lt;/li&gt;
  &lt;li&gt;1 USB-A so I can plug in all the random USB dongles, cables, drives, hardware that I have&lt;/li&gt;
  &lt;li&gt;Why the second USB-A? I thought I &lt;em&gt;might&lt;/em&gt; want mouse/keyboard at some point, or to copy from one USB drive to another…&lt;/li&gt;
  &lt;li&gt;And the other USB-C? Well, most things I have are USB-C, but the other plug is taken up by the power.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at the storage.&lt;/p&gt;

&lt;p&gt;I decided to NOT make the nvme bootable.  Yes, I know the nvme is a lot faster than the USB
drives; but… I wanted to be able to cold-swap OSes without dealing with multiboot grub/etc.&lt;/p&gt;

&lt;p&gt;So, one 250gb is Ubuntu.  Another one will be Arch.  Another might be Windows or Kali or something.&lt;/p&gt;

&lt;h2 id=&quot;first-boot&quot;&gt;First boot&lt;/h2&gt;

&lt;p&gt;To do the first boot, I chose the following modules:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;USB-A (with Ventoy on USB)&lt;/li&gt;
  &lt;li&gt;USB-C (not in use)&lt;/li&gt;
  &lt;li&gt;USB-C (for power)&lt;/li&gt;
  &lt;li&gt;250 gb (for Ubuntu install)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When attempting to boot, there was a message that there was no OS.  Makes sense, but why didn’t
it detekt the OS on the bootable USB?&lt;/p&gt;

&lt;h3 id=&quot;secure-boot&quot;&gt;Secure Boot&lt;/h3&gt;

&lt;p&gt;During boot, tap [F2] repeatedly to get into the BIOS.&lt;/p&gt;

&lt;p&gt;On the Security tab, disable Secure Boot.&lt;/p&gt;

&lt;p&gt;It should be noted that it is likely possible to get it to work with Secure Boot - however,
it wanted me to mark every UEFI install on the Ventoy partition as trusted for execution. I
don’t want to go into the BIOS every time I drop an ISO on there.&lt;/p&gt;

&lt;p&gt;After disabling Secure Boot, Ventoy Started up.&lt;/p&gt;

&lt;h3 id=&quot;ubuntu-install&quot;&gt;Ubuntu install&lt;/h3&gt;

&lt;p&gt;Usually, I prefer ZFS.  I used it on Solaris, FreeBSD and Ubuntu.  I currently use it on
my work laptop and my home desktop.&lt;/p&gt;

&lt;p&gt;However, in this case this only has 4 cores and we are running off of the USB.  I decided
to not use ZFS for this go.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/nvme0n1&lt;/code&gt; showed up as the 500gb nvme. I’ll be saving that until after install.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sda&lt;/code&gt; showed as the 250gb USB Disk 3.2 that we will install to.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sdb&lt;/code&gt; showed as my 62gb Kingston Elite G2 hosting Ventoy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After getting Ubuntu installed on sda, I used the &lt;code class=&quot;highlighter-rouge&quot;&gt;Disks&lt;/code&gt; utility to format and mount the
nvme.  I was originally going to do it manually but was feeling lazy late at night.&lt;/p&gt;

&lt;p&gt;I’ll be using the nvme to host work / git repos.  When I switch between Ubuntu / Arch / etc,
I won’t have to redownload all those repos.  In addition, all the builds will still happen
with the speed of the nvme - even though the OS itself is on the USB.&lt;/p&gt;

&lt;h3 id=&quot;neofetch&quot;&gt;neofetch&lt;/h3&gt;

&lt;div&gt;
&lt;pre&gt;&lt;font color=&quot;#2AA1B3&quot;&gt;&lt;b&gt;└&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#12488B&quot;&gt;&lt;b&gt;─(&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#A2734C&quot;&gt;&lt;b&gt;21:36:08&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#12488B&quot;&gt;&lt;b&gt;)&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#2AA1B3&quot;&gt;&lt;b&gt;──&amp;gt;&lt;/b&gt;&lt;/font&gt; neofetch                                                                                   &lt;font color=&quot;#2AA1B3&quot;&gt;&lt;b&gt;─&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#12488B&quot;&gt;&lt;b&gt;─(&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#A2734C&quot;&gt;&lt;b&gt;Mon,Aug16&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#12488B&quot;&gt;&lt;b&gt;)─&lt;/b&gt;&lt;/font&gt;&lt;font color=&quot;#2AA1B3&quot;&gt;&lt;b&gt;┘&lt;/b&gt;&lt;/font&gt;
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;            .-/+oossssoo+/-.&lt;/b&gt;&lt;/font&gt;               &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;malachi&lt;/b&gt;&lt;/font&gt;@&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;dwemer&lt;/b&gt;&lt;/font&gt; 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;        `:+ssssssssssssssssss+:`&lt;/b&gt;&lt;/font&gt;           -------------- 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;      -+ssssssssssssssssssyyssss+-&lt;/b&gt;&lt;/font&gt;         &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;OS&lt;/b&gt;&lt;/font&gt;: Ubuntu 21.04 x86_64 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;    .ossssssssssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;dMMMNy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;sssso.&lt;/b&gt;&lt;/font&gt;       &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Host&lt;/b&gt;&lt;/font&gt;: Laptop A3 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;   /sssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hdmmNNmmyNMMMMh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssss/&lt;/b&gt;&lt;/font&gt;      &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Kernel&lt;/b&gt;&lt;/font&gt;: 5.11.0-31-generic 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;  +sssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hm&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;yd&lt;/b&gt;&lt;/font&gt;&lt;b&gt;MMMMMMMNddddy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssss+&lt;/b&gt;&lt;/font&gt;     &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Uptime&lt;/b&gt;&lt;/font&gt;: 2 hours, 3 mins 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt; /ssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hNMMM&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;yh&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hyyyyhmNMMMNh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssss/&lt;/b&gt;&lt;/font&gt;    &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Packages&lt;/b&gt;&lt;/font&gt;: 1923 (dpkg), 11 (snap) 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;.ssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;dMMMNh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hNMMMd&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssss.&lt;/b&gt;&lt;/font&gt;   &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Shell&lt;/b&gt;&lt;/font&gt;: zsh 5.8 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;+ssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hhhyNMMNy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;yNMMMy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;sssssss+&lt;/b&gt;&lt;/font&gt;   &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Resolution&lt;/b&gt;&lt;/font&gt;: 2256x1504 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;oss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;yNMMMNyMMh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hmmmh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssso&lt;/b&gt;&lt;/font&gt;   &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;DE&lt;/b&gt;&lt;/font&gt;: GNOME 3.38.4 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;oss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;yNMMMNyMMh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;sssssssssssssshmmmhssssssso&lt;/b&gt;&lt;/font&gt;   &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;WM&lt;/b&gt;&lt;/font&gt;: Mutter 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;+ssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hhhyNMMNy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;yNMMMy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;sssssss+&lt;/b&gt;&lt;/font&gt;   &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;WM Theme&lt;/b&gt;&lt;/font&gt;: Adwaita 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;.ssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;dMMMNh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hNMMMd&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssss.&lt;/b&gt;&lt;/font&gt;   &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Theme&lt;/b&gt;&lt;/font&gt;: Yaru-dark [GTK2/3] 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt; /ssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hNMMM&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;yh&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hyyyyhdNMMMNh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssss/&lt;/b&gt;&lt;/font&gt;    &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Icons&lt;/b&gt;&lt;/font&gt;: Yaru [GTK2/3] 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;  +sssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;dm&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;yd&lt;/b&gt;&lt;/font&gt;&lt;b&gt;MMMMMMMMddddy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssssss+&lt;/b&gt;&lt;/font&gt;     &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Terminal&lt;/b&gt;&lt;/font&gt;: gnome-terminal 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;   /sssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;hdmNNNNmyNMMMMh&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssssss/&lt;/b&gt;&lt;/font&gt;      &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;CPU&lt;/b&gt;&lt;/font&gt;: 11th Gen Intel i5-1135G7 (8) @ 4.200GHz 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;    .ossssssssssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;dMMMNy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;sssso.&lt;/b&gt;&lt;/font&gt;       &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;GPU&lt;/b&gt;&lt;/font&gt;: Intel TigerLake GT2 [Iris Xe Graphics] 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;      -+sssssssssssssssss&lt;/b&gt;&lt;/font&gt;&lt;b&gt;yyy&lt;/b&gt;&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;ssss+-&lt;/b&gt;&lt;/font&gt;         &lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;Memory&lt;/b&gt;&lt;/font&gt;: 5192MiB / 64101MiB 
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;        `:+ssssssssssssssssss+:`&lt;/b&gt;&lt;/font&gt;
&lt;font color=&quot;#C01C28&quot;&gt;&lt;b&gt;            .-/+oossssoo+/-.&lt;/b&gt;&lt;/font&gt;               &lt;span style=&quot;background-color:#171421&quot;&gt;&lt;font color=&quot;#171421&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#C01C28&quot;&gt;&lt;font color=&quot;#C01C28&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#26A269&quot;&gt;&lt;font color=&quot;#26A269&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#A2734C&quot;&gt;&lt;font color=&quot;#A2734C&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#12488B&quot;&gt;&lt;font color=&quot;#12488B&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#A347BA&quot;&gt;&lt;font color=&quot;#A347BA&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#2AA1B3&quot;&gt;&lt;font color=&quot;#2AA1B3&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#D0CFCC&quot;&gt;&lt;font color=&quot;#D0CFCC&quot;&gt;   &lt;/font&gt;&lt;/span&gt;
                                           &lt;span style=&quot;background-color:#5E5C64&quot;&gt;&lt;font color=&quot;#5E5C64&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#F66151&quot;&gt;&lt;font color=&quot;#F66151&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#33DA7A&quot;&gt;&lt;font color=&quot;#33DA7A&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#E9AD0C&quot;&gt;&lt;font color=&quot;#E9AD0C&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#2A7BDE&quot;&gt;&lt;font color=&quot;#2A7BDE&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#C061CB&quot;&gt;&lt;font color=&quot;#C061CB&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#33C7DE&quot;&gt;&lt;font color=&quot;#33C7DE&quot;&gt;   &lt;/font&gt;&lt;/span&gt;&lt;span style=&quot;background-color:#FFFFFF&quot;&gt;&lt;font color=&quot;#FFFFFF&quot;&gt;   &lt;/font&gt;&lt;/span&gt;

&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;first-week&quot;&gt;First week…&lt;/h2&gt;

&lt;p&gt;I’ve been using it for about a week now.  Overall I really like it, and especially like
the idea behind it.&lt;/p&gt;

&lt;p&gt;The screen is much smaller than I am used to, but I was able to cope
with that a bit better by changing Chrome and Firefox to 80% scaling.&lt;/p&gt;

&lt;p&gt;Sometimes the trackpad doesn’t seem to register the clicks. The Framework team is
looking into that.&lt;/p&gt;

&lt;p&gt;I’ve already done my first “repair”.  It was just adding a little double sided tape
(as recommended by Framework) to help ensure the keyboard cable stays in place. Point
is though, I have already opened the case up twice in the first week.&lt;/p&gt;

&lt;p&gt;Performance is pretty good.  I wouldn’t normally choose to buy Intel products if I had
any choice in the matter.  Hopefully they make an AMD mainboard and I can swap that out.
It has a lot less cores and memory than my desktop - but 64gb is pretty respectable for
a laptop.  I have been playing with local kubernetes (via microk8s) and it’s been handling
that fine.&lt;/p&gt;

&lt;p&gt;It runs a bit hotter than I would like. It’s hovering around 40℃  (104℉, though it was getting
up to 122℉ ). I ripped open
my Targus lapdesk and am going to try swapping the tiny fans with some Noctua to see if
that helps a bit.&lt;/p&gt;

&lt;p&gt;The keyboard feels pretty nice. Once I realized that [Fn+Space] would turn on the backlight,
it became a bit nicer experience since I usually am using it in the dark.  The arrow keys
are taking a little effort to get used to, and I miss having a 10-key… but it feels nice.&lt;/p&gt;

&lt;p&gt;The trackpad works pretty well most of the time.  Sometimes the clicks just don’t register.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next?&lt;/h2&gt;

&lt;p&gt;Next up will be installing some additional OSes on the other 250gb drives and finding
a good small case for carrying the modules around so they aren’t loose in the backpack.&lt;/p&gt;

&lt;h2 id=&quot;update-18aug2021&quot;&gt;Update 18Aug2021&lt;/h2&gt;

&lt;p&gt;I swapped out the tiny fans in the Targus laptop as mentioned above with a pair of
Noctua NF-A12x25 5V.  The machine is running much cooler.  It’s running about 27℃  (82℉ ) now.&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="framework" /><summary type="html"></summary></entry><entry><title type="html">Cardano/₳DA: First Thoughts</title><link href="https://www.malachid.com/blog/2021-03-13-cardano-first-thoughts/" rel="alternate" type="text/html" title="Cardano/₳DA: First Thoughts" /><published>2021-03-13T13:50:29-08:00</published><updated>2021-03-13T13:50:29-08:00</updated><id>https://www.malachid.com/blog/cardano-first-thoughts</id><content type="html" xml:base="https://www.malachid.com/blog/2021-03-13-cardano-first-thoughts/">&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#what-are-cardano-and-ada&quot; id=&quot;markdown-toc-what-are-cardano-and-ada&quot;&gt;What are Cardano and ADA?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#yet-another-coin--why-do-we-care&quot; id=&quot;markdown-toc-yet-another-coin--why-do-we-care&quot;&gt;Yet another coin?  Why do we care?&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#proof-of-work-vs-proof-of-stake&quot; id=&quot;markdown-toc-proof-of-work-vs-proof-of-stake&quot;&gt;Proof-of-Work vs Proof-of-Stake&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#maintenance&quot; id=&quot;markdown-toc-maintenance&quot;&gt;Maintenance&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#open-source&quot; id=&quot;markdown-toc-open-source&quot;&gt;Open Source&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#costs-of-getting-started&quot; id=&quot;markdown-toc-costs-of-getting-started&quot;&gt;Costs of Getting Started&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#wallets&quot; id=&quot;markdown-toc-wallets&quot;&gt;Wallets&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#obtaining-ada&quot; id=&quot;markdown-toc-obtaining-ada&quot;&gt;Obtaining ADA&lt;/a&gt;        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#kraken-account&quot; id=&quot;markdown-toc-kraken-account&quot;&gt;Kraken Account&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#usd---ada&quot; id=&quot;markdown-toc-usd---ada&quot;&gt;USD -&amp;gt; ADA&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#btcxbt---ada&quot; id=&quot;markdown-toc-btcxbt---ada&quot;&gt;BTC/XBT -&amp;gt; ADA&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#kraken---daedalus&quot; id=&quot;markdown-toc-kraken---daedalus&quot;&gt;Kraken -&amp;gt; Daedalus&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#staking-your-ada&quot; id=&quot;markdown-toc-staking-your-ada&quot;&gt;Staking your ADA&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#whats-next&quot; id=&quot;markdown-toc-whats-next&quot;&gt;What’s next?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-are-cardano-and-ada&quot;&gt;What are Cardano and ADA?&lt;/h2&gt;

&lt;p&gt;Cardano is a public blockchain project. ADA (₳) is the cryptocurrency that runs on it.&lt;/p&gt;

&lt;p&gt;This is similar to the distinction between Blockchain/Bitcoin and Ether/Ethereum.&lt;/p&gt;

&lt;h2 id=&quot;yet-another-coin--why-do-we-care&quot;&gt;Yet another coin?  Why do we care?&lt;/h2&gt;

&lt;p&gt;That’s a very valid question.  While I have played around with a few coins over the years, I
am in no way an expert on the landscape.  What I can talk about is why I am paying attention
to it.&lt;/p&gt;

&lt;p&gt;When Bitcoin came onto the scene, it had a lot of promise for decentralizing banking and financing.
This was really important at the time because the public was being made aware of some, let’s say &lt;em&gt;issues&lt;/em&gt;, 
in the banking industry.&lt;/p&gt;

&lt;p&gt;In the early days there wasn’t much we could do with it. There were a lot of early try-your-luck games and
get-spammed-with-ads-for-a-taste sites; but not many places that would take it.  That’s obviously changed
now.  You can use them locally to buy food or at places like Performance PCs to buy some components for your rig.&lt;/p&gt;

&lt;p&gt;Unfortunately, the cost of using it has also grown quite a bit.  And the delays.  Trying to mine it from home is
also a very expensive proposition.  It started splitting into different coins like Bitcoin Cash.&lt;/p&gt;

&lt;p&gt;Ethereum came along and offered smart contracts.  While great in concept, it was always very slow. Fees on it were
also very high.  Trying to mine it on low-end hardware (like a laptop) is pretty much a joke.  It also started
splitting into other coins.&lt;/p&gt;

&lt;p&gt;There were other coins as well. Monero offered privacy, at least until the authorities break that.  Namecoin was going
to fix DNS. Insert random ICO from random startup that will disappear in 5 years as well.&lt;/p&gt;

&lt;p&gt;Even with all of that, I still try to keep an eye/ear out for anything that is somewhat different.&lt;/p&gt;

&lt;h3 id=&quot;proof-of-work-vs-proof-of-stake&quot;&gt;Proof-of-Work vs Proof-of-Stake&lt;/h3&gt;

&lt;p&gt;The most obvious difference is that Cardano is based on Proof of Stake.&lt;/p&gt;

&lt;p&gt;What does that really mean for you?&lt;/p&gt;

&lt;p&gt;In a proof-of-work system, you really have three ways to make money:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Sell things/services and receive the coin in payment&lt;/li&gt;
  &lt;li&gt;Mine the coin directly&lt;/li&gt;
  &lt;li&gt;Mine the coin as part of a pool&lt;/li&gt;
  &lt;li&gt;Run a pool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first one is pretty straight forward.&lt;/p&gt;

&lt;p&gt;Mining a coin directly requires that you keep the hardware very new to have much chance of competing.  You also have to
utilize a lot of power and bandwidth.  It is very very hard to do - but if you succeed, the rewards are very high.&lt;/p&gt;

&lt;p&gt;Mining on behalf of some pool means that you are giving your compute power and bandwidth to that pool.  That pool will be
more likely to solve a block that an individual at home, meaning they are more likely to share the reward.  Easier to do,
but much lower rewards – and it still requires your network and electricity.&lt;/p&gt;

&lt;p&gt;Running a pool yourself could garner more rewards than contributing to one; but will likely also have much higher costs
as you need to guarantee uptime, handle larger amounts of bandwidth, etc.&lt;/p&gt;

&lt;p&gt;In a proof-of-stake system, the options are similar but distinctly different:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Sell things/services and receive the coin in payment&lt;/li&gt;
  &lt;li&gt;Delegate your coin to a stake pool&lt;/li&gt;
  &lt;li&gt;Run a stake pool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These seem very similar don’t they?&lt;/p&gt;

&lt;p&gt;The selling one is identical, assuming vendors are willing to take the coin.  Transaction fees may be different, however.&lt;/p&gt;

&lt;p&gt;There is no concept of mining a coin as an individual.&lt;/p&gt;

&lt;p&gt;When you delegate your coin to a stake pool, you are in essence voting for them to get the right to mine/mint the block.
If that pool wins that right, you share in the profits, based on how much coin you voted with.  You don’t lose your coin
in this case (minus the transaction fee discussed below), but it determines how much of a vote you get - and therefore
how much of a reward as well.  VERY IMPORTANT here though – your personal machine does not need to be connected or even
powered on. You cast your vote and walk away.  They are working on your behalf – ie: delegates.&lt;/p&gt;

&lt;p&gt;Running a stake pool is very similar to running a standard pool.  You need to have the machine up and running at all times,
thus incurring some costs.  &lt;em&gt;If&lt;/em&gt; you win any minting rights, you are guaranteed a stipend to help maintain the costs. You
will also share in the proceeds of any rewards.&lt;/p&gt;

&lt;p&gt;There are some mechanisms built in to try to ensure that pools stay decentralized and smaller; but for now this is enough.&lt;/p&gt;

&lt;h3 id=&quot;maintenance&quot;&gt;Maintenance&lt;/h3&gt;

&lt;p&gt;Currently, Cardano has low fees.  At the current exchange rate, it’s about 20 cents per transaction.  These fees go into
a special fund that is used to pay for projects.  The community votes on which projects to fund.&lt;/p&gt;

&lt;p&gt;Since your vote is based on how much ADA you have, I do have some concerns that government or institutional actors could
control what protocol changes are funded by buying a lot of staking power.  I’ll need to look into this more as I have 
not had a chance to vote yet.  The next round of voting takes place in a couple weeks.&lt;/p&gt;

&lt;p&gt;Ignoring my misgivings there for a moment, I really like the idea behind this.  The idea that you, as a developer, can
say “I think we should invest in this change to the system” and people can vote to fund that; and that the money is there
because it came out of the transaction fees.  Sure, that sounds like a tax - I get that.  However, I don’t get that much
say in how my taxes are spent.&lt;/p&gt;

&lt;h3 id=&quot;open-source&quot;&gt;Open Source&lt;/h3&gt;

&lt;p&gt;As can be expected of any cryptocurrency and blockchain these days, it’s open source.&lt;/p&gt;

&lt;p&gt;I was a bit surprised that it was written in Haskell.  I do know &lt;em&gt;one&lt;/em&gt; developer that uses Haskell; but I guess it’s time
for me to pick up another language.&lt;/p&gt;

&lt;h2 id=&quot;costs-of-getting-started&quot;&gt;Costs of Getting Started&lt;/h2&gt;

&lt;p&gt;Ok, it sounds interesting!  I’d like to dip my toes in… but, how much will it cost me?&lt;/p&gt;

&lt;p&gt;That’s a very good question.  Since I just did that this week, let me give you a rundown of my experience doing just that.&lt;/p&gt;

&lt;h3 id=&quot;wallets&quot;&gt;Wallets&lt;/h3&gt;

&lt;p&gt;Which wallet should you use?  There are two “Official” wallets.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://daedaluswallet.io/&quot;&gt;Daedalus&lt;/a&gt; is a Linux/Windows/Mac desktop app. It is a full node wallet, validating every transaction.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://yoroi-wallet.com/#/&quot;&gt;Yoroi&lt;/a&gt; is a light wallet. They have mobile and browser integration; but it is not full-featured.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While they brag about Daedalus running in Electron, I see that as a negative.  Electron apps tend to have bad performance and be
a potential weak spot when it comes to security.  With the exception of the Stake Pools tab in the app, however, it seems to be
pretty snappy.&lt;/p&gt;

&lt;p&gt;I did install both of the official apps, but Daedalus is the one I used for my testing.&lt;/p&gt;

&lt;p&gt;You can’t currently buy ADA from the wallet, which would definitely drive up adoption.  For that, we’ll have to take a few extra steps.&lt;/p&gt;

&lt;h3 id=&quot;obtaining-ada&quot;&gt;Obtaining ADA&lt;/h3&gt;

&lt;p&gt;First, you’ll have to decide where to get ADA from.  I expected some services, like ShapeShift, to have it listed - but they did not.&lt;/p&gt;

&lt;h4 id=&quot;kraken-account&quot;&gt;Kraken Account&lt;/h4&gt;

&lt;p&gt;I chose to use Kraken to purchase the ADA.  I didn’t already have an account there, so had to jump through some KYC hoops.&lt;/p&gt;

&lt;p&gt;Kraken provides three tiers&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Tier 1 - Can swap crypto, but can not use fiat&lt;/li&gt;
  &lt;li&gt;Tier 2 (requires ID) - Can use fiat&lt;/li&gt;
  &lt;li&gt;Tier 3 (requires 100k+ transactions) - OTC desk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My existing BTC was locked up in an interest-bearing account, so I decided to buy some ADA using USD.  For that, I needed
Tier 2 due to Know Your Customer laws.  After creating my account, I had to upload a picture (front/back) of my ID and also
allow them to take a picture of my face using the webcam.&lt;/p&gt;

&lt;h4 id=&quot;usd---ada&quot;&gt;USD -&amp;gt; ADA&lt;/h4&gt;

&lt;p&gt;Transferring money from my bank was not as straightforward as I would have liked.  Unlike buying crypto from other sites, 
Kraken does not talk to your bank.  They do not support ACH. In fact, they do not even support the Android app being used
from inside the USA; even though they are a San Francisco company.&lt;/p&gt;

&lt;p&gt;They give you instructions to wire the money from your bank.  This is similar to the Western Union idea.  Sending money
from my credit union to the bank Kraken chose took a day and cost me $20.&lt;/p&gt;

&lt;p&gt;Once the money was in the Kraken account, it was pretty straight forward to swap it for ADA.&lt;/p&gt;

&lt;p&gt;However, you can’t withdraw funds (after your first fiat deposit) for 72 hours.&lt;/p&gt;

&lt;p&gt;Because of this, the ADA sits in the Kraken account for 3 days while you wait to withdraw it.  If you look at it over time,
it seems to be on a vesting schedule as the max withdraw is not 0 ADA the entire time.&lt;/p&gt;

&lt;h4 id=&quot;btcxbt---ada&quot;&gt;BTC/XBT -&amp;gt; ADA&lt;/h4&gt;

&lt;p&gt;After realizing it was going to take 3 days to see the ADA, I went ahead and decided to cash out some of my BTC from the interest
account and try a coin swap.&lt;/p&gt;

&lt;p&gt;The hosting exchange said it was going to take 2-3 days and cost me a fee to take it out of the interest bearing account.  From
what I can tell, it took a couple hours and I was not charged a fee.&lt;/p&gt;

&lt;p&gt;Once it was in the normal wallet, then I could transfer that BTC to Kraken, which lists it as XBT.  That had a $5.50 fee.&lt;/p&gt;

&lt;p&gt;Once the 10 confirmations had once again gone through, then I could convert it to ADA for another couple dollars.&lt;/p&gt;

&lt;p&gt;These funds were available for withdraw immediately, though the site gave me errors a few times as it settled.&lt;/p&gt;

&lt;h4 id=&quot;kraken---daedalus&quot;&gt;Kraken -&amp;gt; Daedalus&lt;/h4&gt;

&lt;p&gt;Each time you want to transfer money from Kraken to Daedalus, you use Daedalus to generate a new address to send funds to.&lt;/p&gt;

&lt;p&gt;Kraken charges 0.6 ADA for the transfer.&lt;/p&gt;

&lt;p&gt;Once that process is initiated, it goes through much quicker than the BTC confirmations. Maybe a couple minutes.&lt;/p&gt;

&lt;h3 id=&quot;staking-your-ada&quot;&gt;Staking your ADA&lt;/h3&gt;

&lt;p&gt;There are different places in Daedalus that allow you to start the process of staking your ADA.&lt;/p&gt;

&lt;p&gt;My recommendation is to watch some YouTube videos that explain how staking pools work before you make your first choice.&lt;/p&gt;

&lt;p&gt;In Daedalus, on the Stake Pools page, there is an option to view the pools as a list or a grid.  It defaults to a grid.
If you change it to a list, it is much easier to work with.  You can sort them by whatever criteria you want (most rewards,
lowest margin, whatever).  You can also search for a particular pool if you want to support someone specific.&lt;/p&gt;

&lt;p&gt;When you find the one you want, select the Delegate button.&lt;/p&gt;

&lt;p&gt;This will take you through a couple screens verifying which wallet you want/etc…&lt;/p&gt;

&lt;p&gt;Then you are charged 2 ADA for a Cardano Delegation Certificate.  This happens one time for your wallet.&lt;/p&gt;

&lt;p&gt;You are also charged a transaction fee.  For me it was 0.175137.  At the time of this writing, that was around 20 cents.&lt;/p&gt;

&lt;p&gt;I’ve &lt;a href=&quot;https://forum.cardano.org/t/cost-of-staking/37649/28&quot;&gt;read&lt;/a&gt; that after this, it should just be the transaction fee.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h2&gt;

&lt;p&gt;I’m currently delegated to a pool that starts in about 7 days.  Each Epoch is 5 days.  So in a couple weeks, I should be
able to see whether I got any rewards and report back on that.&lt;/p&gt;

&lt;p&gt;Also, in a few weeks, there should be a round of voting on funding proposals.&lt;/p&gt;

&lt;p&gt;I might also try my hand at writing a contract or working on the codebase itself.&lt;/p&gt;

&lt;p&gt;I’ve also noticed that the Shift button no longer works. Maybe I should make an ADA replacement for that? ;)&lt;/p&gt;</content><author><name>Malachi de &amp;AElig;lfweald</name><email>malachid@gmail.com</email></author><category term="crypto" /><summary type="html"></summary></entry></feed>