Introduction
A system call is the controlled gateway through which a user-mode application requests a privileged service from the kernel, such as creating a process, reading a file, or allocating memory. Because user-mode code cannot execute privileged instructions or directly touch hardware, system calls are the only legitimate path from an application into kernel functionality.
Cricket analogy: A batsman cannot walk onto the field and change the pitch or scoreboard directly; he must request the umpire, the only authority allowed to act, just as user-mode code must request the kernel for privileged operations.
How It Works
When a program calls a library function like read() or fork(), the C library wraps the request in a special trap instruction (on x86-64 Linux, historically 'int 0x80', and on modern systems the faster 'syscall' instruction). Executing this instruction causes a controlled transition from user mode to kernel mode: the CPU switches privilege level, saves the user context, and jumps to a fixed kernel entry point. The kernel looks up the requested operation in a system call table using a syscall number, executes the corresponding kernel function with the given arguments, and then returns the result, switching the CPU back to user mode and resuming the calling process. This mechanism is what keeps the kernel in full control of hardware while still letting applications request services safely.
Cricket analogy: Calling read() is like a captain signaling the third umpire via a formal review request; the syscall/trap instruction is the review signal, the third umpire's booth is kernel mode, and the decision returns control to the field.
Example
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void) {
printf("Before fork(): PID=%d\n", getpid());
/* fork() is a system call: it traps into the kernel,
which duplicates the calling process's address space
and scheduling state, then returns twice -- once in
the parent, once in the new child. */
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
return 1;
} else if (pid == 0) {
/* Child process: write() is also a system call,
trapping into the kernel to perform actual I/O. */
const char msg[] = "Child: hello from kernel-mediated I/O\n";
write(STDOUT_FILENO, msg, sizeof(msg) - 1);
_exit(0);
} else {
/* Parent waits for the child using the wait() system call. */
int status;
waitpid(pid, &status, 0);
printf("Parent: child %d finished\n", pid);
}
return 0;
}Analysis
Each of fork(), write(), and waitpid() triggers a user-to-kernel mode transition. fork() asks the kernel's process manager to duplicate the calling process; the kernel returns 0 in the new child and the child's PID in the parent, letting one call produce two distinct control-flow paths. write() asks the kernel's file/I/O subsystem to copy bytes from user-space memory into the OS-managed file descriptor (here, standard output), which the kernel then flushes to the terminal driver. waitpid() blocks the parent, requesting the scheduler suspend it until the kernel signals that the child has exited. In every case, the application never touches hardware or the scheduler directly — it only issues a well-defined request and lets the kernel act on its behalf, illustrating the safe boundary system calls enforce.
Cricket analogy: fork() is like a coach cloning a player into two identical twins mid-match, one continuing as the original batsman and one starting a new innings elsewhere, each returned a different signal to know which role they play.
Key Takeaways
- System calls are the only sanctioned path from user mode into kernel-mode services.
- A trap instruction (e.g., syscall on x86-64) triggers the user-to-kernel mode switch.
- The kernel dispatches requests via a syscall number looked up in a system call table.
- fork(), write(), and waitpid() are classic examples of process and I/O system calls.
- After servicing the request, the kernel returns control and the CPU switches back to user mode.
Practice what you learned
1. What is a system call?
2. What CPU-level event occurs when a program executes a system call instruction such as 'syscall' on x86-64?
3. In the fork() example, why does the same fork() call appear to 'return twice'?
4. Which kernel structure does the OS use to dispatch a system call to the correct handler function?
Was this page helpful?
You May Also Like
Introduction to Operating Systems
Learn what an operating system is, why it exists, and how it mediates between hardware and applications.
OS Functions and Types
Explore the core functions every OS performs and the major categories of operating systems.
OS Structure and Kernel Types
Compare monolithic, microkernel, and hybrid kernel architectures with real-world examples.