Hi, author here! I've just finished writing the pre-emptive multitasking [0](only round robbin though, nothing fancy).

I'm currently writing an ATA driver [1], the idea is to implement ext2.

I used to do this in Rust but I switched to zig for maintainability and readability over Rust. It seems that with `comptime` I'm able to make a lot of things optimal.

Overall I have to say kernel programming is _hard_ but very rewarding when it finally works, it's really demystifying computers for me!

[0] https://wiki.osdev.org/Brendan%27s_Multi-tasking_Tutorial

[1] https://wiki.osdev.org/IDE

> I used to do this in Rust but I switched to zig for maintainability and readability over Rust.

Can you expand on this ? I'm asking out of curiosity because I want to learn a "system" programming language (for whatever definition there is to this term). So far I briefly tried Rust and Nim and found the former more difficult to read. I know nothing about Zig, how would you place it between these two ?

In general you'll find that zig is easier to read than Rust (see the first version of this project in Rust [0]) because it's a simpler language. For kernel programming this is even more so the case:

* zig has native support for arbitrary sized integers. In Rust I used to do bitshifts, Now I just have a packed struct of u3/u5/u7 whatever (see `src/pci/pci.zig`). Of course Rust has a bitflags crate but I didn't find it handy, this is a case where native support vs library support means a world of difference.

* zig has native support for freestanding target. I used to have to build with Xargo for cross compiling to a custom target, I also was forced to `[nostd]`, and some features I was using forced me to use nightly Rust. In zig I have a simple `build.zig` and a simple `linker.ld` script, just works.

* zig has nicer pointer handling. A lot of kernel programming is stuff that Rust considers unsafe anyway. It's not uncommon to have to write lines like `unsafe { (ptr as const u8) }` to deref a pointer in Rust, which is a pain because this kind of thing happens all of the time. Also you have to play around with mut a lot like this: `unsafe { &mut (address as mut _)`. It just felt wrong a lot of the time, where in zig you have either `const` or `var` and that's the end of it.

* zig is really fun to write! this is something that comes up often in the community, after years of C it's just very refreshing.

Some things zig is missing:

* Package manager, this is coming soon. [1]

* Missing documentation for inline assembly (I think this part is going to get overhauled, as Andrew Kelley is writing an assembler in zig atm [2]).

I don't know Nim, but I believe it has a garbage collector so it could be tricky to use for kernel programming.

[0] https://github.com/jzck/kernel-rs

[1] https://github.com/ziglang/zig/issues/943

[2] https://www.youtube.com/watch?v=iWRrkuFCYXQ

You can certainly use Nim for kernels. I've created a proof of concept long ago, and things are only improving with ARC fast becoming a great alternative to Nim's GC.

https://github.com/dom96/nimkernel