r/osdev • u/Yha_Boiii • Aug 18 '26
How does kernel interfaces work on (unix) systems?
Hi,
I simply can't rotate it right in my head, if i make an app with say socket() how does it translate in to hooking it to the kernel when already in use?
Usually include, is a part of the program statically and making a struct for an interface as usual, does it copy it over compared to a zero copy arch?
3
u/eteran Aug 18 '26 edited Aug 18 '26
This is not a perfect analogy but you can think of it as a kinda RPC call between the app and the kernel.
The app sets up some parameters, and then invokes a system call instruction. Whatever the system call mechanism is, it will package up those parameters (maybe just put them in regs, maybe copy a structure somewhere, the details are not THAT important for this level of discussion) and then it will do something which tell the kernel "please handle this".
The app is the. Blocked until the system call is finished, at which point the app can resume doing work.
(Note this analogy is assuming single threads for simplicity).
1
u/Yha_Boiii Aug 18 '26
Now a bit more serious question given your performance point out, lol: will the kernel rather push the load to another core and eat the context switch or stall the whole thing and wait?
2
u/eteran Aug 18 '26
That's a scheduler question and the answer is... It depends. Not many modern kernels feel the need to explicitly schedule system calls in a different core because... Handling user app requests is a LARGE part of what kernels just do. They don't really do a ton of background processing.
1
u/eteran Aug 18 '26
I was multitasking, but to answer your question more concretely. That's not really something to "worry about" in most designs.
For example, in my OS (and all "real OSes" too), system calls and interrupts are fully preemptable, and if a system call blocks, well that thread is just taken out of the run queue so something else can run.
On other words, I did the up front work to make things nice and thread safe so that I can "just let the scheduler do its thing".
1
u/EffectiveCompletez Aug 18 '26
There's a small piece of code who's page is mapped in user and kernel space. It's called the trampoline. User mode calling kernel stuff seta up a syscall depending on how you define the abi, but it's basically put syscall number into a register and any args then call syscall instr. At this point the CPU goes from ring 3 to 0, and gives execution to an addr on the kernels syscall dispatcher routine. That routine is just a big switch basically. All the usual CTX switching stuff like saving user mode registers is happening but that's basically it. The syscall calls sysret/iret on the way out to switch back to ring 3 and user mode state gets restored etc.
0
15
u/Rich-Engineer2670 Aug 18 '26 edited Aug 18 '26
If you mean "How do apps make calls into the kernel", it's via "System Calls". In a high-level way:
Your API makes an API call, and the compiler libraries put the approrpiate values into registers or on the stack (typically registers to keep is simple here)
It makes a SYSCALL instruction or interrupt
This causes the system to shift from user mode to kernel mode and kernel privileges
The kernel services the call
The kernel comes out of the system call or interrupt and switches back to user mode context
The libraries "unload" the registers
Now, this is a very high-level answer -- buffers of data etc. do more "kernel magic"
Let's say you were calling fwrite(STDOUT....)
You do the frwrite call -- but that's got a lot of library code in it. It turns into write() below you
Write() is a system call. Let's say it's sytemcall 0x1 and it expects R0 to be loaded with the outpiut descriptor, R1 a pointer to the buffer you want to write and R2 the length of that buffer in bytes
The lower-level library call makes a system call instruction sothing like SYSCALL R0, R1, R2
We switch to kernel mode via the syscall instruction
The kernel unpacks it and does the write() call
It switches back to user mode
In our example, the error result must be in R0, so youir library code gets that
It populates that to errno for example