[HN Gopher] Minimal x86 Kernel Zig
       ___________________________________________________________________
        
       Minimal x86 Kernel Zig
        
       Author : lopespm
       Score  : 142 points
       Date   : 2026-02-18 00:02 UTC (22 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | ajxs wrote:
       | See also: https://wiki.osdev.org/Zig_Bare_Bones
        
         | anta40 wrote:
         | Both tutorials work fine on latest stable zig (0.15.2)
        
         | xx__yy wrote:
         | Thanks for sharing
        
       | csense wrote:
       | Very neat. To clarify, Qemu can boot it, but I'm pretty sure you
       | need some bootloader (e.g. Grub) to boot it on a physical system.
        
         | toast0 wrote:
         | Looks like it's multiboot compliant, so you can pick your
         | favorite multiboot loader. ipxe, grub, pretty sure there's some
         | other ones out there.
         | 
         | As it's multiboot, it should likely run on v86 too. It's always
         | fun to have an in browser demo of a little OS like this.
        
         | flopsamjetsam wrote:
         | From the GitHub page:
         | 
         | > It boots on an x86 (i386) machine via the Multiboot 1
         | protocol
         | 
         | Yes, it does need a compliant bootloader on virtual or physical
         | hardware.
        
         | anta40 wrote:
         | If you want to use Grub, this tutorial works (see "Booting the
         | kernel"):
         | 
         | https://wiki.osdev.org/Zig_Bare_Bones
         | 
         | Yes, just tried it.
        
       | throwaway27448 wrote:
       | Why choose intel? Let's build bootable software in 2026
        
         | xx__yy wrote:
         | I'm not that cluey, but from the README it sounds like it can
         | be compiled for a bunch of arches
        
           | asQuirreL wrote:
           | It can be (cross-)compiled on whatever architectures the Zig
           | compiler is available for, but the source contains inline x86
           | assembly, so you're not going to be able to build this for
           | ARM or RISC-V.
        
             | mghackerlady wrote:
             | For how short it is, it would be trivially easy to
             | translate the instructions into whatever flavor of CPU made
             | in the past 25 years or so
        
       | xx__yy wrote:
       | Gold! I see Zig, I upvote!
        
         | smallstepforman wrote:
         | Well, in the real world we need at least polymorphism and
         | operator overloading, but that is against the core Zig
         | philosophy, so serious GameDev ignores it (which ironically one
         | would think is the biggest core market for low level systems
         | programming). Hence why new GameDev development still chooses
         | C++, and Andrew's project fails to gain a significant boost in
         | users.
        
           | flohofwoe wrote:
           | > in the real world we need at least polymorphism and
           | operator overloading
           | 
           | Maybe in _your_ real-world ;)
           | 
           | Building your game code around classes with virtual methods
           | has been a bad idea since at least the early 2000s (but both
           | static and dynamic polymorphism is something that Zig can do
           | just fine when needed), and the only important use case for
           | operator overloading in game-dev is vector/matrix math, where
           | Zig is going down a different road (using builting vector
           | types, which maybe one day will be extended with a builtin
           | matrix type - there is some interest in using Zig for GPU
           | code, and at least this use cases will require proper
           | vector/matrix primitives - but not operator overloading).
        
           | mghackerlady wrote:
           | >polymorphism and operator overloading
           | 
           | Gee, this new C language and UNIX operating system sure seem
           | cool but someone ought to tell those poor people at bell labs
           | that they'll never catch on without them
        
       | drnick1 wrote:
       | What's the point of doing this in "Zig" instead of C, the
       | traditional choice for this kind of thing?
        
         | mitchellh wrote:
         | Fun?
        
           | nickmonad wrote:
           | Not allowed.
        
         | toast0 wrote:
         | Because you can is a pretty traditional reason.
         | 
         | Zig is supposed to be an improvement upon C, so doing C things
         | with it seems reasonable.
         | 
         | Kind of neat that there's no need for a separate assembly file
         | although there is inline assembly. Might get better (or worse)
         | syntax support for separate assembly files? But it doesn't make
         | a big difference until there's more features that need it
         | (interrupts, threads/processes and maintaining their stacks,
         | syscalls, starting other processors, etc)
        
         | 6r17 wrote:
         | What's the point writing another kernel in C ???
        
           | lelanthran wrote:
           | Considering that we are talking about experimental toys which
           | have lower odds of seeing production than of you winning a
           | national lottery jackpot, the point of writing it in C would
           | be the same as the point of writing it in anything else -
           | IOW, the kernel is the objective, not the language used to
           | write it.
           | 
           | .
        
             | mghackerlady wrote:
             | Yeah, but even if I'm doing something for fun I do want to
             | be a bit unique with it. Anyone who's interested enough in
             | osdev to build something for baremetal has at least
             | attempted a unix-like kernel in C
        
             | 6r17 wrote:
             | If you read yourself you'll realize your answer i highly
             | toxic, quiet honestly completely irrelevant, discouraging
             | other people from doing what they like. I would get rid of
             | people with your attitude, you are the kind of problem I
             | don't want to have to deal with and more than that, I don't
             | want to have juniors have to deal with you. Please realize
             | that you had your chance and you played it. Nobody ow you
             | an explanation if you can't even get basics up.
        
               | SpecialistK wrote:
               | What in the sweet chili dipping sauce did I walk into?
               | 
               | drnick1 says why "Zig" not C? [I took the quotation marks
               | as dismissive of Zig, but I could be misreading that]
               | 
               | 6r17 says why do it in C?
               | 
               | lelanthran says the language is mostly irrelevant, it's a
               | fun experiment.
               | 
               | 6r17 blows off the handle and starts calling people toxic
               | and being really unpleasant.
               | 
               | Nothing in this comment chain seems to justify even
               | 1/10th of the vitriol espoused.
        
         | pmarreck wrote:
         | because Zig is simply a better C, often faster (normally at
         | least as fast), but with way more safety guarantees or at least
         | things preventing the vast majority of traditional C footguns
         | from happening
        
           | bjourne wrote:
           | Zig is not faster than C.
        
             | lionkor wrote:
             | Would you say its always slower, or always faster?
        
               | flohofwoe wrote:
               | The optimization work happens in the LLVM backend, so in
               | most cases (and using the same optimization and target
               | settings - which is an important detail, because by
               | default Zig uses more aggressive optimization options
               | than Clang), similar Zig and C code translates to the
               | exact same machine code (when using Clang to build the C
               | code).
               | 
               | The same should be true for any compiled language sitting
               | on top of LLVM btw, not just C vs Zig.
        
               | bjourne wrote:
               | No. I will continue my crusade against blanket statements
               | about performance.
        
               | pmarreck wrote:
               | Gee, good thing I didn't make a blanket statement and
               | qualified it by saying "often", which is true, my
               | contrarian dude. https://tigerbeetle.com wouldn't have
               | chosen it unless they found it faster than C- and there's
               | a significant quantity of money riding on that decision,
               | so it likely wasn't done lightly _at all_.
               | 
               | The rest, you can google yourself, but in short, sorry to
               | tell you that it is sometimes faster. Often, sometimes,
               | _some portion of the time_.
        
             | flohofwoe wrote:
             | With default build settings it actually might be, because
             | Zig's release mode builds with the equivalent of
             | `-march=native` by default ;)
             | 
             | (disclaimer: not sure if that's actually still the case,
             | last I checked in detail was probably 2 years ago).
             | 
             | Also Zig always builds the entire project as a single
             | compilation unit, which allows more optimization options
             | because the compiler sees all function bodies. The closest
             | equivalent in the C world is LTO, but this is usually also
             | not enabled by default.
        
         | jandrewrogers wrote:
         | Zig is essentially a substantially improved and enhanced C,
         | both in character and intent. There is a lot to recommend it
         | for applications where you might otherwise use C.
        
         | moonlion_eth wrote:
         | because zig is lower level than c
        
         | kunley wrote:
         | I guess one of good reasons is easy cross-compilation.
         | 
         | But also, I can see some amount of weird hooray optimism in
         | this project, like: totally confusing claim that the thing is
         | bare metal when it's still being run under an emulator; also,
         | calling it a kernel is a huge overstatement
        
         | flohofwoe wrote:
         | In this case, better tooling and consistency. E.g. the small
         | block of inline assembly would already be trouble for some C
         | compilers.
        
         | AndyKelley wrote:
         | bitpacked structs, good enums, arbitrary sized integers,
         | optionals + non-nullable pointers, fast compiler, zig fmt, unit
         | testing, ability to use standard library and the rest of the
         | third-party ecosystem on freestanding, std.ArrayList,
         | std.AutoArrayHashMap, std.MultiArrayList, std.crypto, more
         | productive type system, comptime, SIMD, slices, labeled switch
         | continue, error handling, custom panic handler, stack traces on
         | freestanding, error return traces, zero bit types, the build
         | system, package management, aligned pointers, untagged union
         | safety, multi-object for loops, inline switch cases,
         | semantically guaranteed inline functions, inline loops
        
         | kennykartman wrote:
         | Because Zig is the future, Rust has clearly failed and C is
         | simply obsolete in 2026. The rest doesn't even matter.
        
       | 6r17 wrote:
       | I'm very surprised it's *that* short - handling one in rust i'm
       | surprised by the very low amount of code to get that up. Thanks
       | or sharing that was a first time reading some Zig for me !
        
         | pmarreck wrote:
         | what you're experiencing is more or less why I am building some
         | stuff in Zig instead of Rust
        
           | simonask wrote:
           | Looking at the code, I'm not really sure what part of this
           | would be more verbose in Rust. This kernel does close to
           | nothing, not even page table setup.
           | 
           | Granted, the code writing to the VGA buffer will need to be
           | in `unsafe` blocks, but yeah.
        
       | aryalaadi wrote:
       | thats not a kernel
        
         | benatkin wrote:
         | Indeed, it's freestanding, the repo name doesn't have the
         | correct term, but the source file does near the end:
         | https://github.com/lopespm/zig-minimal-kernel-x86/blob/main/...
         | 
         | Also baremetal where the metal is virtual. LLVM uses this term
         | for when an OS isn't available https://github.com/llvm/llvm-
         | project/tree/main/libc/src/stdl...
        
           | aryalaadi wrote:
           | I think calling baremetal software a kernel keeps a bad
           | impression on people just starting out, you can do alot with
           | baremetal and it does not have to be a kernel
        
       | messe wrote:
       | Minimal slop.
        
       | WD-42 wrote:
       | Here's one for Risc-V that's a little more fleshed out, also in
       | Zig: https://github.com/Fingel/aeros-v/blob/main/src/kernel.zig
        
       | gethly wrote:
       | wtf? 10 lines of hello world code is not a kernel.
        
       | kunley wrote:
       | Why to spread confusion and call it bare metal when it's run
       | under QEMU? Then it's not bare metal at all.
       | 
       | In order to be run on bare metal it's needing another bootloader
       | which the documentation only barely mentions.
       | 
       | More on the naming: why to call it kernel?
        
         | cies wrote:
         | I agree, I'd not call this a kernel. It does not allow any
         | software to be run on top of it. It just prints text to screen
         | and halts.
         | 
         | Even saying it "runs" on QEMU is a far stretch: it "halts",
         | that's all it does. :)
         | 
         | (it does run on hardware as per other commenters in this HN
         | convo)
        
           | kunley wrote:
           | Ok, I am not saying it doesn't run on hardware, but the
           | primary example runs (for the somehow stretched definition of
           | "run", as you say) on QEMU but displays a message that it's
           | bare metal.
           | 
           | Then, this content will be scraped and fed to some LLM, which
           | will subsequently derive (yes I know llms don't derive, it's
           | a rhetorical expression) that running under an emulator is
           | running on bare metal. Confusion for the masses! (Not to
           | mention confusion for a reader already now)
        
             | cies wrote:
             | It does not "run" anything: it halts. :)
        
         | lelanthran wrote:
         | > In order to be run on bare metal it's needing another
         | bootloader which the documentation only barely mentions.
         | 
         | Maybe it's an in-group vs out-group thing: those in the group
         | (i.e. have attempted this in the past) _don 't care_ about what
         | the first stage bootloader is; you'll just use some existing
         | bootloader (I used grub).
         | 
         | If you're in the out-group, you feel cheated that you still
         | need a bootloader.
        
         | eddd-ddde wrote:
         | You still need a bootloader to run the Linux kernel.
        
           | vluft wrote:
           | well, not with efistub, at least, depending on how you define
           | bootloader.
        
         | toast0 wrote:
         | Almost every OS needs a bootloader; but not every OS needs to
         | develop one. Certainly there's some exceptions where there's
         | not really separation between the two functions, but it's not
         | common and most hobby OSes have the distinction unless they're
         | single sector OSes.
         | 
         | The booloader and the kernel are separate stages; they're both
         | interesting, but pick the part that interests you and work on
         | that. With the multiboot standard and existing loaders like
         | ipxe and grub, if you want to write a kernel, there's no need
         | to write your own bootloader.
         | 
         | Otoh, if you want to write your own bootloader, you can do that
         | too, there's plenty of existing kernels to boot.
         | 
         | And yeah, this kernel does nothing. But it would be a
         | reasonable start to a kernel that does things, although you
         | would need to write all the things.
         | 
         | Bare metal in qemu is a little fishy, but it's easier to take a
         | screenshot of qemu than to take a screenshot of a full
         | computer. I would expect this to run on a full computer as long
         | as it supports BIOS booting, and then it would be a bare metal
         | boot and halt kernel.
        
       | boricj wrote:
       | I wrote something similar a while ago:
       | https://github.com/boricj/hang-os
       | 
       | It handles interrupts/traps and targets the aarch64 QEMU virt
       | platform. It also features a HAL.
        
       ___________________________________________________________________
       (page generated 2026-02-18 23:02 UTC)