Any good resources/deeper dives into the details of what actually happens on modern computers when making these syscalls on, say, linux? I might have a reasonable idea about what goes on when performing a mode switch or context switch, but I’d love to have a reference or a nice walkthrough.
My introduction to this was the 'Direct Execution' chapter of the book 'Operating Systems: Three Easy Pieces'.
It's a fantastic write up on not just how system calls work, but the motivation behind why operating systems even implement them in the first place. It's not specifically about Linux, but the book is clearly heavily inspired by early *nix designs and it's still applicable.
I wrote a detailed walk-through of the illumos syscall handler back in 2016. It's missing the updates around KPTI (meltdown mitigation), but other than that the mechanisms should be unchanged.
> It’s not a great idea to call system calls by writing your own assembly code.
> One big reason for this is that some system calls have additional code that runs in glibc before or after the system call runs.
That's not really the fault of the system calls. The problem is the C library itself. It's too stateful, it's full of global data and action at a distance. If you use certain system calls, you invalidate its countless assumptions and invariants, essentially pulling the rug from under it.
I've found programming in freestanding C with Linux system calls and no libc to be a very rewarding experience. Getting rid of libc and its legacy vastly improves C as a language. The Linux system call interface is quite clean. Don't even have to deal with the nonsense that is the errno variable.
Sounds roughly equivalent to discussing how much more rewarding it is to walk 1000km than to drive it.
Yes, everybody knows you can get from A to B on foot. But for multiple reasons, and over and extended period of time, we developed other methods of doing so. That doesn't invalidate the experience of doing it on foot, but it does make the walk into a very conscious choice that probably isn't the one most people are going to make most of the time.
But the internal details of libc leaking is accidental, not essential, complexity for the problem at hand. There's the baseline level of difficulty with writing assembly language, but the libc influence is imposed on top of that.
If the policy of the OS is to for programmers to only use libc for syscalls, perhaps that's a valid caveat to asm syscalls, but I don't think Linux is such an OS.
It absolutely is a policy of the OS and whoever is in charge of it. Nearly all of them provide their own libraries and decree that the only supported way to interface with the system is via those libraries. So you cannot "find a different libc or do without libc" on the vast majority of operating systems out there. You literally cannot get away from the OS libraries. If you try, your software inevitably breaks when they change system call numbers and semantics. Golang found out the hard way. Here's an awesome quotation from a BSD guy:
> I have altered the ABI. Pray I do not alter it any further.
Linux is actually the odd one. It's the only one with a stable language-agnostic system call ABI. It's stable because breaking the ABI makes Linus Torvalds send out extremely angry emails to the people involved until they fix it. Because of this stability, you actually can have alternative libc implementations like musl and you can also rewrite literally everything in Rust or Lisp if you want. Only on Linux can you do this.
For some reason people try extra hard to make it look like glibc is some integral part of the kernel. Diagrams on Wikipedia showing glibc enveloping the kernel like it's some outer component. Look up Linux manuals and you somehow get glibc manuals instead. The truth is they're completely independent projects. The GNU developers have zero power to force anyone to use glibc on Linux. You can make a freestanding application using system calls directly and literally boot Linux into it. I have made it my goal to create an entire programming language and ecosystem centered around that exact concept.
You are using the term "OS" to mean something other than "kernel", which is the meaning required by this thread (and arguably entire topic) thus far.
This is demonstrated by the rest of your comment, in which you note that linux has a stable, language agnostic system call ABI, and that other libc implementations exist.
TFA was ONLY about Linux syscalls, so what other platforms do or do not is irrelevant in context.
I understand what you mean. It's just that I object on principle to this notion that using system calls is "wrong" or "something normal people aren't supposed to do" as if the libc programmers have special privileges. It's these constant warnings about and fearmongering around the system calls that made me want to use them in the first place.
The warnings etc. are for people who, more likely than not, are using a libc implementation that depends upon its own wrapping of syscalls. As such, they are entirely appropriate.
Do they apply to all possible uses of syscalls? They do not.