<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Systems on</title><link>/tags/systems/</link><description>Recent content in Systems on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 08 Aug 2025 09:33:27 +0000</lastBuildDate><atom:link href="/tags/systems/index.xml" rel="self" type="application/rss+xml"/><item><title>Lesson 12: Production Systems Software — Databases, runtimes, proxies</title><link>/post/rust/rust-sys-production-systems/</link><pubDate>Fri, 08 Aug 2025 09:33:27 +0000</pubDate><guid>/post/rust/rust-sys-production-systems/</guid><description>&lt;p&gt;I&amp;rsquo;ve been building systems software professionally for a while now, and here&amp;rsquo;s what I&amp;rsquo;ve noticed: the skills we&amp;rsquo;ve covered in this course — &lt;code&gt;no_std&lt;/code&gt; programming, memory-mapped I/O, custom allocators, interrupt handlers, network protocols — they all converge when you build production systems software. A database engine is just a file system on top of a storage engine with a query processor. A network proxy is packet parsing plus connection management. A language runtime is memory management plus a scheduler.&lt;/p&gt;</description></item><item><title>Lesson 11: Building a Minimal Hypervisor — Virtualization in Rust</title><link>/post/rust/rust-sys-hypervisor/</link><pubDate>Mon, 04 Aug 2025 15:42:18 +0000</pubDate><guid>/post/rust/rust-sys-hypervisor/</guid><description>&lt;p&gt;The first time I watched a virtual machine boot — not using VirtualBox, but running inside a hypervisor &lt;em&gt;I&amp;rsquo;d written&lt;/em&gt; — I had the same feeling as when my bootloader printed its first character. Except this time, I wasn&amp;rsquo;t just running code on bare metal. I was creating a &lt;em&gt;fake machine&lt;/em&gt; that thought it was running on bare metal.&lt;/p&gt;
&lt;p&gt;Virtualization is where systems programming hits its ceiling of complexity. You&amp;rsquo;re manipulating the CPU&amp;rsquo;s hardware virtualization extensions to create isolated execution environments. It&amp;rsquo;s also where Rust&amp;rsquo;s safety guarantees become most valuable — because a bug in a hypervisor doesn&amp;rsquo;t just crash your program, it potentially compromises every virtual machine running on the host.&lt;/p&gt;</description></item><item><title>Lesson 10: Writing a Bootloader — The first code that runs</title><link>/post/rust/rust-sys-bootloader/</link><pubDate>Fri, 01 Aug 2025 22:10:44 +0000</pubDate><guid>/post/rust/rust-sys-bootloader/</guid><description>&lt;p&gt;There&amp;rsquo;s something almost spiritual about writing a bootloader. Your code is the &lt;em&gt;first thing that runs&lt;/em&gt; on a machine. Before the OS. Before any drivers. Before the memory manager. Before anything. The CPU comes out of reset, fetches an instruction from a known address, and that instruction is yours.&lt;/p&gt;
&lt;p&gt;I spent a weekend writing one. By Sunday night, I had four characters on screen — &lt;code&gt;BOOT&lt;/code&gt; — rendered by writing directly to VGA memory. And it felt like I&amp;rsquo;d conquered the world.&lt;/p&gt;</description></item><item><title>Lesson 9: Interrupt Handlers and Real-Time Constraints — When timing matters</title><link>/post/rust/rust-sys-interrupt-handlers/</link><pubDate>Wed, 30 Jul 2025 06:55:22 +0000</pubDate><guid>/post/rust/rust-sys-interrupt-handlers/</guid><description>&lt;p&gt;I once spent three days debugging a motor controller that would randomly twitch. The code was correct. The hardware was fine. The interrupt handler was well-written. But every few thousand cycles, a timer interrupt would preempt the motor control interrupt at exactly the wrong moment, corrupting a shared variable. The fix was two lines of code — disable interrupts around the critical section — but finding it cost me a weekend.&lt;/p&gt;</description></item><item><title>Lesson 8: Designing Custom Allocators — Beyond the global allocator</title><link>/post/rust/rust-sys-allocator-design/</link><pubDate>Sun, 27 Jul 2025 13:19:56 +0000</pubDate><guid>/post/rust/rust-sys-allocator-design/</guid><description>&lt;p&gt;Here&amp;rsquo;s a dirty secret of systems programming: &lt;code&gt;malloc&lt;/code&gt; is not magic. It&amp;rsquo;s just code. Code that somebody wrote, code that makes tradeoffs, and code you can replace when those tradeoffs don&amp;rsquo;t match your workload.&lt;/p&gt;
&lt;p&gt;I spent two years writing performance-sensitive Rust before I realized that the global allocator was my bottleneck. Not CPU. Not I/O. Memory allocation — thousands of tiny allocations per request, each one hitting a lock, each one fragmenting the heap a little more. Switching to a bump allocator for request-scoped data cut latency by 40%.&lt;/p&gt;</description></item><item><title>Lesson 7: Implementing Network Protocols — TCP from scratch</title><link>/post/rust/rust-sys-network-stack/</link><pubDate>Thu, 24 Jul 2025 10:31:48 +0000</pubDate><guid>/post/rust/rust-sys-network-stack/</guid><description>&lt;p&gt;I thought I understood TCP until I tried to implement it. Turns out, &amp;ldquo;client connects to server, data flows&amp;rdquo; is about 5% of the story. The other 95% is state machines, retransmission timers, congestion windows, and edge cases that would make your head spin.&lt;/p&gt;
&lt;p&gt;But here&amp;rsquo;s the good news: implementing even a simplified TCP teaches you more about networking than any textbook. And Rust&amp;rsquo;s type system is actually perfect for modeling protocol state machines — states become types, invalid transitions become compile errors.&lt;/p&gt;</description></item><item><title>Lesson 6: Building a File System — From blocks to files</title><link>/post/rust/rust-sys-file-systems/</link><pubDate>Tue, 22 Jul 2025 16:08:32 +0000</pubDate><guid>/post/rust/rust-sys-file-systems/</guid><description>&lt;p&gt;The moment a file system clicked for me was when I stopped thinking of files as &amp;ldquo;things on disk&amp;rdquo; and started thinking of them as &amp;ldquo;names mapped to byte ranges scattered across a block device.&amp;rdquo; That sounds more complicated, but it&amp;rsquo;s actually simpler — because now there&amp;rsquo;s no magic. Just data structures.&lt;/p&gt;
&lt;p&gt;Every file system, from FAT16 to ZFS, answers the same fundamental questions: Where does this file&amp;rsquo;s data live on disk? How do I find a file by name? What metadata (size, permissions, timestamps) does each file have? Let&amp;rsquo;s answer all of these by building one from scratch.&lt;/p&gt;</description></item><item><title>Lesson 5: OS Concepts in Rust — Processes, threads, signals</title><link>/post/rust/rust-sys-os-concepts/</link><pubDate>Sat, 19 Jul 2025 07:45:19 +0000</pubDate><guid>/post/rust/rust-sys-os-concepts/</guid><description>&lt;p&gt;I used to think I understood processes. Then I tried to implement &lt;code&gt;fork()&lt;/code&gt; semantics in Rust and realized I&amp;rsquo;d been cargo-culting UNIX concepts for years without actually understanding what was happening underneath.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the thing — Rust forces you to think about OS primitives more carefully than C ever did. The ownership model doesn&amp;rsquo;t just prevent memory bugs; it makes you confront questions like &amp;ldquo;who owns a file descriptor?&amp;rdquo; and &amp;ldquo;what happens to shared memory after fork?&amp;rdquo; that C lets you handwave past.&lt;/p&gt;</description></item><item><title>Lesson 4: Writing Linux Kernel Modules in Rust — Rust in the kernel</title><link>/post/rust/rust-sys-kernel-modules/</link><pubDate>Thu, 17 Jul 2025 11:23:45 +0000</pubDate><guid>/post/rust/rust-sys-kernel-modules/</guid><description>&lt;p&gt;In December 2022, Rust officially merged into the Linux kernel source tree. Not as an experiment. Not as a sidecar. As a first-class language for writing kernel code. Linus Torvalds signed off on it.&lt;/p&gt;
&lt;p&gt;I remember reading the mailing list thread and thinking: &amp;ldquo;This is either going to be the most important thing to happen to systems programming in twenty years, or the most spectacular failure.&amp;rdquo; Three years in, it&amp;rsquo;s looking a lot like the former.&lt;/p&gt;</description></item><item><title>Lesson 3: Memory-Mapped I/O — Talking to hardware</title><link>/post/rust/rust-sys-memory-mapped-io/</link><pubDate>Mon, 14 Jul 2025 19:52:07 +0000</pubDate><guid>/post/rust/rust-sys-memory-mapped-io/</guid><description>&lt;p&gt;There&amp;rsquo;s a moment in every systems programmer&amp;rsquo;s life when they realize that writing to memory address &lt;code&gt;0x4002_0818&lt;/code&gt; doesn&amp;rsquo;t store a value — it turns on an LED. That address isn&amp;rsquo;t RAM. It&amp;rsquo;s a hardware register. And the CPU doesn&amp;rsquo;t know the difference.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s memory-mapped I/O in a nutshell, and it&amp;rsquo;s how virtually all hardware communication works on modern processors. Understanding it properly is the difference between code that happens to work and code that&amp;rsquo;s &lt;em&gt;correct&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>Lesson 2: Embedded Rust — Microcontrollers and bare metal</title><link>/post/rust/rust-sys-embedded-intro/</link><pubDate>Sat, 12 Jul 2025 14:37:51 +0000</pubDate><guid>/post/rust/rust-sys-embedded-intro/</guid><description>&lt;p&gt;I bricked my first development board within forty-five minutes of getting it out of the box. Wrote some C code, forgot to configure the clock properly, flashed it, and the thing just&amp;hellip; stopped responding. No debugger connection. No serial output. A $15 paperweight.&lt;/p&gt;
&lt;p&gt;That experience — the raw, unforgiving nature of hardware programming — is exactly why Rust matters in embedded. Not because it prevents you from writing to the wrong register (it can&amp;rsquo;t, really), but because it gives you tools to &lt;em&gt;structure&lt;/em&gt; hardware access so mistakes become harder to make.&lt;/p&gt;</description></item><item><title>Lesson 1: no_std — Rust without the standard library</title><link>/post/rust/rust-sys-no-std/</link><pubDate>Thu, 10 Jul 2025 08:14:33 +0000</pubDate><guid>/post/rust/rust-sys-no-std/</guid><description>&lt;p&gt;The first time I tried to compile a Rust program with &lt;code&gt;#![no_std]&lt;/code&gt;, I felt like someone had pulled the floor out from under me. No &lt;code&gt;println!&lt;/code&gt;. No &lt;code&gt;String&lt;/code&gt;. No &lt;code&gt;Vec&lt;/code&gt;. No &lt;code&gt;HashMap&lt;/code&gt;. Half the stuff I relied on daily — just &lt;em&gt;gone&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s exactly the point.&lt;/p&gt;
&lt;h2 id="why-would-anyone-do-this"&gt;Why Would Anyone Do This?&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s the thing most Rust tutorials won&amp;rsquo;t tell you up front: the standard library is &lt;em&gt;enormous&lt;/em&gt;. It pulls in heap allocation, threading, file I/O, networking, and a whole OS-level runtime. That&amp;rsquo;s great for application development. It&amp;rsquo;s a non-starter for:&lt;/p&gt;</description></item><item><title>Lesson 2: CGo Performance and Pitfalls — The hidden cost of crossing the boundary</title><link>/post/go/go-cgo-performance/</link><pubDate>Thu, 24 Oct 2024 00:00:00 +0000</pubDate><guid>/post/go/go-cgo-performance/</guid><description>&lt;p&gt;When I profiled a service that was spending 40% of its time in cgo calls, I thought I was measuring the C library. I was not. I was measuring the overhead of &lt;em&gt;getting to&lt;/em&gt; the C library. The actual C work was fast. What was slow was the goroutine-to-OS-thread transition, the stack switching, and the runtime bookkeeping that happens every single time Go code crosses the C boundary. Understanding this overhead is what separates cgo code that runs fine from cgo code that becomes a bottleneck.&lt;/p&gt;</description></item><item><title>Lesson 1: CGo Basics — When you need C and how to call it safely</title><link>/post/go/go-cgo-basics/</link><pubDate>Mon, 22 Jul 2024 00:00:00 +0000</pubDate><guid>/post/go/go-cgo-basics/</guid><description>&lt;p&gt;There is a saying in the Go community: &amp;ldquo;cgo is not Go.&amp;rdquo; It is not an insult. It is a warning. The moment you add &lt;code&gt;import &amp;quot;C&amp;quot;&lt;/code&gt; to a file, you are no longer writing a pure Go program — you are writing a Go program that manages a C boundary, and all the things that make Go comfortable (fast builds, easy cross-compilation, the race detector, straightforward stack traces) become harder. You are doing it on purpose, because the alternative is worse.&lt;/p&gt;</description></item></channel></rss>