HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
matheusmoreira
liblinux
Rust2020–2026
matheusmoreira / liblinux

liblinux

Linux system calls in Rust

4Distinct people
22Mentions
0Explicit recommenders
4GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Linux system calls in Rust

GitHub

Where it is used

The source check is incomplete. Verified examples will appear here.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year22 dated mentions

Observed mentions: 2020-03-26 18:52:45 UTC to 2026-08-19 13:28:30 UTC.

02468102020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 9 mentions; 1 submissions, 8 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments20232024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC303
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC918
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC404
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC413
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC101

What Hacker News says

22 sources
> Hardly anything is written against the kernel ABI except glibc itself. I'm working hard to change that. Here's an entire lisp interpreter written in freestanding C using nothing but Linux system calls: https://github.com/lone-lang/lone It has a system-call primitive too, which means it can do anything. Here's a TCP echo server written in lone lisp: https://github.com/lone-lang/lone/blob/master/examples/tcp-e... It works, and you don't need libc. > Like it or not, glibc is the singular entry point for desktop Linux Well I don't like it, and I've made it my mission to fix it. Maybe lisp isn't the answer, Rust is. I've revived my liblinux crate too. https://github.com/matheusmoreira/liblinux I'm going to add system calls to this thing every day until I have every single one. Then I'll use them to make all of my applications. Already have m
Read the rest
y first project planned: a custom Rust network stack for my QEMU virtual machines so I can firewall them off in userspace without root access. > the Linux platform The linux platform is these system calls. Everything else is userspace. This is exactly what makes it special. https://www.matheusmoreira.com/articles/linux-system-calls
In Solo – a .so loader for static Linux binaries
Hacking this stuff is so fun!! > Depending on your program, _start may be the only thing between the entrypoint and your main function I once developed a liblinux project entirely built around this idea. I wanted to get rid of libc and all of its initialization, complexity and global state. The C library is so complex it has a primitive form of package management built into it: https://blogs.oracle.com/solaris/post/init-and-fini-processi... So I made _start functions which did nothing but pass argc, argv, envp and auxv to the actual main function: https://github.com/matheusmoreira/liblinux/blob/master/start... https://github.com/matheusmoreira/liblinux/blob/master/start... You can get surprisingly far with just this, and it's actually possible to understand what's going on. Biggest pain point was the lack of C library utility functions li
Read the rest
ke number/string conversion. I simply wrote my own. https://github.com/matheusmoreira/liblinux/tree/master/examp... Linux is the only operating system that lets us do this. In other systems, the C library is part of the kernel interface. Bypassing it like this can and does break things. Go developers once discovered this the hard way. https://www.matheusmoreira.com/articles/linux-system-calls The kernel has their own nolibc infrastructure now, no doubt much better than my project. https://github.com/torvalds/linux/tree/master/tools/include/... I encourage everyone to use it. Note also that _start is an arbitrary symbol. The name is not special at all. It's just some linker default. The ELF header contains a pointer to the entry point, not a symbol. Feel free to choose a nice name!
In The Journey Before main()
> My day-to-day job that actually pays me a salary wouldn't ever provide a bulleted list of the reasons I suck, let alone a project I develop in my spare time. The questions you received were: > Can we expect development from the maintainer? > How can the community support? > Are you open to PRs and reviewing them? > What's your time commitment? > Should someone just fork the repo and develop it from there? This is far from a "bulleted list of the reasons I suck". Whoever asked this cared about your project and its future. They just wanted to know what was going on. They might have been intending to contribute patches to you: they specically asked if you were accepting pull requests for review. It's extremely frustrating when you send a patch in and don't get a response. This was my approach when I received similar questions: https://gith
Read the rest
ub.com/matheusmoreira/liblinux/issues/16 I think it's better to just be sincere and provide the necessary context.
In Please Don't Ask If an Open Source Project Is Dead
> libc isn't really getting in the way here. It depends. For the standard set of system calls, the libc is pretty great. For Linux-specific features, it could take years for glibc to gain support, if it ever does. All the libcs will get in the way if you try to use something like the clone system call: https://sourceware.org/bugzilla/show_bug.cgi?id=10311 > Ulrich Drepper 2009-06-22 19:35:54 UTC > If you use clone() you're on your own. My obsession with Linux system calls started years ago when I read about an episode where glibc literally got into Linux's way. The LWN wrote extensively about the tale of the getrandom system call and the quest to get glibc to support it: https://lwn.net/Articles/711013/ A kernel hacker wrote in an email: > maybe the kernel developers should support a libinux.a library that would allow us to bypass glibc w
Read the rest
hen they are being non-helpful That made a lot of sense to me. I took that concept and kind of ran with it. Started a liblinux project, essentially a libc with nothing in it but the thinnest possible system call wrappers. Researched quite a bit about glibc's attitude towards Linux to justify it: https://github.com/matheusmoreira/liblinux#why The more I used this stuff, the more I enjoyed it. I was writing freestanding C and interfacing directly with the kernel. The code was so clean. No libc baggage anywhere, not even errno. And I knew this could do literally anything when I wrote a little freestanding program to print my terminal window dimensions. When I did that I knew I could write code to mount disks too if I really wanted to. I was talking to the kernel. Eventually I discovered Linux was already doing the same thing with their own nolibc.h file which they were already using in their own tools. It was a single file back then, by now it's become a sprawling directory full of code: https://github.com/torvalds/linux/tree/master/tools/include/... Even asked Greg Kroah-Hartman on reddit about it once: https://old.reddit.com/r/linux/comments/fx5e4v/im_greg_kroah... Since the kernel was already developing their own awesome headers, I decided to drop liblinux and start lone instead. :)
In A standalone zero-dependency Lisp for Linux
> Now, do I think it would make total sense for syscall wrappers and NSS to be split into their own libs (or dbus interfaces maybe) with stable ABIs to enable other libc's, absolutely! I worked on this a few years ago: liblinux. https://github.com/matheusmoreira/liblinux It's still a nice proof of concept but I abandoned it when I found out the Linux kernel itself has a superior nolibc library that they use for their own tools: https://github.com/torvalds/linux/tree/master/tools/include/... It used to be a single header but it looks like they've recently organized it into a proper project! > This is something the BSD's got absolutely right. BSDs and all the other operating systems force us to use their C libraries and the C ABI. I think Linux's approach is better. It has a language-agnostic system call binary interface: it's just a simple
Read the rest
calling convention and the system call instruction. The right place for system call support is the compiler. We should have a system_call keyword that makes it emit code in the aforementioned calling convention. With this single keyword, it's possible to do literally anything on Linux. Wrappers for every specific system call should be part of every language's standard library with language-specific types and semantics. An example of one such language is Virgil by HN used titzer: https://news.ycombinator.com/item?id=28283632
In Win32 Is the Only Stable ABI on Linux?
I'm not using this stuff professionally, it's just my own home lab's virtual machines with little services implemented as freestanding C programs. Not doing anything fancy right now, much of it was just to see if I could do it. I've seen other people commenting here on HN saying they're using the same approach in production so it's defenitely not my invention. Hopefully they'll see this thread and reply. I published some of my work in the form of a liblinux that I use to make system calls: https://github.com/matheusmoreira/liblinux I'm not developing it anymore though because I found out the kernel itself has a superior nolibc library: https://github.com/torvalds/linux/tree/master/tools/include/... It used to be a single header but it looks like they've recently organized it into a proper project! I wonder if it will become some kind of o
Read the rest
fficial kernel library at some point. I asked Greg Kroah-Hartman about this and he mentioned there was once a klibc: https://old.reddit.com/r/linux/comments/fx5e4v/im_greg_kroah...
In Oasis: Small statically-linked Linux system
That's awesome. I didn't know about rwildcard until now. Is it part of GMSL? I searched for rwildcard on gmsl.sourceforge.io but didn't find it. I think my function is needlessly complicated compared to rwildcard. Here's my code: https://github.com/matheusmoreira/liblinux/blob/modular-buil... https://github.com/matheusmoreira/liblinux/blob/modular-buil... The file? and directory? functions were inspired by GMSL. I think I learned how to check whether a path is a directory from one of your posts. I wrote a general recursion function. It takes a function to apply to lists and a function to compute whether an element is a base case. The recursive file system traversal function applies a directory globbing function to the list of paths and has file? as base case. It returns all files without filtering. The find function recursively traverses
Read the rest
the file system while filtering out all items not matching the given predicate function. It was my intention to provide predicates like c_file? and header_file? but I stopped developing that project before that happened. Users can easily write their own predicates too. I think rwildcard is probably simpler and more efficient! If my code helps in any way though, feel free to use it.
In A Tutorial on Portable Makefiles (2017)
Linux is the only operating system that guarantees kernel binary interface stability. You can discard the entire user space and write dependency-free software that interfaces with Linux directly. You can even boot Linux straight into your own program and bring up the system yourself. This single function is all you need to do literally anything on x86_64 Linux from writing to a file descriptor to graphics card ioctls: https://github.com/matheusmoreira/liblinux/blob/master/sourc... In all others, interfacing with the kernel directly eventually leads to breakage because the people in charge change the system calls. Go binaries broke on OS X because of this. We're not meant to bypass their system libraries.
In Virgil: A fast and lightweight programming language that compiles to WASM
Great article, it was immensely useful in my quest to understand Linux processes. It says "Linux x86 program" but it assumes it's a hosted C program whose entry point is provided by GCC startfiles and libc. Everything after _start is specific to C. Note that _start is an arbitrary symbol and merely the linker's default value of the entry point. It can be changed to anything. The important Linux facts are: 1. _start is not a function It can't be returned from, the exit system call must be issued before execution terminates. 2. Arguments and environment are on the stack Argument count and vector can be simply popped off the stack into appropriate registers, in that order. The environment vector is located after the NULL terminator of the argument vector, or argument count + 1. The auxiliary vector is located after the NULL terminator of the
Read the rest
environment vector. No count is provided for that, so code must loop through the environment looking for the sentinel in order to find it. The auxiliary vector is really interesting. I don't usually see software making direct use of it. It contains interesting information such as CPU identifier and capabilities, page size, the location of the Linux vDSO, some random bytes, program file name, user and group IDs, among other things. https://github.com/torvalds/linux/blob/master/include/uapi/l... https://github.com/torvalds/linux/blob/master/arch/x86/inclu... https://github.com/torvalds/linux/blob/master/Documentation/... This is the data the Linux kernel passes to programs. After organizing these parameters, the program is free to do whatever it wants. The libc entry point will naturally start setting up libc. In particular, it seems to spend a lot of time setting up the init and fini insanity that's probably better off forgotten. https://blogs.oracle.com/solaris/post/init-and-fini-processi... It's not necessary. After this, you can just run your program directly. I used to develop a liblinux that illustrates all this with much simpler code: https://github.com/matheusmoreira/liblinux/blob/master/start... https://github.com/matheusmoreira/liblinux/blob/master/start... The entry point code passes the stack pointer to a C function which gathers all kernel parameters and starts the program with no further setup. I made several example programs, including one which outputs all these variables. https://github.com/matheusmoreira/liblinux/blob/master/examp... I stopped developing this because I discovered the Linux itself has a better solution that they use for their own tools: https://github.com/torvalds/linux/blob/master/tools/include/... The entry point code for all supported architectures is present as inline assembly code!
In Linux x86 program start up – How the heck do we get to main()? (2011)
Thanks for this, it's extremely awesome! Really happy to see others have gone so much farther than I ever did. I started looking into this myself some years ago. Even started developing a liblinux with process startup code and everything. Abandoned it after I found the kernel itself had an awesome nolibc.h file that was much more practical for my C programming needs: https://elixir.bootlin.com/linux/latest/source/tools/include... My code is in a bad state but if you'd like to take a look: https://github.com/matheusmoreira/liblinux It's amazing how this really lets you do everything... Want a JIT compiler? Map some executable pages and emit some code. You can statically allocate memory at process startup and use that for bootstrapping code. This lets you implement dynamic memory allocation and even garbage collection in your own language.
In My mouse driver is asking for a firewall exemption (2019)
Start using your operating system directly instead of relying on libraries to do things for you. Learn Linux system calls and use them for everything. A great way to do this is to compile your C code in freestanding mode and with no libc. You'll have to do everything yourself. It is easy to get started. Here's a system call function for x86_64 Linux: https://github.com/matheusmoreira/liblinux/blob/master/sourc... With this single function, it is possible to do anything. You can rewrite the entire Linux user space with this. The Linux kernel itself has a nolibc.h file that they use for their own freestanding tools: https://github.com/torvalds/linux/blob/master/tools/include/... It's even better than what I came up with. Permissively licensed. Supports lots of architectures. There's process startup code so you don't even need GCC's startfil
Read the rest
es in order to have a normal main function. The only missing feature is the auxiliary vector. You can just include it and start using Linux immediately. You can absolutely do this with Rust as well. Rust supports programming with no standard library. If I remember correctly, the inline assembly macros are still an unstable feature. It's likely to change in the future though.
In Ask HN: How to learn proper systems programming?

Showing the 15 most recent of 22 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.