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 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 2:59:53 AM 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

9 sources
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?
> What I wouldn't give for a liblinux, similar to NTDLL. Hey I actually tried to make such a thing. https://github.com/matheusmoreira/liblinux It provides access to Linux system calls and process start up code that gets all the arguments, environment and auxiliary values. I have several examples of applications written in 100% freestanding C with zero dependencies other than this library: https://github.com/matheusmoreira/liblinux/tree/master/examp... It's a bit too low level but I actually planned to make my own ld-liblinux eventually. It currently works with static and dynamic linking. The ld-linux.so is able to link even though nothing else links against glibc. I didn't test dynamic loading though. I stopped working on it because I found better solution for system calls on the Linux kernel repository: https://github.com/torvalds/linux/
Read the rest
blob/master/tools/include/... Do you think liblinux could have a future?
In Actually Portable Executables
Thanks! Your projects are so inspiring. I too felt great joy discovering all this. Every time I see someone asking about system calls I respond by writing about everything I know. I usually don't get many replies... So happy to see another person who understands. > You would like this project: https://chromium.googlesource.com/linux-syscall-support/ Yes, I would! I saw references to this library in your source code, specifically your jump slots implementation. I had no idea Chromium had this and I've been meaning to explore it later. I'm gonna do it now. > Because too many people who post here hold the viewpoint that SYSCALL is evil and you must link the platform libc dynamic shared object or else you're a very horrible person who deserves to have their binaries broken like Apple did to Go. I know what you mean! Using system calls are hea
Read the rest
vily discouraged by libc maintainers and even users. Using calls like clone will actually screw up the global state maintained by glibc threads implementation. It gets to the point where they don't even offer wrappers for system calls they don't want to support. I don't like it... What's the point of an amazing system call that lets you choose exactly which resources you want to share with a child task if all it's ever used for is some POSIX threads implementation? Even the Linux manuals do this for some reason: the documentation I linked in my above post actually describe the glibc stuff as if it was part of the kernel and leaves the actual binary interfaces as an afterthought. Linux manuals also inexplicably host documentation for systemd instead of a generic description of how a Linux init system is supposed to interface with the kernel. It makes no sense to me! I even asked Greg Kroah-Hartman about it on Reddit: https://old.reddit.com/r/linux/comments/fx5e4v/im_greg_kroah... I actually think using the system call interface is better than using the C library. No thread local errno business, no global state anywhere, no buffering unless you do it explicitly, no C standard to keep in mind... It's just so simple it's amazing. It's also stable unlike other operating systems which ship user space libraries as the actual interface. On Linux there's no reason not to use it! > I feel like you should publish this and post it on Hacker News. I wrote a liblinux library, the README describes part of my journey learning about this system call stuff. Lots of LWN sources! https://github.com/matheusmoreira/liblinux/blob/master/READM... I've been thinking about expanding on it in order to describe everything I know about the Linux system call interface. You really think I should publish this? The reason I didn't post liblinux here is it's in a very incomplete state and actually less practical than the kernel nolibc.h file. I only discovered the header much later into development and figured there was no point anymore since the kernel had a much better solution not only available but in actual use. I ended up rewriting autoconf in pure makefiles instead...
In Actually Portable Executable
> learning the linux syscall stuff I've been studying this for a while. Turns out Linux has an amazing interface. It's stable and language-agnostic. All you need to do is put the values in specific registers and execute a special instruction. The result comes back in one of those same registers. The high level documentation is here: https://man7.org/linux/man-pages/man2/syscall.2.html https://man7.org/linux/man-pages/man2/syscalls.2.html https://www.kernel.org/doc/Documentation/ABI/stable/syscalls https://www.kernel.org/doc/Documentation/ABI/stable/vdso On Windows there is a similar interface but it is not stable. The system call numbers can change. Developers are supposed to use the good old Microsoft DLLs in order to get anything done. Just like how everyone uses libc on other systems. Linux is different. The system call binary interfac
Read the rest
e is the Linux interface. So it's actually possible to trash all of GNU and rewrite the entire Linux user space in Rust or Lisp or whatever. It doesn't have to be written in C. It doesn't even have to be POSIX compliant. Could be GUI-focused! All you need to make any x86_64 Linux system call is this code: long system_call(long number, long _1, long _2, long _3, long _4, long _5, long _6) { register long rax __asm__("rax") = number; register long rdi __asm__("rdi") = _1; register long rsi __asm__("rsi") = _2; register long rdx __asm__("rdx") = _3; register long r10 __asm__("r10") = _4; register long r8 __asm__("r8") = _5; register long r9 __asm__("r9") = _6; /* r8, r9 and r10 may be clobbered but can't be in the clobbers list because the compiler won't use clobbered registers as inputs. So they're placed in the outputs list instead. */ __asm__ volatile ("syscall" : "+r" (rax), "+r" (r8), "+r" (r9), "+r" (r10) : "r" (rdi), "r" (rsi), "r" (rdx) : "rcx", "r11", "cc", "memory"); return rax; } This is all you need to do anything. You can perform I/O. You can allocate memory. You can obtain your terminal's dimensions. You can perform ioctl's to your laptop's camera. You could make a new programming language today and all it really needs to be complete is this single function. What if instead of having this function the compiler could simply emit code that conform to this binary interface? The language could have a system_call keyword that generates Linux system call code! Once I realized this I tried to turn it into a library called liblinux... I stopped working on it when I found out the kernel already has an awesome single file header you can include that lets you build freestanding Linux executables for a ton of architectures. They use it on the kernel to build their own tools! https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin... It even includes process entry point code! Linux copies the argument and environment vectors to the stack before entering the executable. The process start up code obtains those pointers and passes them to the main function. It also ensures the exit system call is called. The process entry point is usually called _start because that's what linkers look for by default. In reality the ELF header has a pointer to the program's entry point, the actual symbol doesn't matter. You can tell the linker to set it to any other address or symbol. Also note that it's an entry point, not a function. There is no return address. Allowing that code to terminate results in a segmentation violation. Hence the need to ensure exit is called before that happens. The only feature that seems to be missing is support for the table of auxiliary values: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin... The auxiliary values are placed on the stack immediately after the environment vector. So all you need to do to find this pointer is loop through it until it goes out of bounds. I wrote this code and it works: https://github.com/matheusmoreira/liblinux/blob/master/start... struct auxiliary { Elf64_Off type; Elf64_Off value; }; static void *after(void *vector) { void **pointer = (void **) vector; while (*pointer++ != 0); return pointer; } int liblinux_start(void *stack_pointer) { long count; char **arguments; char **environment; struct auxiliary *values; count = *((long *) stack_pointer); arguments = ((char **) stack_pointer) + 1; environment = arguments + count + 1; values = after(environment); return start(count, arguments, environment, values); } You can just loop over the pointer to the structure until you find one with type equal to AT_NULL. Example here: https://github.com/matheusmoreira/liblinux/blob/master/examp...
In Actually Portable Executable

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.