Files
derisis13.github.io/_site/feed.xml

820 lines
103 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2025-02-10T01:56:26+01:00</updated><id>http://localhost:4000/feed.xml</id><title type="html">Derisis13s temporary blog</title><subtitle>Just some nerd rambling</subtitle><entry><title type="html">How I got started with open-source FPGA development</title><link href="http://localhost:4000/2025/02/10/open-source-fpga-development.html" rel="alternate" type="text/html" title="How I got started with open-source FPGA development" /><published>2025-02-10T00:00:00+01:00</published><updated>2025-02-10T00:00:00+01:00</updated><id>http://localhost:4000/2025/02/10/open-source-fpga-development</id><content type="html" xml:base="http://localhost:4000/2025/02/10/open-source-fpga-development.html">&lt;p&gt;In the software world, open-source toolchains are taken for granted.
In the FPGA/hardware world, the situation is not as good, but with the right choice of FPGA, it is feasible.
Allow me to tell my tale about how I succeeded in bringing up my Artix devboard with only open-source programs.&lt;/p&gt;
&lt;h1 id=&quot;writing-vhdl-in-neovim&quot;&gt;Writing VHDL in Neovim&lt;/h1&gt;
&lt;p&gt;My go-to text editor is Neovim.
Ive been using it for years (I think I picked it up in 2022), and it stuck with me.
Im not particularly good at it (I only know the basic keybinds), but its already better than anything else Ive tried.
The most important tools for VHDL are the language server: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vhdl-ls&lt;/code&gt; (also known as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rust_hdl&lt;/code&gt;), the Treesitter VHDL grammar, and my snippets.
My config—based on NvChad—can be found in my dotfiles repository.&lt;/p&gt;
&lt;p&gt;For the sake of trying out the toolchains, I made the simplest possible LED blinking example:&lt;/p&gt;
&lt;div class=&quot;language-vhdl 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;c1&quot;&gt;-- Test entity for synthesis&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;library&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ieee&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;n&quot;&gt;ieee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std_logic_1164&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;all&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;n&quot;&gt;ieee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUMERIC_STD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blink&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;led_o&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;std_logic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;std_logic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;areset&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;std_logic&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;architecture&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rtl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blink&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;signal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;downto&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;-- around 1 Hz with 12 MHz oscillator&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;signal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;led_state&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;std_logic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;L_BLINK_PROC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rising_edge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;areset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;1&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;counter&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;k&quot;&gt;others&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;led_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;led_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;led_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;process&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L_BLINK_PROC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;led_o&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;led_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;architecture&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rtl&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;I also made a simple testbench so I could try simulation too:&lt;/p&gt;
&lt;div class=&quot;language-vhdl 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;c1&quot;&gt;-- Testbench for the blink example&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tb_blink&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tb_blink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;library&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ieee&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;n&quot;&gt;ieee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std_logic_1164&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;architecture&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tb&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tb_blink&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;signal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;std_logic&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;signal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;areset_n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;std_logic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;signal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;led&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;std_logic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;areset_n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;L_STIM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;process&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;loop&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;wait&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;wait&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;process&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L_STIM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;L_DUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;work&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blink&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;led_o&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;led&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;areset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;areset&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;architecture&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tb&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;The two files are named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blink.vhd&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tb_blink.vhd&lt;/code&gt;.
For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vhdl-ls&lt;/code&gt;, I also made a descriptor file (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vhdl-ls.toml&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;language-toml 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;[libraries]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;defaultlib.files&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;*.vhd&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;simulation-with-ghdl-and-gtkwave&quot;&gt;Simulation with GHDL and GTKWave&lt;/h1&gt;
&lt;p&gt;Apart from creating my sources, simulating was one of the easiest steps—it just worked.
The only requirements here are GHDL for elaboration and running the simulation, and GTKWave for viewing the output waveform.
The process is well documented in &lt;a href=&quot;https://ghdl.github.io/ghdl/using/Simulation.html&quot;&gt;GHDLs documentation&lt;/a&gt;.
All I had to do was:&lt;/p&gt;
&lt;div class=&quot;language-sh 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; ./workdir
ghdl &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--workdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;./workdir blink.vhd tb_blink.vhd
ghdl &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--workdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;./workdir tb_blink
ghdl &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--workdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;./workdir tb_blink &lt;span class=&quot;nt&quot;&gt;--wave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;wave.ghw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The first GHDL command (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-a&lt;/code&gt;) analyzes the source files into the directory we just created (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./workdir&lt;/code&gt;).
The second GHDL command (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-e&lt;/code&gt;) elaborates the top-level entity, creating the simulation binary.
The third one runs the simulation, writing the output waveform into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wave.ghw&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Do note that for analysis, source files are referenced, but for elaboration and running, entity names have to be specified instead of filenames.
Additionally, elaboration and running can be combined into a single command:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ghdl &lt;span class=&quot;nt&quot;&gt;--elab-run&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--workdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;./workdir tb_blink &lt;span class=&quot;nt&quot;&gt;--wave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;wave.ghw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To view the output, I could open GTKWave graphically and then open the file from the picker, or run it from the CLI like this (this still opens a GUI window):&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gtkwave wave.ghw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;GTKWave is an OK viewer; at least I dont have to re-run the simulation when I want to look at a new signal, unlike with ModelSim.&lt;/p&gt;
&lt;h1 id=&quot;synthesis-with-ghdl-and-yosys&quot;&gt;Synthesis with GHDL and Yosys&lt;/h1&gt;
&lt;p&gt;But GHDL isnt just a simulator.
It can also do—albeit experimental—synthesis and technology mapping by hooking into Yosys.
This is so much in development that not many packages are provided—I was lucky that someone had already made a &lt;a href=&quot;https://copr.fedorainfracloud.org/coprs/rezso/HDL/&quot;&gt;Copr repo&lt;/a&gt; for it, so I didnt have to compile it on my Fedora machine.
I also saw an AUR package for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghdl-yosys-plugin&lt;/code&gt;, so following along on Arch is probably easy too.
I do not know anything about Debian/Ubuntu; there may be a PPA, but if you have to build from source, check this page: &lt;a href=&quot;https://github.com/BrunoLevy/learn-fpga/blob/master/FemtoRV/TUTORIALS/toolchain_arty.md&quot;&gt;https://github.com/BrunoLevy/learn-fpga/blob/master/FemtoRV/TUTORIALS/toolchain_arty.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To keep the clutter away from source files, I made a build directory:&lt;/p&gt;
&lt;div class=&quot;language-sh 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; ./build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To use the GHDL Yosys plugin, I launched Yosys like this:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yosys &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; ghdl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Unless you specify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-m ghdl&lt;/code&gt;, its plugin will be missing when you run Yosys.
In its console, I first issued &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghdl blink.vhd -e blink&lt;/code&gt; to elaborate my source(s), with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blink&lt;/code&gt; as the top-level entity.
Then, I ran &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;synth_xilinx -json ./build/blink.json&lt;/code&gt; to synthesize a netlist into a JSON file, using technology mapping to the Xilinx 7 family.&lt;/p&gt;
&lt;p&gt;Alternatively, a single script for the same commands can be written like:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yosys &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; ghdl &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ghdl blink.vhd -e blink; synth_xilinx -json ./build/blink.json&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;One downside is that VHDL 2008 is not—or not completely—supported.
To stay safe, I omitted the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std=08&lt;/code&gt; flag everywhere.&lt;/p&gt;
&lt;h1 id=&quot;place--route-with-nextpnr&quot;&gt;Place &amp;amp; route with NextPNR&lt;/h1&gt;
&lt;p&gt;Once I had a netlist, I proceeded to use NextPNR to place and route it to actual components in the FPGA.
My device is an Artix 7 (XC7A35T CPG236-1) as part of a Digilent CMOD A7 devboard.
I first made the mistake of using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nextpnr-xilinx&lt;/code&gt; fork, which is not maintained regularly and refused to work for me.
A bit of information that was unnecessarily hard to find is that the himbaechel backend of NextPNR (which is built into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nextpnr&lt;/code&gt; package provided by the Copr repo) supports Xilinx 7 FPGAs—including my Artix 7.&lt;/p&gt;
&lt;p&gt;An &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xdc&lt;/code&gt; file is required to map top-level inputs and outputs to physical pins.
I derived this from the &lt;a href=&quot;https://github.com/Digilent/digilent-xdc/blob/master/Cmod-A7-Master.xdc&quot;&gt;CMOD A7s xdc file&lt;/a&gt; provided by Digilent:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xdc&quot;&gt;set_property LOC L17 [get_ports {clk}]
set_property IOSTANDARD LVCMOS33 [get_ports {clk}]
create_clock -add -name sys_clk_pin -period 83.33 -waveform {0 41.66} [get_ports {clk}]
set_property LOC A17 [get_ports {led_o}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_o}]
set_property LOC A18 [get_ports {areset}]
set_property IOSTANDARD LVCMOS33 [get_ports {areset}]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I spent an embarrassing amount of time debugging an error caused by comments (and semicolons) at the end of the xdc files lines.
These completely break NextPNRs xdc parser, so they had to go.&lt;/p&gt;
&lt;p&gt;I also used the this file to specify my timing constraints (the 12 MHz clock of the CMOD A7) but due to limitations of NextPNR isnt used for static timing analysis (STA).
To check if my design can operate at the required frequency, I had to specify an additional argument.
NextPNR doesnt know the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-add&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-name&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-waveform&lt;/code&gt; arguments (I guess they are used by Vivado for simulation), but only shows a warning if they are left in.
My final place and route command thus looked like this:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nextpnr-himbaechel &lt;span class=&quot;nt&quot;&gt;--device&lt;/span&gt; xc7a35tcpg236-1 &lt;span class=&quot;nt&quot;&gt;--json&lt;/span&gt; ./build/blink.json &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;xdc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Cmod-A7-Master.xdc&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--write&lt;/span&gt; ./build/blink_routed.json &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fasm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;./build/blink.fasm &lt;span class=&quot;nt&quot;&gt;--router&lt;/span&gt; router2 &lt;span class=&quot;nt&quot;&gt;--freq&lt;/span&gt; 12
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--router&lt;/code&gt; argument had little effect on my design, but it was in the NextPNR GitHUB repos example code so I left it there assuming it does no harm.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--freq&lt;/code&gt; argument specifies the clock frequency (in megahertz) for STA.
The output file Im going to work with in the following section is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blink.fasm&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;bitstream-generation-with-project-x-ray&quot;&gt;Bitstream generation with Project X-Ray&lt;/h1&gt;
&lt;p&gt;To write the configuration to the FPGA I needed it in a loadable format.
For Xilinx devices its a bitstream, also known as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bit&lt;/code&gt; files.
I achieved this in two steps: first I converted the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fasm&lt;/code&gt; file to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frames&lt;/code&gt;, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;frames&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bit&lt;/code&gt;.
The software collection thats going to help me generate programming files for the Artix 7 (and for Xilinx FPGAs in general) is called Project X-Ray.
I preformet the first step with Xrays &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fasm2frames&lt;/code&gt; tool, which is sadly broken in the package form the Copr repo.
As a dirty fix, I cloned the &lt;a href=&quot;https://github.com/f4pga/prjxray&quot;&gt;Project X-Ray GitHUB repo&lt;/a&gt; (to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.local/bin/build_stage/&lt;/code&gt;) then used the script in its sources like this:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python ~/.local/bin/build_stage/prjxray/utils/fasm2frames.py &lt;span class=&quot;nt&quot;&gt;--db-root&lt;/span&gt; /usr/share/xray/database/artix7 &lt;span class=&quot;nt&quot;&gt;--part&lt;/span&gt; xc7a35tcpg236-1 ./build/blink.fasm ./build/blink.frames
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I still had to source database from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;projectxray-data&lt;/code&gt; package, as its not stored in the GitHUB repo directly.&lt;/p&gt;
&lt;p&gt;For step two, I employed the tool &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xc7frames2bit&lt;/code&gt; that worked from the installation.
This saved me some time as I would have had to compile this program otherwise (since its written in C, unlike &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fasm2frames&lt;/code&gt;).
The command I used for the conversion is what youd expect:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;xc7frames2bit &lt;span class=&quot;nt&quot;&gt;--part_file&lt;/span&gt; /usr/share/xray/database/artix7/xc7a35tcpg236-1/part.yaml &lt;span class=&quot;nt&quot;&gt;--frm_file&lt;/span&gt; ./build/blink.frames &lt;span class=&quot;nt&quot;&gt;--output_file&lt;/span&gt; ./build/blink.bit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Note that depending on the installation of Project X-Ray, the database directory may be different from mine; find or locate commands can be used to determine the exact path.
Same goes for the part number: different FPGAs from different families need different databases/partfiles.&lt;/p&gt;
&lt;h1 id=&quot;programming-with-openfpgaloader&quot;&gt;Programming with openFPGAloader&lt;/h1&gt;
&lt;p&gt;At last I have my bitstream.
Getting this on the FPGA required the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openFPGAloader&lt;/code&gt; package, also provided by the Copr repo.
For now I loaded the configuration into SRAM, but the CMOD A7 also comes with a serial flash memory to store the config.
The command I used to write the sram looked like this:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/usr/bin/openFPGALoader &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; cmoda7_35t ./build/blink.bit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And flashing wouldve looked like this:&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/usr/bin/openFPGALoader &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; cmoda7_35t &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; blink.bit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once this was complete, I had a led blinking at approximately 0.5 Hz.
Project success!&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;While its a far cry from proprietary integrated development environments, fully open-source FPGA synthesis is possible.
Its limited to Xilinx, Lattice and some other manufacturers (and even here the supported devices/families are limited too).
The weak points are no or limited VHDL 2008 support, the difficulty of hunting down every component (and their documentation).
Thus the barrier to entry is quite high, it took me roughly a day to get it all sorted out with prior knowledge of FPGAs and minimal prior knowledge of the software used.
Advanced features like post-layout synthesis, IP core wizzards and graphical pin planners are either non-existent or not practical.&lt;/p&gt;
&lt;p&gt;On the other hand, these tools feel very fast, especially the synthesis workflow.
I havent done any benchmarks, but especially with Modelsims free edition slowing down significantly over 10000 lines GHDL should be able to compete with it.
Also, since all of them (except GTKWave) are command-line tools, their outputs are mostly in plain text, they fit the general tools of open-source development rather well (eg. git and make).
This makes them feel more ergonomic for a nerd like me, who even edits text in the terminal.
All in all I wouldnt use them in my dayjob (they are just not on par with vendor IDEs), but theyll do fine for my hobby projects.&lt;/p&gt;
&lt;h1 id=&quot;sources&quot;&gt;Sources:&lt;/h1&gt;
&lt;p&gt;nextpnr-himbaechel usage: &lt;a href=&quot;https://github.com/YosysHQ/nextpnr/tree/master/himbaechel/uarch/xilinx/examples/arty-a35&quot;&gt;https://github.com/YosysHQ/nextpnr/tree/master/himbaechel/uarch/xilinx/examples/arty-a35&lt;/a&gt;
general workflow: &lt;a href=&quot;https://github.com/BrunoLevy/learn-fpga/blob/master/FemtoRV/TUTORIALS/toolchain_arty.md&quot;&gt;https://github.com/BrunoLevy/learn-fpga/blob/master/FemtoRV/TUTORIALS/toolchain_arty.md&lt;/a&gt;, &lt;a href=&quot;https://github.com/BrunoLevy/learn-fpga/blob/master/Basic/ARTY/ARTY_blink/makeit.sh&quot;&gt;https://github.com/BrunoLevy/learn-fpga/blob/master/Basic/ARTY/ARTY_blink/makeit.sh&lt;/a&gt;
CMOD A7 docs: &lt;a href=&quot;https://digilent.com/reference/_media/reference/programmable-logic/cmod-a7/cmod_a7_rm.pdf&quot;&gt;https://digilent.com/reference/_media/reference/programmable-logic/cmod-a7/cmod_a7_rm.pdf&lt;/a&gt;
CMOD a7 xdc file: &lt;a href=&quot;https://github.com/Digilent/digilent-xdc/blob/master/Cmod-A7-Master.xdc&quot;&gt;https://github.com/Digilent/digilent-xdc/blob/master/Cmod-A7-Master.xdc&lt;/a&gt;
GHDL Simulation: &lt;a href=&quot;https://ghdl.github.io/ghdl/using/Simulation.html&quot;&gt;https://ghdl.github.io/ghdl/using/Simulation.html&lt;/a&gt;
GHDL synthesis: &lt;a href=&quot;https://github.com/ghdl/ghdl-yosys-plugin&quot;&gt;https://github.com/ghdl/ghdl-yosys-plugin&lt;/a&gt;, &lt;a href=&quot;https://wiki.f-si.org/images/b/b3/Ghdl-FSiC2022.pdf&quot;&gt;https://wiki.f-si.org/images/b/b3/Ghdl-FSiC2022.pdf&lt;/a&gt;
Project X-Ray: &lt;a href=&quot;https://github.com/f4pga/prjxray&quot;&gt;https://github.com/f4pga/prjxray&lt;/a&gt;&lt;/p&gt;</content><author><name></name></author><category term="FPGA" /><summary type="html">In the software world, open-source toolchains are taken for granted. In the FPGA/hardware world, the situation is not as good, but with the right choice of FPGA, it is feasible. Allow me to tell my tale about how I succeeded in bringing up my Artix devboard with only open-source programs.</summary></entry><entry><title type="html">The Self-Contradiction of Spice and Wolf</title><link href="http://localhost:4000/2025/01/09/Spice-and-Wolf.html" rel="alternate" type="text/html" title="The Self-Contradiction of Spice and Wolf" /><published>2025-01-09T00:00:00+01:00</published><updated>2025-01-09T00:00:00+01:00</updated><id>http://localhost:4000/2025/01/09/Spice-and-Wolf</id><content type="html" xml:base="http://localhost:4000/2025/01/09/Spice-and-Wolf.html">&lt;p&gt;I really enjoyed the 2008 &lt;em&gt;Spice and Wolf&lt;/em&gt; series when I watched it, so I was excited to hear it was being worked on again.
After watching &lt;em&gt;Spice and Wolf: MERCHANT MEETS THE WISE WOLF&lt;/em&gt;, I felt the reboot was completely justified.
I had to get used to the new art style initially, but all in all, it looked good.
The sounds (the effects, the soundtrack, and the voice acting) were generally very good, and they get extra points for re-casting the voice actors from the 2008 series.&lt;/p&gt;
&lt;p&gt;The highlight of the show—as with its previous iteration—was Lawrences and Holos pairing and their interactions.
In this regard, the anime didnt fail to deliver; those two were just as fun to watch as always.
But despite all of this, I couldnt help but feel cheated by the shallowness and poorness of the overarching narrative.
Let me expand on this in this writing.&lt;/p&gt;
&lt;h1 id=&quot;premise&quot;&gt;Premise&lt;/h1&gt;
&lt;p&gt;Apart from being a semi-episodic, almost slice-of-life tale of a merchant and his wolf (girl) friend, &lt;em&gt;Spice and Wolf&lt;/em&gt; is about Holo looking for her way home.
The way she goes about doing this is by traveling with Lawrence and seeking out folklore—stories about various pagan deities, which are adjacent or connected to hers and thus show her a way.&lt;/p&gt;
&lt;p&gt;Additionally, the whole season is framed by a Mother (with the voice of Holo) telling the story to her Daughter about the duos adventures.
They are alternately going bankrupt and getting chased by the church on the basis of witchcraft, while slowly progressing towards their destination.
This premise of seeking ones way through the study of tales and stories handed down via oral tradition is very interesting to me and has remarkable potential from a psychological perspective.
This is why it pains me even more to see it turn out the way it did—shallow.&lt;/p&gt;
&lt;h1 id=&quot;stories-are-real&quot;&gt;Stories Are Real&lt;/h1&gt;
&lt;p&gt;Sherlock Holmes lives at 221B Baker Street.&lt;/p&gt;
&lt;p&gt;Santa Claus brings presents to good kids.&lt;/p&gt;
&lt;p&gt;The Hogwarts Express departs from Platform 9¾ at Kings Cross.&lt;/p&gt;
&lt;p&gt;These are widely accepted truths, which are, in one sense, just fabrications.
But I would argue that Sherlock Holmes address matters much more than my address.
To my address, a couple of people come: those who know me and wish to visit me.
But Sherlock Holmes is known by millions, and Baker Street 221B is visited by hundreds on a daily basis for the sole reason that its Sherlock Holmes house.
Everybody says he lives there and even acts as if he lived there.&lt;/p&gt;
&lt;p&gt;Similarly, Santa Claus is real because of the traditions tied to his name.
From a materialist-reductionist point of view, these stories arent hard facts—they have no sensory evidence.
Yet they shape our lives more than, (for example), gravitational waves, which have empirical evidence supporting them.&lt;/p&gt;
&lt;p&gt;Moreover, we have no reason to believe the future is real.
Quite the contrary: were at constant risk of dying (although for the luckier amongst us, that chance is very low), so there may never be a future for us.
We have no sensory reading of tomorrow, yet we naturally act as if it were just as real as today—or even more real, when we set aside resources from today (for example, when we only eat half of that delicious spaghetti for dinner, so that the other half can be tomorrows lunch).&lt;/p&gt;
&lt;p&gt;Now, I do not wish to dismantle the utility of measured truths nor their validity; I just want to escape the narrow-mindedness of believing that they are the only things that matter.&lt;/p&gt;
&lt;p&gt;Fiction is often used as an abstraction of reality to help us understand the world and ourselves.
Engineers, in particular, know the utility of abstraction very well.
For example, the story of &lt;em&gt;Star Wars&lt;/em&gt; tells us about passion, politics, forgiveness, and virtue by showing them in action instead of explaining them.
The Emperor is the manifestation of the evil tempter, who corrupts a democracy, destroys a religious order, and manipulates a young hero into becoming his dark, half-machine, broken servant.
His character is an abstraction for evil that needs no explanation to be understood, but can be analyzed in great depth without expending it.&lt;/p&gt;
&lt;p&gt;Abstractions like this are very important to us because they allow us to perceive very complex phenomena with our limited brain capacity.
Dispensing with &lt;em&gt;Star Wars&lt;/em&gt; just because “in reality Darth Vader is just made up by George Lucas” would be superficial to the truths his character tells us about ourselves.
Quite the contrary, I find stories most interesting because they teach me something new about how humans (including me) work—not because they are accurate from a scientific point (be that historical accuracy, physical accuracy, etc.).&lt;/p&gt;
&lt;h1 id=&quot;stories-in-spice-and-wolf&quot;&gt;Stories in &lt;em&gt;Spice and Wolf&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Spice and Wolf&lt;/em&gt; takes this meta-reality of stories and brings them in-universe to material reality, which I find to be an interesting choice.
Holo herself is a mythical beast from pagan traditions, who dwells in the wheat and is responsible for its growth.
But she isnt just an abstraction of the harshness of nature and the hardships of agriculture; shes a walking and breathing demihuman with a wolf tail and ears.&lt;/p&gt;
&lt;p&gt;This could have been used as narrative dissonance (like the forest creatures in &lt;em&gt;Tonari no Totoro&lt;/em&gt;), but instead, she exhibits her supernatural nature in front of all characters, not just Lawrence, thus dismissing this interpretation.
Worse than this, she isnt the only living pagan deity.
Its implied that all of them exist in one form or another, and their stories are considered 100% real (even though these stories are also transmitted through oral tradition).
Their magic is also real, as demonstrated by Holo on multiple occasions, meaning that her powers are not abstractions of natures laws; they are “scientific truths” (in-universe).&lt;/p&gt;
&lt;p&gt;Holos journey—as I wrote before—is about finding stories adjacent to hers in order to find her hometown.
It is similar to how humans orient themselves in the world, with the use of fiction, by identifying as the characters and drawing from the underlying meaning.
The difference is that these pagan stories never seem to extend beyond the factual value of which geographical directions lead to Holos hometown.
This may have been fine if it applied to all stories in this universe, but this is not the case.
The exception is the churchs narrative.&lt;/p&gt;
&lt;p&gt;We never get to really know this story, but we see its effects.
This narrative of the One True God is oppressive against the pagan gods and cant tolerate their existence.
While this is responsible for adding adventure to the story, it is never explained beyond the idea that this was what Christianity did in medieval Europe.
In the end, the church is reduced to power-hungry oppressors who use their narrative to achieve their goals.
For a story about stories, I find this to be a very shallow approach and a massive missed opportunity.
Oppressive stories do exist, so it makes sense to include the dark side of storytelling (which would be propaganda), but we never get to know what makes the story bad or inauthentic.
I dont think that our stories can be reduced to “true = good” and “false = bad.”&lt;/p&gt;
&lt;p&gt;In my opinion, &lt;em&gt;Fullmetal Alchemist: Brotherhood&lt;/em&gt; tackled faith-based exploitation much better in its third episode, &lt;em&gt;City of Heresy&lt;/em&gt;.
Here we not a detailed display of how dangerous religious manipulations are—just listen to the promises of Cornello.
But in &lt;em&gt;Spice and Wolf&lt;/em&gt; were left to believe that members of the church are just after power and money.
And it doesnt stop there; when combined with the next episode, &lt;em&gt;An Alchemists Anguish&lt;/em&gt;, the picture becomes even broader: bad intentions may corrupt any enterprise, not just religion.&lt;/p&gt;
&lt;h1 id=&quot;the-contradiction&quot;&gt;The Contradiction&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Spice and Wolf&lt;/em&gt; is, in the end, a work of fiction.
Its focus is on stories (other works of fiction), which are either factual and valid or oppressive and invalid.
But then again, &lt;em&gt;Spice and Wolf&lt;/em&gt; isnt factual either.
Does that mean that its also a self-serving story?
How is it that I still found it valuable, (albeit annoying), despite not being real in the material sense?
This is the self-contradiction of &lt;em&gt;Spice and Wolf&lt;/em&gt;.&lt;/p&gt;</content><author><name></name></author><category term="anime" /><summary type="html">I really enjoyed the 2008 Spice and Wolf series when I watched it, so I was excited to hear it was being worked on again. After watching Spice and Wolf: MERCHANT MEETS THE WISE WOLF, I felt the reboot was completely justified. I had to get used to the new art style initially, but all in all, it looked good. The sounds (the effects, the soundtrack, and the voice acting) were generally very good, and they get extra points for re-casting the voice actors from the 2008 series.</summary></entry><entry><title type="html">Server Setup Part 3 - Docker and Nextcloud</title><link href="http://localhost:4000/2024/12/14/docker.html" rel="alternate" type="text/html" title="Server Setup Part 3 - Docker and Nextcloud" /><published>2024-12-14T00:00:00+01:00</published><updated>2024-12-14T00:00:00+01:00</updated><id>http://localhost:4000/2024/12/14/docker</id><content type="html" xml:base="http://localhost:4000/2024/12/14/docker.html">&lt;p&gt;This is part four of my server write-up.
In the last part, I wrote about networking on my home server.
This time, Ill let you in on a little secret about how I share one drive between my various applications without ownership/permission problems.
I derived this configuration from the Nextcloud, Servarr, and smbd documentation.
As a reminder, my NAS is still running Openmediavault on a RockPro64 with 1 TB of RAID-1 redundant HDD storage and 500 GB of non-redundant SSD storage.
The first is for bulk storage, and the second is for caching and backups.&lt;/p&gt;
&lt;h1 id=&quot;docker&quot;&gt;Docker&lt;/h1&gt;
&lt;p&gt;For those who have never heard of it, Docker is a containerization platform that I use for running most of my services on my NAS.
Docker Compose is employed due to its convenience of having YAML files (compose files) describe services, which it then pulls like packages and runs like systemd services.
Even more convenient is the Openmediavault Compose plugin that provides a web editor for my compose files and GUI buttons to interact with my containers.
I found this to be the sweet spot between GUI and CLI Docker management, as I dont have to SSH into my server, move to the directory of the compose file, and finally start it, but I was able to use what I knew about YAML and Compose without needing to learn any new concepts.
This conservative approach makes it outshine Portainer, CasaOS, and whatever is built into TrueNAS Scale and Unraid.
Those GUIs are much more difficult to translate to Docker/Compose syntax used by all the tutorials out there.
Additionally, it exposes most functionalities that Docker provides, even ones I didnt know about.
This is another reason why its a solid choice for beginners.
Apart from having SMB configured out of the box, this may be one of the best features of Openmediavault.&lt;/p&gt;
&lt;p&gt;My containers are usually tracking the latest branch.
The images are stored on the 500 GB SSD because they are too large to fit in the 16 GB eMMC of the RockPro64.
Im willing to take the risk of all my services shutting down if the SSD dies because Im only afraid of data losses.
Using the redundant storage would make them slower, and I would find it wasteful.
I pull them by hand around once or twice a month.
I dont employ Watchtower or any other auto-update tool for the same reason I dont run unattended upgrades—its an extra liability and makes troubleshooting an eventual problem more difficult.&lt;/p&gt;
&lt;p&gt;The only thing I dislike about Docker is that it litters my system with virtual and bridge interfaces.
Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker system prune&lt;/code&gt; is a must after updating the containers, but it only keeps the list from growing.
Ideally, an LXC container (with nesting enabled) would be an excellent solution to keep the network shenanigans away from the host, but since that would require giving up the web UI, I never made that move.
If I were running Proxmox, it would be a no-brainer.&lt;/p&gt;
&lt;h1 id=&quot;nextcloud&quot;&gt;Nextcloud&lt;/h1&gt;
&lt;p&gt;Nextcloud is a wonderful suite of applications designed as a self-hosted version of large cloud services (the Google suite, Office 365, Dropbox, etc.).
I use it for sharing files with people (and computers) outside of my network, backing up photos from my phone, and synchronizing my calendar, contacts, Keepass file, notes, and tasks.
For backing up photos, I use their Android app.
It works, has plenty of options, and I dont need more.
For synchronizing contacts, calendar, and tasks, I use DAVx⁵.
Again, its free software and just works.
The password file is accessed through WebDAV by my password managers.
I briefly used Nextcloud to listen to my music, but since Jellyfin is miles ahead in that region, I no longer need this functionality.
The online editor got some use, but I find it hard to push it as most of my peers default to Googles equivalent.&lt;/p&gt;
&lt;p&gt;For managing my Nextcloud instance, I use the Docker AIO.
Its quite convenient due to its automated backups and self-contained nature.
My only complaint is that once you set it up, reconfiguring some options (e.g., the domain to get the certificate for) is a massive pain—you should rather export all your data and start over.
Still, I recommend it wholeheartedly to beginners, as its much easier than building it up component by component (which is totally possible, by the way).&lt;/p&gt;
&lt;h1 id=&quot;storage-permissions&quot;&gt;Storage Permissions&lt;/h1&gt;
&lt;p&gt;By default, Nextcloud stores its files inside its data directory, where touching them with any other program is not a real option.
But since I wanted it to have access to the same files as my SMB server and so I could use my data hoarding tools to organize my media libraries, I mounted my user data directories (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/fileserver/user&lt;/code&gt;) inside Nextcloud as an external directory.
The advantage is that an external directory can be “untrusted,” allowing for changes outside of Nextcloud to its content.
Then, every time a directory is opened through Nextcloud, its contents are refreshed (this requires a setting in Nextcloud—the default behavior is not to refresh).
The reason for mounting it separately for every user is that this way, access can be managed individually.&lt;/p&gt;
&lt;p&gt;However, Nextcloud needs all the files inside the shared directory to be owned by the user &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;www-data&lt;/code&gt; (UID: 33) and the group &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;users&lt;/code&gt; (GID: 100).
To achieve this, I dont run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chown&lt;/code&gt; every hour but instead set SMB to force the user and group to these values, and all my Docker containers are also called with these process IDs.
In the case of qBittorrent and the *Arr stack, it can be achieved by the following environment variables (inside their Compose files):&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;environment&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;PUID=33&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;PGID=100&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;UMASK=002&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In the case of Jellyfin, its a little different; it needs the following line:&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;user&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;33:100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PUID&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PGID&lt;/code&gt; are the process user and group IDs.
The UMASK value makes all the files readable and writable for the user &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;www-data&lt;/code&gt; and also the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;users&lt;/code&gt; group while making them read-only for everyone else.
This may be a security risk, but its not a gaping hole in my system so that every script kiddie can come and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rm -rf&lt;/code&gt; my system—just that itll be easier for them to ruin my day once they are in.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Nextcloud is a good suite of applications for those looking to de-Google their life.
To get the most out of it, my main storage is attached as an external volume.
The only downside is that other services will need to respect Nextclouds permissions: files shall be owned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;www-data:users&lt;/code&gt; (33:100), which can be set for my other Docker services one way or another, and SMB also provides a way to overwrite ownership permissions.&lt;/p&gt;</content><author><name></name></author><category term="home server" /><summary type="html">This is part four of my server write-up. In the last part, I wrote about networking on my home server. This time, Ill let you in on a little secret about how I share one drive between my various applications without ownership/permission problems. I derived this configuration from the Nextcloud, Servarr, and smbd documentation. As a reminder, my NAS is still running Openmediavault on a RockPro64 with 1 TB of RAID-1 redundant HDD storage and 500 GB of non-redundant SSD storage. The first is for bulk storage, and the second is for caching and backups.</summary></entry><entry><title type="html">Server Setup Part 2 - Networking</title><link href="http://localhost:4000/2024/11/25/networking.html" rel="alternate" type="text/html" title="Server Setup Part 2 - Networking" /><published>2024-11-25T00:00:00+01:00</published><updated>2024-11-25T00:00:00+01:00</updated><id>http://localhost:4000/2024/11/25/networking</id><content type="html" xml:base="http://localhost:4000/2024/11/25/networking.html">&lt;p&gt;This is part three of my server writeup.
Ill take a look at the networking services running on my homelab.
As usual, this is not a tutorial but merely a reminder for myself of what I have (or had) and a source of inspiration for others.&lt;/p&gt;
&lt;h1 id=&quot;internal-networking&quot;&gt;Internal networking&lt;/h1&gt;
&lt;p&gt;At home, I have a decent internet connection: 1 GB/s symmetric, nominally.
The reality of this is outside the scope of this essay, but in the end, its sufficient for my activities.
Most importantly, Im not behind CGNAT.
The ISP-provided modem/router/AP all-in-one device is acceptable, and Im satisfied with it in terms of configurability, except for the fact that it runs an OS whose source code I cant access (even though its based on OpenWrt).
All my networking equipment supports 1 Gbit or less, as I currently dont need more.&lt;/p&gt;
&lt;p&gt;In terms of network interfaces for my server, I run a virtual bridge network behind the RockPro64s single gigabit Ethernet port.
Setting it up was a bit tricky (as is the case for every IP change).
Be absolutely sure to set it to the correct static IP, default gateway, and DNS server.
Having a bridge network is mostly beneficial for virtualization, and even though Docker does its own networking, I dont mind it.
It imposes no drawbacks while providing flexibility.&lt;/p&gt;
&lt;p&gt;Docker containers are accessed through port forwards, for which I prefer to use the default port when available, only remapping if theres a collision.
Many services (e.g., qBittorrent) will expect you to use a specific port and require extra configuration internally if you want to use another.
The OpenMediaVault control panel was also moved from ports 80/443 to allow Nextcloud to use them.
I no longer keep a homepage (eg. Homarr) running to remind me of the assigned ports—youll see why later.&lt;/p&gt;
&lt;p&gt;Pi-hole is used for DNS, as it allows me to block network traffic according to my taste.
Currently, I have lists loaded against telemetry, ads, and pornography.
If I werent so lazy, I would have migrated to its DHCP server (in addition to providing DNS), but the ISP router does the job just fine—except that I cant back up its config.
Using Unbound in conjunction with Pi-hole would be ideal, as the recursive DNS solution provided by Unbound is more private than forwarding all my queries to 8.8.8.8 or 1.1.1.1.
Unfortunately, Ive failed to find a working AArch64 image for it when I tried, they kept restarting Unbound perpetually.&lt;/p&gt;
&lt;h1 id=&quot;external-networking&quot;&gt;External networking&lt;/h1&gt;
&lt;p&gt;My homelab has a fully qualified domain name (FQDN) because its required for Nextcloud (and its HTTPS certificates).
Since I dont want to pay for a static IP, I use DuckDNS for dynamic DNS, as they provide free domains.
This domain is then further divided into subdomains by a Caddy reverse proxy on my homelab to forward traffic to my various services.
This is why I no longer need a homepage.
The best thing is that Caddy provides Lets Encrypt certificates and HTTPS encryption, even if the underlying services dont support it.
This even works with DuckDNS domains, but a special container with built-in support is required.&lt;/p&gt;
&lt;p&gt;I currently dont have a VPN set up, as my laptop has issues with WireGuard (even though it works fine from my phone) or Ive misconfigured it.
I havent bothered with it further, as my most important services are proxied out and accessible from the internet.
If I ever upgrade or change distros, Ill give WireGuard another chance.&lt;/p&gt;
&lt;h1 id=&quot;final-words&quot;&gt;Final words&lt;/h1&gt;
&lt;p&gt;Although I have public IPv6, DuckDNS is yet to support it.
Luckily, I dont need it for my server just yet.&lt;/p&gt;
&lt;p&gt;Im considering getting a regular domain instead of the one provided by DuckDNS, but so far, the prices Ive seen are pretty steep.
If I did get one, itd likely be to host my own email server.
Because Im somewhat paranoid about sharing my IP/domain (mostly due to fear of DoS attacks), this blog will continue to exist on GitHub Pages.&lt;/p&gt;
&lt;p&gt;Im thinking about installing an x86 machine to take over networking, home automation, and maybe media server duties, but for now, thats only something Ive experimented with.&lt;/p&gt;</content><author><name></name></author><category term="home server" /><summary type="html">This is part three of my server writeup. Ill take a look at the networking services running on my homelab. As usual, this is not a tutorial but merely a reminder for myself of what I have (or had) and a source of inspiration for others.</summary></entry><entry><title type="html">Creating a Better, New World</title><link href="http://localhost:4000/2024/09/22/creating-a-better-new-world.html" rel="alternate" type="text/html" title="Creating a Better, New World" /><published>2024-09-22T00:00:00+02:00</published><updated>2024-09-22T00:00:00+02:00</updated><id>http://localhost:4000/2024/09/22/creating-a-better-new-world</id><content type="html" xml:base="http://localhost:4000/2024/09/22/creating-a-better-new-world.html">&lt;p&gt;&lt;em&gt;A Comparative Analysis of Code Geass and Death Note&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Code Geass&lt;/em&gt; (the original two seasons) is one of my favourite anime, so when people recommended &lt;em&gt;Death Note&lt;/em&gt; as a similar story, I was intrigued.
During the first episodes, I saw the similarities in the motives and decided to write a comparative analysis to extract the archetypes represented by the two protagonists (antagonists?), Lelouch vi Britannia and Light Yagami.
Needless to say, this analysis contains full spoilers for both anime.&lt;/p&gt;
&lt;h1 id=&quot;dark-tetrad-traits&quot;&gt;Dark Tetrad Traits&lt;/h1&gt;
&lt;p&gt;The dark tetrad is an extension of the dark triad personality traits proposed by psychologists Delroy L. Paulhus and Kevin M. Williams.
It encapsulates the traits of narcissism (holding oneself in extremely high regard, sometimes infallible), Machiavellianism (seeing other people as means to achieve ones goal), and psychopathy (being void of remorse and conscience).
The fourth trait—sadism (finding pleasure in causing pain)—was proposed later, extending the triad into a tetrad.
This collection of personality types is considered dark because they each lean towards malevolence, exploitation, and antisocial behavior.
Exploring these traits is central to both stories, as is apparent in their main characters.&lt;/p&gt;
&lt;p&gt;Light Yagami is a prime example of the dark tetrad.
Hes clearly the unredeemable antagonist of the story, fully aware of the consequences of his actions yet completely committed to them.
This demonstrates psychopathy, as he shows no remorse, no matter who he has to kill to achieve his goal—his utopia.
He also displays Machiavellianism by considering sacrificing his sister to save himself and by pretending to work with the investigators, even “befriending” L.
Most notable is his narcissism, putting himself in the position of god of the new world, being extremely smug about his victories and trembling in the face of defeat.
This is probably Lights most characteristic trait.
His sadism is questionable, as he doesnt actively cause unnecessary pain, but he cant help announcing his victory to the defeated person every single time—even at the risk of getting caught.&lt;/p&gt;
&lt;p&gt;Lelouch vi Britannia, on the other hand, is a much lighter case.
In some sense, he could be called a humanitarian—rising against the oppression of the Japanese, fighting for his sister Nunally—but its not clear throughout the story if hes more evil or good.
Later, it turns out that his support of the oppressed was only secondary to his goal of destroying his father, which marks him as Machiavellian, along with his exploitation of Rolo, Shirley, and Kallen.
His ongoing conflict with Suzaku revolves around whether the ends justify the means, furthering his Machiavellian tendencies.
With the character of Zero, he also exhibits similar narcissistic behavior to Light, deeming himself the maker of miracles (a roundabout way of saying “Im god”), which is further emphasized by his antisocial nature in his class (a trait he shares with Light).
The sense of righteousness is another characteristic of a narcissist, as it puts them above others morally.
In the Zero Requiem arc, Lelouch amplifies these traits to appear entirely antagonistic and draw the worlds hatred onto himself.&lt;/p&gt;
&lt;p&gt;His self-sacrifice shows an improvement in his narcissistic traits by admitting that the world would be better without him, but paradoxically also states that only he could bring about the end of worldwide conflict and oppression.
Sacrificing himself is the ultimate argument of his utilitarianism, showing that even his own life (something many hold most precious) is beneath his final goal, maintaining his integrity even after betraying almost everyone who trusted him (as opposed to Light, who holds his own life most dear).
Where Lelouch remains relatable is in how he feels remorseful and grieves multiple times during the series, which excludes him from being a psychopath or sadist, unlike Light.&lt;/p&gt;
&lt;h1 id=&quot;values-and-motivations&quot;&gt;Values and Motivations&lt;/h1&gt;
&lt;p&gt;The backgrounds of the two antagonists (protagonists?) are strikingly similar.
They both start off as excelling high-school students, which might be the most boring occupation out there.
Where they diverge is the worlds they inhabit.
While both find their worlds rotten, Light lives in whats essentially the same as our world—though it has its problems, it certainly doesnt benefit from his radical actions as Kira.
On the other hand, Lelouch lives in a reality where theres real oppression, real genocide, and real tyranny.
Even though hes in the privileged class, he cant stay silent about it.
In both series, storytelling amplifies this argument, showing only minimal crimes in &lt;em&gt;Death Note&lt;/em&gt; but full purges and exploitation of the “Elevens” in &lt;em&gt;Code Geass&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The two characters families also play a significant role in shaping their actions, but in an almost opposite way.
Light inherits his sense of justice from his father and thus pretends to be his ally, whereas Lelouch is in conflict with his father (and most of his half-siblings), destined to fight against him.
His sense of justice comes from his personal experience of abuse and stands in opposition to the exploitative nature of his ancestors.
This isnt unique to his generation, as Euphemia and Nunally also find Britannia despicable, but Lelouch is the one who takes action first.&lt;/p&gt;
&lt;p&gt;Both characters claim to want to make the world a better place and are willing to take extreme measures to achieve it.
But theres an interesting difference: Lelouch wants a world where he and his sister can live peacefully—value added to the existing world—while Light wants a world without crime—something subtracted from the existing.
I generally value constructive methods and tend to be skeptical of destructive ones.
The outcomes of the two stories seem to support this, though it may also be rooted in their ability to make the correct sacrifices.&lt;/p&gt;
&lt;h1 id=&quot;allies-and-pawns&quot;&gt;Allies and Pawns&lt;/h1&gt;
&lt;p&gt;As the journey of the two (anti)heroes unfolds, they both make allies, or at least sacrificial pawns, to help them achieve their goals.
In Lelouchs case, the supporting group is the Black Knights, a band of freedom fighters who doubt Zero, but have no better option than to serve him.
In Yagamis case, he joins the Special Provision for Kira only in the second half of the anime, and only as an extra layer of disguise.
They, too, arent the pinnacle of competence, but they remain wary of him, and eventually catch on, which proves detrimental for Kira—similarly to how Lelouchs situation worsens after Schneizel exposes him to the Black Knights.&lt;/p&gt;
&lt;p&gt;More interesting to me are the allies who share in the powers: the Death Note and the Geass.
Yagami has quite a few of them, but the main one is Misa Amane—a fanatic of Kira and Light, who gives up three-quarters of her life to get affirmation from a psychopath who discards her after she is no longer of use to him.
A similar fate awaits all the other Kiras, who all get disposed of by Light when they achieve the goal they were given a Death Note for, or when Light is at risk of getting found out.
Teru Mikami, Kyouske Higuchi, and Kiyomi Takada are all just pawns in Lights quest, who can be sacrificed for the greater good—or so Light believes.&lt;/p&gt;
&lt;p&gt;Lelouch has only one Geass-user ally: Rolo.
He enters the story as a fake brother, sent by his father to keep him in check, but is manipulated into allying with Zero after he awakens.
Similarly to Misa, he is emotionally unstable and naive, serving as a prime victim for the Machiavellian Lelouch.
He becomes so attached to him that he sacrifices his life to save Zero.
In this victim role, they both serve as examples of how one can be completely exploited and die for a lie they tell themselves.&lt;/p&gt;
&lt;p&gt;Despite the similarities of their underlings, the two stories have a big difference, namely the supernatural entities bestowing the superpowers that change the world.
Ryuk, as a god of death, has no interest in the success or failure of Light beyond entertainment and maybe as a way to eat apples, and he makes it clear that he doesnt want to help him.
After all, hes only interested in humans dying, as thats the condition of shinigamis.
His only goal is to kill some time—in the most bizarre sense.&lt;/p&gt;
&lt;p&gt;C.C., on the other hand, is deeply involved in Lelouchs success, first as a partner in crime and with the goal of ending her own misery.
I speculate that she harbors a great deal of regret—in the case of Mao, she even states it—but I assume she feels some responsibility for Britannias conquest.
I base this on the support she provides Lelouch to achieve his aim, even from the beginning, by playing the part of a critic of his actions.
Later, she grows emotionally attached to Lelouch, going as far as to give up her own wish of dying for the sake of the new world order based on his death—the event she spent the entirety of the story preventing.&lt;/p&gt;
&lt;h1 id=&quot;symbolical-similarities&quot;&gt;Symbolical Similarities&lt;/h1&gt;
&lt;p&gt;Both series use symbols to convey deeper meanings.
The main reason I wanted to write this analysis is the symbolic similarities, which are quite consistent between the two series.&lt;/p&gt;
&lt;p&gt;The first is that both powers are linked to vision and eyes.
Lelouchs Geass requires eye contact to work, and the Death Note requires you to visualize the target as well as write their name into the book.
Additionally, the shinigami eyes grant vision of names above the targets.
These sets of restrictions provide challenges to the wielders of the powers, as they force personal contact, leading to intentionally exciting situations.
But apart from being plot devices, they also highlight the visionary nature of the two lead characters.&lt;/p&gt;
&lt;p&gt;Another interesting similarity is that both stories feature a memory loss arc.
These allow us to peek into what would have happened if Light and Lelouch had never gotten hold of their powers and had never set out on their quests.
But they also show that once they started on their mission, they are no longer content with ordinary life, and their fate at the end of the road.&lt;/p&gt;
&lt;p&gt;But what fate awaits them at the end of the road?
For both, its death.
Light is taken out by Ryuk right after he is exposed as Kira, and Lelouch sacrifices himself at the hands of Suzaku to achieve his goal of making the world a better place to live in.
Light gets close to his goal of becoming the god of the new world but fails in the end, whereas Lelouch succeeds—but only by sacrificing everything, including himself.&lt;/p&gt;
&lt;p&gt;Sacrificing oneself to cleanse the world—this is clearly a parallel to Jesus Christ, who is known as the ultimate example of self-sacrifice for the complete salvation of mankind.
Dying in the arms of Nunnally is also intentionally similar to the Pietà—the symbol of Holy Mary holding her dead son.
&lt;em&gt;Death Note&lt;/em&gt; also has its Biblical reference: when L washes Yagamis feet, it mirrors the image of Jesus washing the feet of Judas Iscariot before being betrayed and killed by him.
This reference even makes sense in-universe, as Ls origin (Wammys House) is illustrated with Christian symbols, including a church, so L might have been familiar with the Bible from his orphanage days.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The two anime — &lt;em&gt;Death Note&lt;/em&gt; and &lt;em&gt;Code Geass&lt;/em&gt; — showcase two similar characters whose alignment in terms of good and evil is comparable.
Both are shown to possess traits that are known in psychology as the dark tetrad, but Yagami is much more pathological than Lelouch.
Their relationships are mostly similar, both in terms of underlings and enemies, except for key differences that usually restore some of Lelouchs humanity and reveal the extent of Yagamis rotten nature.
They end the same but differently—both characters die, closing their stories, but Lelouch succeeds in his goal by sacrificing himself, while Light suffers for sacrificing everyone and everything for his twisted ego.&lt;/p&gt;</content><author><name></name></author><category term="anime" /><summary type="html">A Comparative Analysis of Code Geass and Death Note</summary></entry><entry><title type="html">AIndustrial Revolution</title><link href="http://localhost:4000/2024/07/28/aindustrial-revolution.html" rel="alternate" type="text/html" title="AIndustrial Revolution" /><published>2024-07-28T00:00:00+02:00</published><updated>2024-07-28T00:00:00+02:00</updated><id>http://localhost:4000/2024/07/28/aindustrial-revolution</id><content type="html" xml:base="http://localhost:4000/2024/07/28/aindustrial-revolution.html">&lt;p&gt;This post is from an essay I wrote last year when I was confronted with the hype around generative AI.
I made some guesses about what the future might hold if machine intelligence lives up to the hype.
I attempt to imagine a future where artificial intelligence replaces human creative labor, make guesses about its effects by drawing parallels with the second industrial revolution, and offer my suggestions on how to deal with the changes as a creative worker.&lt;/p&gt;
&lt;h1 id=&quot;aindustrial-revolution&quot;&gt;AIndustrial Revolution&lt;/h1&gt;
&lt;p&gt;Those who use AI to get creative work done: This is a warning!&lt;br /&gt;
For at least five years, many have entertained the idea of the Internet of Things (IoT) bringing about the Fourth Industrial Revolution for developed countries.
While this has yet to happen, recent advances in generative Artificial Intelligence (AI) make me wonder how it would look if it were to be the next revolution.&lt;/p&gt;
&lt;p&gt;In February 2023, David Rivers wrote an &lt;a href=&quot;https://agequodagis.substack.com/p/the-struggle-is-real&quot;&gt;article&lt;/a&gt; titled “The Struggle is Real,” investigating the problematic nature of AI in entertainment and art.
He wrote about how the creative process is more than just having an idea and seeing it realized: its hard work, and this is what gives creation value and meaning.
This article inspired me to think about how using AI would affect my work as an (electronics) engineer and how it would affect anyone whose job is to create intellectual property.&lt;/p&gt;
&lt;p&gt;The current state of IP mass production is akin to hand manufacturing after the first industrial revolution.
There are lots of specialized workers in massive offices (assembly lines), with many working on the same product in a waterfall manner.
The output products are somewhat serialized (although the appearance of innovation is important): just look at the differences between the same manufacturers sequentially released smartphones, computer parts, cars, movies, TV series, etc.
These are all optimized for development time and cost to achieve an aggressive time-to-market delay, while entire departments are dedicated to selling this surplus of products.
My guess is that once these industries learn how to harness generative AIs, theyll start to phase out humans in favor of machines and their operators—just as they did in the second industrial revolution.
The output quality and “waste” produced wont matter as long as the increase in quantity makes up for it in terms of profit.&lt;/p&gt;
&lt;p&gt;The number of laborers needed to operate an AI-driven IP factory is a lot less than in a conventional office.
Even though creative industries are considered a growing field, switching to AI en masse would probably see more or less all of these workers laid off, depending on the field, just like factory workers during the second industrial revolution.
Even though IP creation requires high fluid intelligence, retraining to become an AI operator might not be an option for everyone.
And what if not all engineers, artists, writers, journalists, and other creative workers are satisfied with instructing an AI and correcting its mistakes for the rest of their careers?&lt;/p&gt;
&lt;p&gt;A more conservative worker might refuse the idea of outsourcing work to something as unpredictable as an AI.
Im sure the traditional jobs wont completely go away, just like theres still a market for handmade consumer products and bio/locally grown food is enjoyed by many — but these are exceptions, and whoever makes them is exceptionally skilled.
If you are working in IP production and are fine with being an AI operator, then be prepared so that you can make the switch when you need to.
If you arent fine with this, strive to be exceptionally skilled.
Compare your work against the best AI tools and specialize in fields that require high accountability and top-notch quality.&lt;/p&gt;
&lt;p&gt;But for the rest, who arent creative workers, what would the AIndustrial revolution bring about?
Apart from the social effects of an unemployment spike and the initial decrease in the quality of IPs (which should improve over time), previous industrial revolutions had a common side effect along with the main welfare effect: pollution.
Operating large AI farms would undoubtedly increase environmental pollution (due to their high energy requirements), but we are prepared for that (to some extent).
Pollution in areas we cant predict is what Im more concerned with.
An example could be the pollution of intellectual products.&lt;/p&gt;
&lt;p&gt;AI designs are sometimes so alien to human designs that we cant fully comprehend them.
And how can we distinguish a good design from a bad one if it doesnt follow the usual conventions (which is often an explicit goal when making effective AIs)?
How can we repair (not to mention repurpose) something that is a black box even to its creator?
Lazy and irresponsible handling of AI design can even lead to a flawed design being released and manufactured, and the lack of understanding of the design doesnt help either.
And worst of all, it might even be financially worth it compared to a suite of specialists perfecting the same design for many, many hours.
In conclusion: if you are producing IPs, be prepared when the AI companies come for your job.
And even if you arent this type of worker, be aware of the dangers of an AI-designed product and proceed with caution.
We were probably wrong to think machines would take over manual labor first.&lt;/p&gt;
&lt;h1 id=&quot;hindsight-after-a-year&quot;&gt;Hindsight After a Year&lt;/h1&gt;
&lt;p&gt;I might have been overly optimistic about the abilities of the AI tools.
In this last year, they have shown no improvement at all, but their limitations are starting to show.
However, Im also starting to see more and more obviously AI-generated billboard graphics, where the fact that they were accepted is somewhat disturbing.
I still hold my final conclusions, but the AI takeover definitely wont happen in the next ten years, and maybe never in my lifetime.
I remain hostile to using AIs for generating content; however, for interpreting and correcting syntax, Im willing to try them out.&lt;/p&gt;</content><author><name></name></author><category term="philosophy" /><summary type="html">This post is from an essay I wrote last year when I was confronted with the hype around generative AI. I made some guesses about what the future might hold if machine intelligence lives up to the hype. I attempt to imagine a future where artificial intelligence replaces human creative labor, make guesses about its effects by drawing parallels with the second industrial revolution, and offer my suggestions on how to deal with the changes as a creative worker.</summary></entry><entry><title type="html">8VIM review</title><link href="http://localhost:4000/2024/07/26/8vim.html" rel="alternate" type="text/html" title="8VIM review" /><published>2024-07-26T00:00:00+02:00</published><updated>2024-07-26T00:00:00+02:00</updated><id>http://localhost:4000/2024/07/26/8vim</id><content type="html" xml:base="http://localhost:4000/2024/07/26/8vim.html">&lt;p&gt;8VIM is an alternative keyboard created by Ravi Agarwal.
Its premise is to replace the traditional target-based typing on touchscreens with more ergonomic, fast, and memorable gestures.
It promises better accuracy, speed, and helpful shortcuts for editing text while typing.
After one month of learning and then six months of exclusive usage on mobile, Im ready to give my review.
Im comparing it to OpenBoard, my previous keyboard app, in both cases using the Hungarian layout, as I need to write using the languages special (umlaut) characters.&lt;/p&gt;
&lt;h1 id=&quot;getting-used-to&quot;&gt;Getting used to&lt;/h1&gt;
&lt;p&gt;Just like regular vim, usage is initially limited by a lack of practice.
As mentioned above, it took me a month to stop learning, meaning that I ceased to see any improvement in my speed or accuracy.
The reason Im hesitant to say Ive mastered it is that neither aspect was to my liking—it was neither faster nor more accurate than OpenBoard.&lt;/p&gt;
&lt;h1 id=&quot;the-good&quot;&gt;The good&lt;/h1&gt;
&lt;p&gt;The clipboard is very well done.
Having a paste gesture is convenient and the clipboard history is a first-class implementation.
The one thing I didnt understand is, why pasting is disabled when typing passwords.
As autofill is still broken within my password manager, this made it really troublesome to log in.
Since most of my passwords are unique, and I rely on a manager to keep track of them, this was a real hindrance.&lt;/p&gt;
&lt;p&gt;Navigation gestures are also the best Ive experienced.
They are a strong selling point of the application, theres a good reason why Termux also includes arrow keys in its auxiliary keybar.
Speaking of Termux, the control modifier can also be useful, but most of the time apps dont expect it, so its not as useful as I wished it was.&lt;/p&gt;
&lt;p&gt;But the primary reason I wanted to use 8VIM was the ability to touch type.
With vibration feedback, I could look away from the screen and still be sure what I was typing was correct - although it was slower than looking at my input.
Ive never tried any keyboard for the visually impaired, but 8VIM might hold its ground against them - assuming you can learn it blindly - at least for letters, that is.&lt;/p&gt;
&lt;h1 id=&quot;the-bad&quot;&gt;The bad&lt;/h1&gt;
&lt;p&gt;It may have been due to my aged (4-year-old) phone, but 8VIM sometimes just froze and took no further input.
It never lasted longer than a few seconds, but it was still annoying, even for that short time.&lt;/p&gt;
&lt;p&gt;Since changing capitalization requires a full turn (which is longer than typing any character), an auto-capitalization would have been welcome.
This problem is exacerbated by the annoyance of correcting mistakes: first finish the word, then swipe back, then correct the letter, and if youre not careful, you insert an extra space you have to clean up.
Its not impossible, just tedious.&lt;/p&gt;
&lt;p&gt;But the worst experience is with symbols and numbers.
To type them you have to use a numpad, reverting to the old targeting method, instead of the gestures.
Its really annoying, especially when mixed with letters (for example ham callsigns).
I wish they were more ergonomic, meaning I could input them blindly, and preferably without lifting my finger (literally).&lt;/p&gt;
&lt;h1 id=&quot;the-ugly&quot;&gt;The ugly&lt;/h1&gt;
&lt;p&gt;In May, I started to grow suspicious of my speed and accuracy when typing, so I reverted to OpenBoard, just for comparison.
As much as I wished it were not the case, I was neither slower nor did I make more mistakes.
But the easy access to the numbers and the vast array of available symbols (something that was limited to four or five times less in 8VIM) were refreshingly convenient.&lt;/p&gt;
&lt;p&gt;OpenBoards clipboard history is just as good as 8VIMs and is not hidden when I need it the most.
Navigation is not as smooth as in 8VIM, but I can still swipe the spacebar to go left or right, which is almost as good.&lt;/p&gt;
&lt;p&gt;Another big improvement (that shouldnt be one) is that OpenBoard can function in landscape mode - something that 8VIM developers just didnt bother to fix.
And while the enter “key” in 8VIM is inconsistent - sometimes inserting newline (eg. in Facebook Messenger), sometimes sending the message (eg. in Discord) - OpenBoards enter always puts newline.&lt;/p&gt;
&lt;h1 id=&quot;verdict&quot;&gt;Verdict&lt;/h1&gt;
&lt;p&gt;8VIM remains a party trick - a way to make your phone unusable for others - but no more.
The touch typing promise is limited by the inability to input numbers and symbols blindly, and the promise of one-handedness is limited by the one hands grip without the thumb (as its used for typing).
So unless youre blind, have only one hand and only type telegraphs, its not for you.&lt;/p&gt;</content><author><name></name></author><category term="tech review" /><summary type="html">8VIM is an alternative keyboard created by Ravi Agarwal. Its premise is to replace the traditional target-based typing on touchscreens with more ergonomic, fast, and memorable gestures. It promises better accuracy, speed, and helpful shortcuts for editing text while typing. After one month of learning and then six months of exclusive usage on mobile, Im ready to give my review. Im comparing it to OpenBoard, my previous keyboard app, in both cases using the Hungarian layout, as I need to write using the languages special (umlaut) characters.</summary></entry><entry><title type="html">Storage in my home server</title><link href="http://localhost:4000/2024/05/26/storage.html" rel="alternate" type="text/html" title="Storage in my home server" /><published>2024-05-26T00:00:00+02:00</published><updated>2024-05-26T00:00:00+02:00</updated><id>http://localhost:4000/2024/05/26/storage</id><content type="html" xml:base="http://localhost:4000/2024/05/26/storage.html">&lt;p&gt;This is part two of my server writeup.
Ill discuss how I organized the storage of my server starting from the hard drives, touching on file systems and redundancy, and even going into the folder structure, permissions and shared folders.&lt;/p&gt;
&lt;h1 id=&quot;changes-to-the-host-system&quot;&gt;Changes to the host system&lt;/h1&gt;
&lt;p&gt;As I mentioned in my last post, my power solution is the weakest link in my system.
Changing to a USB-C PD charger and trigger board didnt help much either: the current spikes from hardware spinup were too much even for that.
In this regard, Im finding the salvaged PSU better, but I wont change back to it, as itd be a shock and fire hazard.
Having an unstable PSU caused corruption of my data, which is unacceptable.&lt;/p&gt;
&lt;p&gt;The requirements also changed since last time: I no longer intend to replace the Synology NAS, I only want to store my data on this server.
This allowed me to drop two of the four redundant disks, which means Im inside the power budget, however even with two disks I was still getting some errors.
Strangely the errors were only affecting one disk.
I got one with the same capacity to replace it, but the system became unusably glitchy, crashing and rebooting after about an hour of usage, every single time, until none of the disks were detected.
It turned out that the six-port PCIe-SATA adapter died on me.
I replaced it with the two-port one I wrote about in part zero (as its sufficient now), and then also replaced the misbehaving disk with another one.&lt;/p&gt;
&lt;p&gt;With these modifications, my server has been running stable for more than a month now (except when I tripped a breaker, but lets not count that).
No crashes, no errors in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmesg&lt;/code&gt;.
It appears Ive fixed all hardware issues, and I can move on with the configuration.&lt;/p&gt;
&lt;h1 id=&quot;block-storage-and-file-system&quot;&gt;Block storage and file system&lt;/h1&gt;
&lt;p&gt;The system boots from a 16GB eMMC module I bought with the SBC.
Its fine for the most part, but container and VM images need to live elsewhere, as they wouldnt fit otherwise.&lt;/p&gt;
&lt;p&gt;I also briefly used a 16GB SD card for swapping (to avoid the OOM killer) but I removed it when the server was crashing constantly.
It doesnt look like the system is missing it at all.&lt;/p&gt;
&lt;p&gt;Theres a 2.5” 1TB HDD attached via a USB3 SATA adapter that serves as a non-redundant local backup storage.
I use it to push (borg) backups from my laptop to and for backups of the most important data on the server as well as system and docker configurations.
Its formatted to BTRFS to take advantage of its extra features (compared to ext4).&lt;/p&gt;
&lt;p&gt;The main storage is the two 1TB HDDs in BTRFS-RAID1.
I choose BTRFS for redundancy instead of MDRAID, because this way BTRFS can take full advantage of the redundancy and correct more errors.
Im not sure if its a testament to this or the quality of my “power supplies”, but while I had 20-30 files rendered partially unreadable with my RAID-6 config, I had none with the BTRFS-RAID1 one.
Do note, that BTRFS on multiple devices is not the best idea, see this article for details: https://arstechnica.com/gadgets/2021/09/examining-btrfs-linuxs-perpetually-half-finished-filesystem/
The best solution would be ZFS, but as explained previously, its not possible for now.&lt;/p&gt;
&lt;h1 id=&quot;folder-layout-and-permissions&quot;&gt;Folder layout and permissions&lt;/h1&gt;
&lt;p&gt;The redundant array serves two purposes: it holds docker configurations (to increase availability) and all the user data.
They are separated into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compose/&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fileserver/&lt;/code&gt;.
Compose holds docker, volumes and compose-files, but not images.
Fileserver is shared via SMB and houses one folder for each user, plus a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public/&lt;/code&gt; directory.
They all have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Documents/&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Downloads/&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Music/&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pictures/&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Templates/&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Videos/&lt;/code&gt; but media is usually uploaded to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public/&lt;/code&gt; and documents are kept in user directories.&lt;/p&gt;
&lt;p&gt;Everything on this array is owned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;www-data:users&lt;/code&gt;.
I would have liked to restrict (write) access to user directories to the users that they belong to, but Nextcloud (which I extensively use) mandates that all directories are owned by the mentioned user and group.
To enforce this, all docker containers are configured with a PUID of 33, a PGID of 100 and a UMASK of 002, and in SMB &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forceuser=www-data&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcegroup=users&lt;/code&gt; options are set for the share.
NFS is avoided since it doesnt have these options.&lt;/p&gt;
&lt;p&gt;On the root of the non-redundant disk, theres a directory exposed as an SMB share, titled “Backup”.
Its purpose is to allow backups to be made from computers on the local network.
An Rsync task is set up to create a copy of it in an offsite NAS in the family for a 3-2-1 backup scheme.
Outside of the backup directory is a folder containing docker images and another one for Jellyfin to use as a (transcode) cache and metadata storage.
These arent critical so itd be a waste to store them on RAID.
In the future, Id like to set up an Rsync target to this disk to receive remote backups from someone.
I also set up an ISCSI target on this disk but I have yet to put it to use.&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;I have 2 TB of usable space in my server.
1 TB is redundant and is used as a high-availability NAS, with only the most important files backed up elsewhere.
The other 1TB is non-redundant and is used only for containers, caching and as a local backup storage, which saved me a lot of time already.
The local backups are further reinforced by an offsite copy, at a family member.
They are both running BTRFS for its advanced features.
Various workarounds are in effect on the redundant array to ensure compatibility with Nextcloud, for which all files need to be owned by a specific user and group.&lt;/p&gt;</content><author><name></name></author><category term="home server" /><summary type="html">This is part two of my server writeup. Ill discuss how I organized the storage of my server starting from the hard drives, touching on file systems and redundancy, and even going into the folder structure, permissions and shared folders.</summary></entry><entry><title type="html">Server Setup Part 1 - Host System</title><link href="http://localhost:4000/2024/05/06/host.html" rel="alternate" type="text/html" title="Server Setup Part 1 - Host System" /><published>2024-05-06T00:00:00+02:00</published><updated>2024-05-06T00:00:00+02:00</updated><id>http://localhost:4000/2024/05/06/host</id><content type="html" xml:base="http://localhost:4000/2024/05/06/host.html">&lt;p&gt;&lt;em&gt;This post was supposed to be published in December 2023, but due to technical dificulties I didnt do it at the time.
Its remained an important part of my server writeup, even though some of it is no longer representative of my setup.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is part one of my server writeup.
Ill go through the hardware choices I made so far and the operating system and core software components.
Ill also briefly mention how I started out as well as what upgrades Im planning to make.
I didnt want to buy something new because of budget concerns, so my choice was dictated by what I already had.&lt;/p&gt;
&lt;h1 id=&quot;the-rockpro64&quot;&gt;The RockPro64&lt;/h1&gt;
&lt;p&gt;As the main platform running my home server, I choose the RockPro64, with 4GB of onboard memory.
In &lt;a href=&quot;https://derisis13.github.io/2023/12/08/statusquo.html&quot;&gt;part zero&lt;/a&gt; I already spoke about the hardware Im replacing, this single-board computer should be more powerful than both combined.
I also experimented with a Chinese motherboard and an Intel i7-2670QM (a 2nd gen mobile i7) but I didnt find the extra performance to be useful (&lt;a href=&quot;https://browser.geekbench.com/v5/cpu/16451184&quot;&gt;benchmark&lt;/a&gt;), and the power draw was too much for my taste.
While my old setup used 20-21W combined, the x86 setup drew 35-36W on average while the RockPro64 drew 17-18W on average; all of them with two HDDs.
If I ever feel like running out of CPU performance I can still try overclocking the RK3399, I havent experimented with this yet, but I hope the stock 1.42 GHz was a conservative choice.&lt;/p&gt;
&lt;p&gt;I bought this SBC in 2021 to experiment on (in some sense this computer taught me to use Linux), and sat abandoned since the end of the 2nd COVID wave in a cardboard box.
I ran it first in this cardboard box with two HDDs, but that couldnt be the permanent solution, so I adapted it to some ITX mounting holes (with a piece of FR4) and placed it inside the biggest case I could find at home.
This time I also included a bigger PCIe SATA card based on the ASM1166 and added two extra hard drives in RAID-6 (Ill talk about this decision in the next chapter).
Currently, the disks are 2x2TB and 2x1TB of spinning rust (for a total of 2TB pooled), but once the migration is complete itll have 4x 3TB for 6TB usable storage.&lt;/p&gt;
&lt;p&gt;These parts are all spares I had lying around, they have bad sectors and they have strange read/write errors at the filesystem level that I attribute to them overloading the power supply.
This is a salvaged unit I pulled from a set-top box (same as &lt;a href=&quot;https://ha5kfu.hu/2023/04/05/vfd-kijelzo-ujrahasznositasa/&quot;&gt;this one&lt;/a&gt; I used in another project) and it can officially provide 1A@12V.
It was good enough when I started, but it seems I hit its limit.
I already ordered a USB-C PD charger with a trigger board that should give me 3x as much power and not be a shock- and fire hazard.&lt;/p&gt;
&lt;p&gt;The biggest limit of this setup is memory.
4GB is just not enough to run Linux, docker containers and spin up at least one virtual machine.
To make it just a little less critical (avoid the OOM killer) I added a 16GB microSD card as a swap partition - I have no idea how long itll hold but its cheap to replace.&lt;/p&gt;
&lt;h1 id=&quot;openmediavault&quot;&gt;OpenMediaVault&lt;/h1&gt;
&lt;p&gt;On my x86 server, I used TrueNAS Scale, and while I was satisfied with ZFS and how it handled SMB shares, the way it complained as soon as I tried to touch the CLI was off-putting and I couldnt get used to its docker UI at all.
Additionally, its not available on ARM as far as I know, so I couldnt use it even if I wanted to.&lt;/p&gt;
&lt;p&gt;So I installed Debian Bullseye and OpenMediaVault 6 on top (just like when I first bought the system).
Many in the self-hosting community find OMV a lesser, unprofessional experience (as opposed to TrueNAS or UnRaid) but I really like the balance it strikes between ease of use and how similar it feels to the CLI tools Im used to.
With all of its plugins it offers a complete experience, and whats missing can be added from docker.
I currently have the plugins for system backups, borg backup, tgt (iSCSI target), wireguard, docker-compose, cputemp (installed by default), flashmemory (folder2ram, installed by default because I boot from eMMC) and kvm (although I no longer have a use for it).&lt;/p&gt;
&lt;p&gt;All in all its a solid experience, OMV only adds to stock Debian and takes none of it away.
I think this pattern is not appreciated enough.&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;I run a RockPro64 SBC with 4GB RAM, supported by some swap.
The performance is just enough for my use case, but it leaves not much space for future expansion, I have it pretty much maxed with the software Ill write about in the next parts.
Storage still needs to be upgraded (I still have to purchase the drives) and the PSU is at its limit, but a new one is on its way.&lt;/p&gt;
&lt;p&gt;I installed OpenMediaVault and I love how it only adds to Linux and takes nothing away.
Its a solid foundation for my storage and other services and I find it more convenient than TrueNAS Scale.&lt;/p&gt;
&lt;p&gt;In the next part, Ill write about the storage setup, from hard disks to folders.&lt;/p&gt;</content><author><name></name></author><category term="home server" /><summary type="html">This post was supposed to be published in December 2023, but due to technical dificulties I didnt do it at the time. Its remained an important part of my server writeup, even though some of it is no longer representative of my setup.</summary></entry><entry><title type="html">Singularity Feedback Loop</title><link href="http://localhost:4000/2023/12/19/singularity.html" rel="alternate" type="text/html" title="Singularity Feedback Loop" /><published>2023-12-19T00:00:00+01:00</published><updated>2023-12-19T00:00:00+01:00</updated><id>http://localhost:4000/2023/12/19/singularity</id><content type="html" xml:base="http://localhost:4000/2023/12/19/singularity.html">&lt;p&gt;In this short essay, Ill examine the idea of the Singularity Feedback Loop.
Ill touch on Trans- and Posthumanism (which Ill shorten to Transhumanism) but the focus will be this disciplines dreaded and awaited messiah: the Technological Singularity.&lt;/p&gt;
&lt;h1 id=&quot;growth-and-singularity&quot;&gt;Growth and Singularity&lt;/h1&gt;
&lt;p&gt;The idea of Singularity is simple: once men create a machine capable of producing a better machine than humans could, it then repeats this process indefinitely.
At the birth of the computer, intelligence became a physical product - and thus it can be manufactured by machines.
With the emergence of generative AI models we have seen working computer code written by computer code, however, these are still much less complex than the generating program.
Based on the exponential growth of computers transistor counts (known as Moores law), its not too difficult to theorize something similar for AI.&lt;/p&gt;
&lt;p&gt;But even Gordon Moore acknowledged the “red brick wall”, beyond which growth is impossible, due to physical limitations.
And as anyone who has learned system theory knows, even feedback - no matter how explosive it is - is limited by the boundaries of the system its part of.
Growth forever is possible, in the case of asymptotic growth, but this isnt a continuously accelerating process.
To think you can create something out of nothing or more out of less contradicts the laws of thermodynamics.
You would have - even if not in the traditional sense - made a perpetuum mobile.
And the thing that can create something out of nothing has always been a religious deity.&lt;/p&gt;
&lt;h1 id=&quot;the-singularity-is-religious&quot;&gt;The Singularity is religious&lt;/h1&gt;
&lt;p&gt;And so the followers of this discipline created their own religions - extropianism, singulitarianism - they believe something thats above the laws of the world as we know it.
And from it, they seek to free mankind from its flesh prison, much like traditional religions.
But unlike how the followers of other religions claim to have seen or heard their deity, or at least know someone who has; not a single person has made contact with the Singularity, as it doesnt exist yet.
And if you ask me, itll never transcend the realm of fantasy, as its impossible to create something from nothing.&lt;/p&gt;
&lt;h1 id=&quot;the-singularity-is-the-philosophers-stone&quot;&gt;The Singularity is the Philosophers Stone&lt;/h1&gt;
&lt;p&gt;Humans always had the desire to create the ultimate creation.
Since the middle ages we have tried to make perpetual motion devices, and to this day charlatans are trying to sell them as “free energy devices”.
A similar invention, that also made its way (conceptually) to Transhumanism is the philosophers stone, sought by the alchemists.
This device would have provided its wielder eternal life (much like Transhumanists would like to artificially surpass death) and infinite wealth and prosperity (another goal of Transhumanism) by turning ordinary metals into gold.&lt;/p&gt;
&lt;p&gt;Even though the alchemists never succeeded in their original goals (now we see why they didnt even have a chance) their contribution to natural sciences is not negligible, and they had a comparable impact on the arts and literature.
They never reached eternal life nor infinite wealth, but from their “failed” experiments came fragments of knowledge, on which modern science is built.
So I keep smiling at the Transhumanists - as long as their methods are kept clean, I want them to carry out their experiments, and even though they wont succeed, we can still be grateful for their “failed” attempts.&lt;/p&gt;</content><author><name></name></author><category term="philosophy" /><summary type="html">In this short essay, Ill examine the idea of the Singularity Feedback Loop. Ill touch on Trans- and Posthumanism (which Ill shorten to Transhumanism) but the focus will be this disciplines dreaded and awaited messiah: the Technological Singularity.</summary></entry></feed>