<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on Tristan Ross</title>
        <link>https://tristanxr.com/post/</link>
        <description>Recent content in Posts on Tristan Ross</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Mon, 17 Nov 2025 11:50:00 +0800</lastBuildDate><atom:link href="https://tristanxr.com/post/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Nix on the DC ROMA II</title>
        <link>https://tristanxr.com/post/dc-roma-ii-nix/</link>
        <pubDate>Mon, 17 Nov 2025 11:50:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/dc-roma-ii-nix/</guid>
        <description>&lt;p&gt;At NixCon 2025, I had the pleasure of meeting the Founder of DeepComputing, Yuning Liang.
I was excited as I ordered their new laptop, the DC ROMA II, a few months prior. It has an ESWIN EIC7700X,
an SoC with 8 out of order execution RV64GBC cores. This is a huge upgrade compared to the 4 in-order
execution cores on the JH7110 that the VisionFive 2 uses. I started looking into getting Nix &amp;amp; NixOS working
on it shortly after receiving it. Surely since I am able to port NixOS to things like the FydeTab Duo and get
a VisionFive 2 to work, I should be able to get this system working.&lt;/p&gt;
&lt;p&gt;The first thing I did was install Nix, however there&amp;rsquo;s no prebuilt binaries for Nix that the installer script
utilizes. I took a look at the installer script and found a convinient option called &lt;code&gt;--tarball-url-prefix&lt;/code&gt;.
I spun up a build of Nix for RISC-V using an Arm cross environment. However, I ended up not needing that due
to Hydra conviently having done that for me in
&lt;a class=&#34;link&#34; href=&#34;https://hydra.nixos.org/build/312888635&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Build 312888635 of job nix:master:binaryTarballCross.x86_64-linux.riscv64-unknown-linux-gnu&lt;/a&gt;.
I managed to even point &lt;code&gt;--tarball-url-prefix&lt;/code&gt; to
&lt;a class=&#34;link&#34; href=&#34;https://hydra.nixos.org/build/312888635/download/1/nix-2.33.0pre20251111_af0ac14-riscv64-linux.tar.xz&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;nix-2.33.0pre20251111_af0ac14-riscv64-linux.tar.xz&lt;/code&gt;&lt;/a&gt;.
Once I ran the installer, the installation experience was smooth. I restarted the shell and ran &lt;code&gt;nix --version&lt;/code&gt; which told me that I have 2.33.0.&lt;/p&gt;
&lt;p&gt;After installing Nix, I decided to try building &lt;code&gt;nix-info&lt;/code&gt;. I ran &lt;code&gt;nix-shell -p nix-info&lt;/code&gt; which seemed to start smoothly,
but was quickly interrupted as bootstrap-tools failed to build. This is a big problem, as the &lt;code&gt;bootstrap-tools&lt;/code&gt; derivation is
a crucial part of the nixpkgs bootstrap process. It takes a pre-built tarball of various tools like &lt;code&gt;coreutils&lt;/code&gt;, &lt;code&gt;gcc&lt;/code&gt;, &lt;code&gt;patchelf&lt;/code&gt;,
and a subset of &lt;code&gt;binutils&lt;/code&gt;. It provides the necessary commands to bootstrap nixpkgs from a small footprint and in a sandboxed
environment. I managed to cross compile a new bootstrap tools tarball on my Ampere desktop, copied that over and hacked around
&lt;code&gt;import &amp;lt;nix/fetchurl.nix&amp;gt;&lt;/code&gt; so it did &lt;code&gt;url = &amp;quot;file://${./bootstrap-tools.tar.xz}&amp;quot;;&lt;/code&gt; instead of fetching from the tarballs server.
This allowed me to use the new bootstrap tools. Once that was done, I attempted another build and the bootstrap tools managed to build.
However, this was only a temporary victory.&lt;/p&gt;
&lt;p&gt;After chatting with other NixOS contributors, it turns there&amp;rsquo;s an issue in nixpkgs regarding PIE. PIE is a method of allowing programs
to be relocated. This is useful on systems with limited address spaces and helps prevent libraries from colliding due to
occupying the same address. The issue was discovered by using &lt;code&gt;strace -E LD_DEBUG=all&lt;/code&gt; on GCC. This revealed the following logs:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;execve(&amp;#34;/nix/store/kg61gdq4svvph0c4pcsf867r8nkbiqs7-bootstrap-tools/lib/ld-linux-riscv64-lp64d.so.1&amp;#34;, [&amp;#34;/nix/store/kg61gdq4svvph0c4pcsf8&amp;#34;..., &amp;#34;/nix/store/kg61gdq4svvph0c4pcsf8&amp;#34;0
brk(NULL)                               = 0x7fff84224000
openat(AT_FDCWD, &amp;#34;/nix/store/kg61gdq4svvph0c4pcsf867r8nkbiqs7-bootstrap-tools/bin/gcc&amp;#34;, O_RDONLY|O_CLOEXEC) = 3
read(3, &amp;#34;\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\2\0\363\0\1\0\0\0\230\312\2\0\0\0\0\0&amp;#34;..., 832) = 832
getpid()                                = 6665
writev(2, [{iov_base=&amp;#34;      6665:\t&amp;#34;, iov_len=12}, {iov_base=&amp;#34;file=&amp;#34;, iov_len=5}, {iov_base=&amp;#34;/nix/store/kg61gdq4svvph0c4pcsf8&amp;#34;..., iov_len=67}, {iov_base=&amp;#34; [&amp;#34;, iov_len=2}, {iovp
) = 111
mmap(0xf000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = -1 EPERM (Operation not permitted)
close(3)                                = 0
writev(2, [{iov_base=&amp;#34;/nix/store/kg61gdq4svvph0c4pcsf8&amp;#34;..., iov_len=67}, {iov_base=&amp;#34;: &amp;#34;, iov_len=2}, {iov_base=&amp;#34;error while loading shared libra&amp;#34;..., iov_len=36}, {iov_base=&amp;#34;: t
) = 217
exit_group(127)                         = ?
+++ exited with 127 +++
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you look closely, you&amp;rsquo;ll see the &lt;code&gt;mmap&lt;/code&gt; call. It&amp;rsquo;s attempting to map address 0xf000 with a 4kb size and have it be read-write.
However, you will notice that the syscall is returning &lt;code&gt;-1&lt;/code&gt; and indicating an error code, &lt;code&gt;EPERM&lt;/code&gt;. Not being able to mmap the address
is causing a big problem since looking at the ELF header using &lt;code&gt;readelf -l&lt;/code&gt;, you can see that is used by the program header (&lt;code&gt;PHDR&lt;/code&gt;).&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x000000000000f040 0x000000000000f040
                 0x00000000000002a0 0x00000000000002a0  R      0x8
  RISCV_ATTRIBUT 0x0000000000219e92 0x0000000000000000 0x0000000000000000
                 0x0000000000000057 0x0000000000000000  R      0x1
  GNU_STACK      0x0000000000001000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  LOAD           0x0000000000000000 0x000000000000f000 0x000000000000f000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
  LOAD           0x0000000000001000 0x0000000000010000 0x0000000000010000
                 0x000000000020ded0 0x000000000020ded0  R E    0x1000
  INTERP         0x00000000000142d0 0x00000000000232d0 0x00000000000232d0
                 0x000000000000005c 0x000000000000005c  R      0x1
      [Requesting program interpreter: /nix/store/kg61gdq4svvph0c4pcsf867r8nkbiqs7-bootstrap-tools/lib/ld-linux-riscv64-lp64d.so.1]
  NOTE           0x0000000000014330 0x0000000000023330 0x0000000000023330
                 0x0000000000000020 0x0000000000000020  R      0x4
  GNU_EH_FRAME   0x00000000001c41d8 0x00000000001d31d8 0x00000000001d31d8
                 0x000000000000967c 0x000000000000967c  R      0x4
  LOAD           0x000000000020ef58 0x000000000021ef58 0x000000000021ef58
                 0x000000000000af28 0x00000000000103b8  RW     0x1000
  TLS            0x000000000020ef58 0x000000000021ef58 0x000000000021ef58
                 0x0000000000000000 0x0000000000000010  R      0x8
  GNU_RELRO      0x000000000020ef58 0x000000000021ef58 0x000000000021ef58
                 0x00000000000080a8 0x00000000000080a8  R      0x1
  DYNAMIC        0x0000000000216dd0 0x0000000000226dd0 0x0000000000226dd0
                 0x0000000000000230 0x0000000000000230  RW     0x8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although this is useful information, it does not clearly state why that is a problem.
All of these addresses fit within the RISC-V specification for alignment and generally looks safe.
However, if you look at the ELF header, it tells a different story.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ELF Header:
  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2&amp;#39;s complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - GNU
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           RISC-V
  Version:                           0x1
  Entry point address:               0x2ca98
  Start of program headers:          64 (bytes into file)
  Start of section headers:          2203656 (bytes into file)
  Flags:                             0x5, RVC, double-float ABI
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         12
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 30
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the problem is revealed, the PIE flag is not set.
What this means is the kernel is doing the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Checks ELF magic&lt;/li&gt;
&lt;li&gt;Iterate through each section&lt;/li&gt;
&lt;li&gt;Check the address is lower than &lt;code&gt;vm.mmap_min_addr&lt;/code&gt; &amp;amp; PIE is set
&lt;ul&gt;
&lt;li&gt;If the PIE flag is set, ignore the &lt;code&gt;vm.mmap_min_addr&lt;/code&gt; sysctl&lt;/li&gt;
&lt;li&gt;If the address is lower, fails&lt;/li&gt;
&lt;li&gt;If the address is higher, succeeds&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Executes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is roughly an oversimplified explanation of how a program is loaded. So we know PIE is not set, however there&amp;rsquo;s
the other problem. I ran &lt;code&gt;cat /proc/sys/vm/mmap_min_addr&lt;/code&gt; and got back 65536. Now that explains what&amp;rsquo;s going on, the
address we&amp;rsquo;re trying to have mapped is lower than what the kernel is permitting. I decided to try &lt;code&gt;sysctl -w vm.mmap_min_addr=4096&lt;/code&gt;
and ran the build again.&lt;/p&gt;
&lt;p&gt;After attempting to build again, everything continued to work. The next thing to do will be fixing PIE on RISC-V in nixpkgs but
that&amp;rsquo;ll be a future thing to do. Until then, I&amp;rsquo;ll be making progress on getting NixOS to boot.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>SELinux on NixOS</title>
        <link>https://tristanxr.com/post/selinux-on-nixos/</link>
        <pubDate>Sat, 05 Apr 2025 18:00:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/selinux-on-nixos/</guid>
        <description>&lt;p&gt;Since Wednesday, I&amp;rsquo;ve been hard at work with trying to get SELinux
(Security Enhanced Linux) to function on NixOS. This is because I
am building a Linux distro called &lt;a class=&#34;link&#34; href=&#34;https://expidusos.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ExpidusOS&lt;/a&gt;.
One of the goals for that is to implement a mobile OS security setup
into the OS. With ExpidusOS being based on NixOS, this means the entire
OS is declaratively built. However, it is more in-line with an appliance
OS. This is to increase security and make it easier for the end user to
utilize.&lt;/p&gt;
&lt;h2 id=&#34;packaging-selinux&#34;&gt;Packaging SELinux
&lt;/h2&gt;&lt;p&gt;SELinux was luckily already packaged in nixpkgs, but it hadn&amp;rsquo;t been
maintained in a long time. That is until I picked it up last year.
I had been a the maintainer of it for about a year. But now,
I am finally getting involved in making SELinux on NixOS a reality.
The only real work has been making sure there&amp;rsquo;s little existing
problems reported and reviewing any pull requests. However, I did
have to package the &lt;a class=&#34;link&#34; href=&#34;https://github.com/SELinuxProject/refpolicy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SELinux reference policy&lt;/a&gt;.
The &lt;code&gt;refpolicy&lt;/code&gt; is a simple SELinux policy that provides enough
for a usable experience. It is in no way a fully secure policy
but it is a good enough policy to work off of.&lt;/p&gt;
&lt;p&gt;To package it, I started out with a typical Nix derivation
which fetches from GitHub. However, I did have to add a few
things that are unique like &lt;code&gt;makeFlags&lt;/code&gt;. This attribute
holds all the flags to pass over to GNU Make as &lt;code&gt;refpolicy&lt;/code&gt;
is built with GNU Makefiles. One of the few differences was
adding in &lt;code&gt;make conf&lt;/code&gt; as the &lt;code&gt;configurePhase&lt;/code&gt; and passing in
the various SELinux userspace tools in through &lt;code&gt;makeFlags&lt;/code&gt;.
From there, I was able to build the policy. Though, it did
end up with &lt;code&gt;$out/usr&lt;/code&gt; but that was as simple as adding this to
the &lt;code&gt;makeFlags&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;prefix=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;placeholder &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;out&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the &lt;code&gt;refpolicy&lt;/code&gt; derivation outputting correctly, it was time
to figure out how SELinux works and getting it functioning.&lt;/p&gt;
&lt;h2 id=&#34;starting-the-selinux-nixos-module&#34;&gt;Starting the SELinux NixOS module
&lt;/h2&gt;&lt;p&gt;The first thing I did on the NixOS side was I created a basic module.
This module added &lt;code&gt;libselinux&lt;/code&gt; and &lt;code&gt;policycoreutils&lt;/code&gt; to
&lt;code&gt;environment.systemPackages&lt;/code&gt;. It also created &lt;code&gt;/etc/selinux/config&lt;/code&gt;,
the configuration file which configures SELinux on the distro. I also
added a kernel patch via &lt;code&gt;boot.kernelPatches&lt;/code&gt; which enabled
&lt;code&gt;CONFIG_SECURITY_SELINUX&lt;/code&gt; and &lt;code&gt;CONFIG_SECURITY_SELINUX_BOOTPARAM&lt;/code&gt;.
I then added &lt;code&gt;security=selinux&lt;/code&gt; to &lt;code&gt;boot.kernelParams&lt;/code&gt;. With this,
I booted up the NixOS VM and checked &lt;code&gt;sestatus&lt;/code&gt; to ensure SELinux
was enabled. However, it reported as disabled. I tried various other
kernel parameters and versions of the kernel. This led me to trying
systemd with SELinux enabled in &lt;code&gt;systemd.package&lt;/code&gt;. I booted up the
VM and got a warning saying &lt;code&gt;/etc/selinux/refpolicy/policy/policy.33&lt;/code&gt;
did not exist. &lt;code&gt;sestatus&lt;/code&gt; also reported that SELinux was indeed enabled.
This was the first large step towards getting SELinux working. The next
step was getting the &lt;code&gt;policy.33&lt;/code&gt; file to exist.&lt;/p&gt;
&lt;h2 id=&#34;getting-a-policy-loaded&#34;&gt;Getting a policy loaded
&lt;/h2&gt;&lt;p&gt;Making a policy load on NixOS was a bit of an endeavor as there wasn&amp;rsquo;t
many tutorials I could find which explained things very aptly. I checked
what Gentoo and Arch Linux does and found that Arch Linux&amp;rsquo;s
&lt;code&gt;selinux-refpolicy-git&lt;/code&gt;&amp;rsquo;s install script from the AUR is what I needed.
The solution I came up with was to tack it into the activation script.
This would install the policy upon the NixOS generation was activated.&lt;/p&gt;
&lt;p&gt;At this point, I got stuck and ran into a broken pipe error. I eventually
managed to figure out via verbose mode that it was looking for &lt;code&gt;hll&lt;/code&gt; in
a FHS path and not within the Nix store. I grepped SELinux&amp;rsquo;s source code
and stumbled upon &lt;code&gt;libsemanage&lt;/code&gt; having a configuration file format. This
would be perfect as it allows for specifying the paths to the various
tools &lt;code&gt;semodule&lt;/code&gt; calls. I added the paths for &lt;code&gt;hll&lt;/code&gt;, &lt;code&gt;load_policy&lt;/code&gt;,
&lt;code&gt;setfiles&lt;/code&gt;, and &lt;code&gt;sefcontext_compile&lt;/code&gt;. I also had to tack on the
arguments that &lt;code&gt;libsemanage&lt;/code&gt; uses by default for the last three tools.&lt;/p&gt;
&lt;p&gt;Once &lt;code&gt;semanage&lt;/code&gt; was using its configuration file inside &lt;code&gt;/etc/selinux&lt;/code&gt;,
I booted up the VM one more time. The boot stalled and the error about
&lt;code&gt;/etc/selinux/refpolicy/policy/policy.33&lt;/code&gt; was still present. I checked
the path and found &lt;code&gt;/etc/selinux/refpolicy/policy/policy.34&lt;/code&gt; existed.
I checked &lt;code&gt;sestatus&lt;/code&gt; and it said the system was using policy v33.&lt;/p&gt;
&lt;h2 id=&#34;getting-the-right-policy-version&#34;&gt;Getting the right policy version
&lt;/h2&gt;&lt;p&gt;SELinux spitting out &lt;code&gt;policy.34&lt;/code&gt; instead of &lt;code&gt;policy.33&lt;/code&gt; stumpted me.
Until, I grepped the SELinux source tree more. I found out that SELinux&amp;rsquo;s
userspace tools default to the max version. The max version which at this
time is 34. The kernel I was using has an SELinux version of 33. This
meant that I had to get &lt;code&gt;refpolicy&lt;/code&gt; to build for SELinux policy 33
instead of 34. I found that various tools in SELinux support specifying
the version. However, &lt;code&gt;refpolicy&lt;/code&gt; has a flag for changing the version. This
led me to add two new attributes which can be overridden when building
&lt;code&gt;refpolicy&lt;/code&gt;, &lt;code&gt;policyVersion&lt;/code&gt; and &lt;code&gt;moduleVersion&lt;/code&gt;. I also added a
&lt;code&gt;policyVersion&lt;/code&gt; option to the SELinux module in NixOS.&lt;/p&gt;
&lt;p&gt;After rebuilding the VM and deleting the &lt;code&gt;qcow2&lt;/code&gt; image as a precaution,
I booted up the VM one more time. It did the usual stall on boot when
&lt;code&gt;semanage&lt;/code&gt; would install the policy. After about 40 seconds, the system
initialization continued. However, the error about the missing &lt;code&gt;policy.33&lt;/code&gt;
file went away. Other messages complaining about various systemd things
also disappeared. I checked &lt;code&gt;/etc/selinux/refpolicy/policy/policy.33&lt;/code&gt; and
it existed. &lt;code&gt;sestatus&lt;/code&gt; also mentioned the policy is &lt;code&gt;refpolicy&lt;/code&gt;. These
two indicated that SELinux is indeed working.&lt;/p&gt;
&lt;h2 id=&#34;configuring-selinux-in-nixpkgs&#34;&gt;Configuring SELinux in nixpkgs
&lt;/h2&gt;&lt;p&gt;With SELinux properly loading a policy, I decided to start cleaning
up how SELinux is handled on nixpkgs. I started with checking for
everything which optionally added SELinux based on an attribute.
I also added a new nixpkgs config flag called &lt;code&gt;selinuxSupport&lt;/code&gt;. This
config flag is able to rebuild everything from coreutils to postgres
and emacs. It enables SELinux support everywhere it is possibly supported.
This process was pretty straight forward and went very smoothly.&lt;/p&gt;
&lt;h2 id=&#34;upstreaming-into-nixpkgs&#34;&gt;Upstreaming into nixpkgs
&lt;/h2&gt;&lt;p&gt;All this work for ExpidusOS had been made with the intention of it
going back into nixpkgs and NixOS upstream. I made the following pull
requests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/NixOS/nixpkgs/pull/396105&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;libselinux: 3.8 -&amp;gt; 3.8.1 #396105&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/NixOS/nixpkgs/pull/396155&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;selinux-refpolicy: init 2.20250213 #396155&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/NixOS/nixpkgs/pull/396168&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pkgs/top-level/config.nix: add selinux support #396168&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/NixOS/nixpkgs/pull/396177&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;nixos/selinux: init #396177&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These four pull requests ended up being all it takes to get basic SELinux
support into NixOS and nixpkgs. In my time of looking at various things,
I came across an RFC (&lt;a class=&#34;link&#34; href=&#34;https://github.com/NixOS/rfcs/pull/41&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;[RFC 0041] SELinux Support #41&lt;/a&gt;).
Reading through it, I see why SELinux support hadn&amp;rsquo;t been done to this degree
before. However, I believe the work I have done here and the ExpidusOS project
to push SELinux support to be capable of securing a NixOS appliance OS.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps
&lt;/h2&gt;&lt;p&gt;The next step from here is get everything upstreamed. From there, I plan on
working out a way to do declarative policy creation within the NixOS module
system. This would make handling policies better than using &lt;code&gt;refpolicy&lt;/code&gt;.
From there, it can be investigated how this impacts the Nix daemon and
building in general.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>The Asahi NixOS Experience</title>
        <link>https://tristanxr.com/post/asahi-nixos/</link>
        <pubDate>Fri, 17 Jan 2025 10:11:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/asahi-nixos/</guid>
        <description>&lt;p&gt;In August of 2023, I was looking around for a new laptop. At the time,
I was running an Alienware laptop with an RTX 3070 in it. However, it
is a cumbersome machine with horrible battery life. The great thing was
its performance. I needed a machine which was powerful, can run Linux,
has great battery life, and portable. I wrote off x86 as S0 sleep mode
(Windows Modern Standby) became pervasive, many vendors omitted or
improperly handle normal S3 sleep. This led me to an ARM machine.
The introduction of compelling ARM-powered laptops led me to select
the 2021 MacBook Pro. It has 16GB of RAM and 1TB of storage. To save
money, I went with one from Apple&amp;rsquo;s refurbishment service.&lt;/p&gt;
&lt;h2 id=&#34;the-installation-process&#34;&gt;The Installation Process
&lt;/h2&gt;&lt;p&gt;As soon as my Macbook Pro arrived, I began installing Nix on Darwin. It was
a troublesome experience trying to integrate it properly in my Flake config.
After a few hours, I was able to get home-manager working with Nix on Darwin.
However, I wasn&amp;rsquo;t done yet and I wanted Linux on this machine. So I stumbled
upon &lt;a class=&#34;link&#34; href=&#34;https://github.com/tpwrules&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Thomas Watson&lt;/a&gt;&amp;rsquo;s
&lt;a class=&#34;link&#34; href=&#34;https://github.com/tpwrules/nixos-apple-silicon&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;nixos-apple-silicon&lt;/code&gt;&lt;/a&gt; Flake.&lt;/p&gt;
&lt;p&gt;The installation went smoothly, after disabling System Integrity Protection and
running the Asahi Linux setup script, I was ready to begin. I grabbed my flash drive
with Thomas&amp;rsquo;s Asahi NixOS installer on it. From there, installation proceeded like
normal for NixOS. I set up an ext4 partition, pull my Flake, and run &lt;code&gt;nixos-install&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After some time of building, I then had NixOS on Apple Silicon. I had my
desktop environment setup like how it is on my other machines but on ARM.
Unfortunately, audio wasn&amp;rsquo;t working properly at the time so I had to rely on
Bluetooth. However, this became less of a problem after months had progressed.
I&amp;rsquo;ve been happily running NixOS with Asahi packages on an M1 Pro.&lt;/p&gt;
&lt;h2 id=&#34;the-problems&#34;&gt;The Problems
&lt;/h2&gt;&lt;p&gt;A few problems I ran into with daily driving Asahi NixOS was the system
did not have enough memory and not enough storage. I decided to get rid of
the replace mode for the Mesa fork and go with an overlay. This would allow
me to build my configuration on Garnix, a Nix CI service. However, this had
the side effect of causing a mass rebuild of everything requiring Mesa.
Not too long after, I had gained access to the Nix community aarch64 machine.
I was then able to use it to build the heavy parts of my configuration. The
reason why Garnix couldn&amp;rsquo;t build it was either Garnix didn&amp;rsquo;t provide aarch64
at the time or I hadn&amp;rsquo;t gotten my configuration to properly take advantage of
Garnix&amp;rsquo;s cache.&lt;/p&gt;
&lt;p&gt;During my work with LLVM, I also was experiencing massive usages in memory
and storage usage. I had configured my system to use half of the drive while
macOS uses the other half. This is so I could have the best of both worlds.
Unfortunately, this has restricted how much storage I have so I&amp;rsquo;d often
be running the Nix garbage collector. I&amp;rsquo;ve also experienced problems with memory.
Due to only having 16GB of RAM and the system using unified memory, there&amp;rsquo;s cases
where I can easily run into the out of memory killer triggering and causing jobs
to fail. A solution has been to limit the number of jobs. However, these problems
are less of a concern after I built my Ampere Altra desktop in July of 2024.&lt;/p&gt;
&lt;h2 id=&#34;gaming&#34;&gt;Gaming
&lt;/h2&gt;&lt;p&gt;Many people may think you cannot game on a Macbook. However, that is not the case.
There&amp;rsquo;s been many documented cases of people playing Steam games on Apple Silicon
machines. Even on macOS, Steam works with Apple&amp;rsquo;s x86 translation layer. However,
on Linux we have to use box86. The problem is, Apple Silicon uses a 16k page size
due to how the IOMMU is designed. The solution has been to use a project called muvm,
formerly called krunvm. However, this tool is new enough that getting it working on NixOS
isn&amp;rsquo;t quite possible yet.&lt;/p&gt;
&lt;h2 id=&#34;battery-life&#34;&gt;Battery Life
&lt;/h2&gt;&lt;p&gt;One of the big requirements for me when I got this machine was battery life.
In macOS alone, the system can last days in sleep which is a great improvement over
the 3 hours my Alienware could last in sleep mode. However, it looks like the Asahi
project has not fully gained that level of sleep performance (Reference
&lt;a class=&#34;link&#34; href=&#34;https://github.com/AsahiLinux/linux/issues/262&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;issue AsahiLinux/linux#262 - &amp;ldquo;sleep mode battery improvement&amp;rdquo;&lt;/a&gt;).
Despite the battery life not being as good as macOS, I can have my machine on
battery for 13 hours while alseep. This is a huge improvement over my Alienware but
isn&amp;rsquo;t much of a concern as I charge my system overnight and usually have access to
power. Although, I mostly have access to an outlet, I like being able to sit on a
couch at home or sit on my bed while I work. While working, I can get somewhere
between 2 hours and 5 hours of battery life. It is very dependant on what I am working
on. If I am building LLVM, I can get 4 full builds and tests of libLLVM to a clang binary
and still have 32% battery life. With web browsing and video playback, I can get closer
to the 5 or 6 hour life.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;The Asahi project and Thomas Watson have done a great job at getting Linux
and NixOS to work well with Apple&amp;rsquo;s ARM chips. The battery life is long enough for me
to get plenty of work done while I am not tethered to a wall. The system&amp;rsquo;s performance
is quite capable despite being limited by memory and storage. It is my go-to machine
and my favorite to use when I don&amp;rsquo;t have to be at a desk. This machine is an example
of why ARM is the future.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Scaling workloads</title>
        <link>https://tristanxr.com/post/scaling-workloads/</link>
        <pubDate>Tue, 11 Jun 2024 19:25:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/scaling-workloads/</guid>
        <description>&lt;p&gt;Since the early 2000s, multi-core CPUs have been standard in consumer machines.
The main advantage of multi-core processors is their ability to run tasks in parallel.
If you&amp;rsquo;re not aware, a single CPU core cannot execute multiple instructions simultaneously
(except in CPU&amp;rsquo;s with speculative execution, deep pipelining, or SMT).
Instead, we rely on schedulers that interrupt the current process and switch it out when it&amp;rsquo;s
time for another process to run. However, this method is not entirely optimal, as it can lead
to situations where not all processes get enough time. Nowadays, processors often have core counts
reaching 10 or more. Many smartphones use octocore processors, meaning they effectively have 8
CPUs within a single CPU. This allows you to run 8 processes on 8 cores, potentially giving 100%
execution time to each process if the scheduler permits it. But many of us are not just running 8
processes. Simply booting up a modern OS can result in thousands of processes, though many of these
are short-lived or use minimal resources. In a modern OS, processes typically jump between different
cores, and those requiring more CPU time are given priority. Balancing workloads on a CPU involves
many factors. This post focuses on scaling compiler jobs when using build systems like Ninja, Make, and Nix.&lt;/p&gt;
&lt;h2 id=&#34;binary-optimizations&#34;&gt;Binary Optimizations
&lt;/h2&gt;&lt;p&gt;There are many layers to scaling, and the efficiency of your program plays a significant role.
Different compilers, even for the same language, can result in varying optimizations that affect
runtime performance. All binaries are large without optimizations due to the inclusion of debugging
information. Therefore, it is typical to build programs in &amp;ldquo;release&amp;rdquo; mode (using &lt;code&gt;-O3&lt;/code&gt; in C/C++ compilers).
This mode maximizes optimizations and minimizes debug information. Another useful technique is compiling
with the CPU tune or model set, ensuring the compiler uses the most optimal instructions for the target
CPU. CPUs of different architectures, generations, and manufacturers can vary significantly, affecting
performance even for programs compiled for the same CPU architecture. CPUs execute instructions in a pipeline,
which typically consists of three steps: fetch, decode, and execute. During the fetch stage, the CPU reads
the instruction from memory, usually using the program counter register. On modern systems, the CPU often
reads from its cache. The CPU then decodes the instruction, setting various control signals. Modern CPUs
use microcode to control the timing pulses and control signals. Finally, the CPU executes the instruction,
sending various signals based on the decoded instruction.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example of how simple programs in x86 assembly can be optimized:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;mov&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ax&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;mov&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;bx&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;add&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ax&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;bx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This program consists of three instructions: two mov instructions and one add instruction. This
simple program takes three clock cycles to complete. However, it can be optimized further:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;mov&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ax&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;add&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ax&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or even more:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;add&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;ax&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This optimization assumes ax is already 1 before the add instruction, reducing the program to a
single clock cycle. However, this optimization is dangerous as it assumes the CPU state without
checks, potentially leading to incorrect results.&lt;/p&gt;
&lt;h2 id=&#34;workload-size&#34;&gt;Workload Size
&lt;/h2&gt;&lt;p&gt;The size of the workloads, the suitability of the CPU for the workload, and sufficient RAM are
crucial. It&amp;rsquo;s better to have a CPU for a specific architecture rather than cross-compiling, as
this reduces the bootstrap requirements. Having enough RAM depends on the system&amp;rsquo;s typical
usage and the degree of parallelization possible. This distinction will become more apparent as the
world moves from x86 to ARM architecture. ARM is known as a RISC (Reduced Instruction Set Computing)
architecture, while x86 is a CISC (Complex Instruction Set Computing) architecture. x86 has more
instructions, but many are similar to each other. ARM has fewer, more essential instructions, resulting
in less complexity, less heat generation, and reduced thermal throttling. This makes ARM ideal for
laptops and phones. In my experience with a modern ARM processor (Apple M1 Pro), it outperforms an
x86 processor (Ryzen 5 3600 on my desktop). Despite having fewer optimized instructions, having more
CPU cores is beneficial. You can only execute instructions so fast, constrained by the silicon design
and thermal limits. ARM systems typically run cooler and have more cores, allowing them to handle many
processes simultaneously. However, memory remains a critical factor. It&amp;rsquo;s essential to know your workload&amp;rsquo;s
RAM requirements and ensure your system has enough RAM to handle peak usage.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Why upsteaming patches matters</title>
        <link>https://tristanxr.com/post/why-upstreaming-matters/</link>
        <pubDate>Mon, 10 Jun 2024 18:18:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/why-upstreaming-matters/</guid>
        <description>&lt;p&gt;With packaging software, there will always be cases where software fail to run
or build as expected. This is especially common in Nix where it is not a traditional
Linux/UNIX environment. For example, Nix does not use the filesystem hierarchy (FHS)
which is standard in POSIX. Instead each package has its own directory in the Nix
store, also referred to as a local cache, and contains directories such as &lt;code&gt;bin&lt;/code&gt;,
&lt;code&gt;lib&lt;/code&gt;, &lt;code&gt;share&lt;/code&gt;, etc. As most software is written to expect the FHS, they can easily
break and not run as expected. Due to the Nix store being write-only at build time,
it is essentially immutable afterwards. These factors cause many software ranging
from LLVM to Google Chrome and Flutter to either not build correctly or not
work as intended.&lt;/p&gt;
&lt;p&gt;When a patch is required during packaging, it&amp;rsquo;s a good idea to send that patch
to the upstream repository. This helps in both preventing the necessity of the patch
when packaging future versions of the software, and notifying the upstream contributors
that special actions must be taken for a given distro. This offers a collaborative
effort to ensure the software builds in one environment but also other environments as well.
With my efforts with LLVM, we&amp;rsquo;re trying to upstream patches whenever we perform an update
to the git package version of LLVM.&lt;/p&gt;
&lt;p&gt;When creating a patch, the easiest way to do it is to utilize the &lt;code&gt;diff&lt;/code&gt; command from
&lt;code&gt;diffutils&lt;/code&gt;. Another way is to use &lt;code&gt;git diff&lt;/code&gt; which git provides, this can be piped to a
file and added into the directory where your package&amp;rsquo;s build files are. Then you can create
a new commit and push to your fork of that software and submit a pull request/merge request.
From there, you can easily communicate to the other contributors and developers of the
package to ensure the patch works as intended and that it is of good quality. This
process may take a while but becomes very collaborative and is often beneficial for
everyone.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Why 16k page size matters</title>
        <link>https://tristanxr.com/post/why-16k-page-size/</link>
        <pubDate>Sun, 09 Jun 2024 18:27:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/why-16k-page-size/</guid>
        <description>&lt;p&gt;Since August of 2023, I&amp;rsquo;ve been a daily user of a 14-inch 2021 Apple MacBook Pro (M1 Pro, 16GB RAM) laptop.
Thanks to &lt;a class=&#34;link&#34; href=&#34;https://github.com/tpwrules&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;@tpwrules&lt;/a&gt;&amp;rsquo;s &lt;a class=&#34;link&#34; href=&#34;https://github.com/tpwrules/nixos-apple-silicon/tree/main&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NixOS Asahi Linux Flake&lt;/a&gt;,
I was able to set up the laptop to run NixOS. The majority of software have worked perfectly on it and I
consider it to be the best Linux laptop for its performance. However, one major issue isn&amp;rsquo;t a hardware issue
but a software one. When you see memory sizes on a system, you commonly think about things like the timing,
what kind of RAM chips they use, the number of RAM chips in a stick or channel of memory, and so on.
Though, this isn&amp;rsquo;t that. This particular issue is one designed into the Asahi Linux kernel and even macOS&amp;rsquo;s
Darwin kernel. This would be the page size, the number which dictates the minimum size of a page of memory is.
Every modern computer nowadays, since the mid 80&amp;rsquo;s and into the 90&amp;rsquo;s, use something called page memory. This is a
technique to efficiently manage memory but it is also used as a security mechanism. Programs can be given
permissions to only certain regions of memory via page memory. However, this exact issue is not an issue with the
security but the size.&lt;/p&gt;
&lt;p&gt;The vast majority of users use x86 which utilizes 4k page memory. This size was great when page memory
was first introduced along with the Intel 386 in 1985. However, our memory sizes nowadays are vastly larger.
This means for a program to allocate something like 1GB of memory, they will need to ask the operating system
for a certain number of pages which gets them up to 1GB. On a 4k page size system, this would be about 244,141 pages
of memory. However, on a 16k page size system, this would be 61,036. Despite the math being 61035.15625, only whole pages
can be allocated. This means the memory allocator used will have to keep that last page for other memory allocations.
Between the 4k and 16k page sizes, it is clear that allocating a smaller number of pages can be beneficial when you
utilize programs that often are going to be allocating memory sizes beyond 1MB. This can result in a performance
improvement as there will be less work the CPU will have to do to ensure the program gets the correct number of pages.&lt;/p&gt;
&lt;p&gt;Due to Asahi Linux using 16k page size memory, this means programs not coded to expect a 16k page size will fail.
This is also true for the new Raspberry Pi 5 where the stock OS uses a 16k page size. A few notable programs which
break under the 16k page size are Zig, Wine, and Telegram. Telegram for one uses jemalloc which does not ask the
operating system for the page size and chooses to pick the size at build time. This causes breakage with prebuilt binaries
and distributed versions of the program like the Flatpak or an AppImage. Wine breaks due to it being a runtime environment
and so it has to mimick a Windows environment. Zig breaks due to the page size being a constant variable instead of a function,
it expects a 4k page size on any ARM system.&lt;/p&gt;
&lt;p&gt;Although many programs are broken due to the 16k page size on these modern systems, they will be patched.
Asahi Linux has a page on their wiki for &lt;a class=&#34;link&#34; href=&#34;https://github.com/AsahiLinux/docs/wiki/Broken-Software&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;broken software&lt;/a&gt; which
are often attributed to this exact issue. If you do find a piece of software which breaks due to this incompatibility, I can
heavily recommend you open an issue on that software&amp;rsquo;s issue tracker and link it to the Asahi Linux&amp;rsquo;s broken software page.
In due time, more systems will come out with 64-bit ARM CPU&amp;rsquo;s and many will likely use the 16k page size because of its
performance benefits. More broken software will be found but thanks to the developers or contributors, it will be fixed.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Commonifying LLVM in Nixpkgs</title>
        <link>https://tristanxr.com/post/commonifying-llvm-in-nixpkgs/</link>
        <pubDate>Sat, 08 Jun 2024 18:16:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/commonifying-llvm-in-nixpkgs/</guid>
        <description>&lt;p&gt;In programming, technical debt often accumulates over time. It often occurs with legacy code
or things which are not maintained often. Recently, I became one of the maintainers for
LLVM in Nixpkgs. With LLVM in Nixpkgs, I discovered there was some technical debt which could
limit the expansion of LLVM. This also would make it more difficult to package new
versions of LLVM. So as a maintainer of LLVM, I made the descision of refactoring all
of the version specific subpackage files for LLVM. This work was split up into 7 pull
requests and was known as the &amp;ldquo;commonification PR&amp;rsquo;s&amp;rdquo;. My goal was to reduce all the Nix
files responsible for the subpackages in LLVM for each version. This ended up making a
new directory in Nixpkgs inside of the LLVM specific one which ended up being called
&amp;ldquo;common&amp;rdquo;. Some of this work was already done by &lt;a class=&#34;link&#34; href=&#34;https://github.com/Artturin&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;@Artturin&lt;/a&gt;,
however my work involved every package in LLVM.&lt;/p&gt;
&lt;p&gt;Now you may be wondering how this was done. I had to figure out which things were common
between each package in LLVM across each version and limit certain things based on the
version. I ended up using a very useful tool called &lt;code&gt;nix-diff&lt;/code&gt; made by
&lt;a class=&#34;link&#34; href=&#34;https://github.com/Gabriella439&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;@Gabriella439&lt;/a&gt;. This tool allowed me to get the
differences between my local version of a package and the upstream. I used a very simple
wrapper script so I would only have to do something like
&lt;code&gt;nix-flake-diff.sh github:NixOS/nixpkgs#llvmPackages_18.clang .#llvmPackages_18.clang&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With the &lt;code&gt;nix-flake-diff.sh&lt;/code&gt; script, I was able to see how things deviated to prevent
Nix from rebuilding. Rebuilds were not acceptable as to prevent any unknown bugs from
cropping up and were out of the scope for this project. After 4 days, I was able to
reduce the number of files. Each pull request made for each specific LLVM package ended
up removing about 1,000 LoC and added under 400 LoC. This resulted in
a smaller number of files to manage. It also allows for easily applying changes across
all versions without touching other directories.&lt;/p&gt;
&lt;p&gt;Now that it has been more than a month since the pull requests for this project have
been merged, Nixpkgs is nearly ready for the next LLVM version. LLVM 19 will be easier
to package with the number of files to manage is a lot less. Another reason why LLVM 19
and future versions of LLVM will be much easier to package is because of consistent git
updating. I will cover what that entails in the future.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>The Beginning</title>
        <link>https://tristanxr.com/post/the-beginning/</link>
        <pubDate>Wed, 13 Dec 2023 16:40:00 +0800</pubDate>
        
        <guid>https://tristanxr.com/post/the-beginning/</guid>
        <description>&lt;img src="https://tristanxr.com/post/the-beginning/cover.jpg" alt="Featured image of post The Beginning" /&gt;&lt;p&gt;Hello, I am Tristan Ross. I&amp;rsquo;ve been a Linux user and programmer for over a decade now.
As 2023 is coming to a close and 2024 looms ever so closer, I&amp;rsquo;ve been reflecting on
the events in the past year. That has led me to the decision of redesigning my website
and adding a blog to it. My goal is for other fellow Linux users and programmers to
get an understanding of how I do things so they can be inspired. Another goal is for
future employers. As I have had been unsuccessful at getting a job after my previous
employment in tech, I believe having a blog could show for my skills until I complete
my bachelor&amp;rsquo;s degree.&lt;/p&gt;
&lt;p&gt;One major event I would like to reflect on here is my Japan trip. The cover photo of this
post is one I took of a shrine in Kyoto during my two-week vacation. I started my trip
by leaving from LAX and landing in NRT. I took Japan Airlines and it was the best airline
service I had taken other than Alaska. I got to experience many things that I had been
looking forward to. A few of the favorites are the Gundam in Yokohama, Gundam Base, walking
around Akihabara, taking the Shinkansen (bullet train), and staying at a Ryokan (traditional
Japanese inn). I might make a post at a later date further reflecting on this particular trip.&lt;/p&gt;
&lt;p&gt;Between my Japan trip and now, not too much has occurred. I&amp;rsquo;ve been continuing to work on ExpidusOS
and progressing towards getting my associates degree. Though, I did get a refurbished 2021 Macbook
Pro M1 Pro. I decided to then install NixOS which caused me to land on &lt;a class=&#34;link&#34; href=&#34;https://github.com/tpwrules&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;@tpwrules&lt;/a&gt;&amp;rsquo;s
&lt;a class=&#34;link&#34; href=&#34;https://github.com/tpwrules/nixos-apple-silicon&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;nixo-apple-silicon&lt;/a&gt; Flake. I may make future posts here about
my experience with Apple Silicon and even a guide to installing NixOS to your own Apple Silicon device.&lt;/p&gt;
&lt;p&gt;Anyway, that&amp;rsquo;s it for the first post to this website. I&amp;rsquo;ll leave you off with a photo of one of my cats.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://tristanxr.com/post/the-beginning/cat.jpg&#34;
	width=&#34;3072&#34;
	height=&#34;4080&#34;
	srcset=&#34;https://tristanxr.com/post/the-beginning/cat_hu1445226326038273472.jpg 480w, https://tristanxr.com/post/the-beginning/cat_hu6517393243140489275.jpg 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;Autumn&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;75&#34;
		data-flex-basis=&#34;180px&#34;
	
&gt;&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
