An operating system (OS) is the software layer between hardware and user applications. It provides three fundamental services:
Common examples: Linux, macOS (XNU kernel), Windows NT, Android (Linux kernel).
Modern CPUs support at least two privilege levels:
| Mode | Who runs here | What it can do |
|---|---|---|
| Kernel mode | OS kernel | Full hardware access — I/O ports, MMU, interrupts |
| User mode | Applications | Restricted; cannot directly access hardware |
A system call is the controlled gateway from user mode to kernel mode. When a program calls read(), it triggers a software interrupt that transfers execution to the kernel, which performs the I/O and returns the result.
Trap instruction: On x86-64, syscall is the instruction that raises privilege level and jumps to the OS system call handler. On Linux, syscall numbers are defined in the kernel ABI.
A process is a running instance of a program. Each process has its own:
The kernel stores per-process state in a PCB (also called task_struct in Linux):
When the OS switches the CPU from process A to process B:
Context switch overhead: Saving/restoring registers, flushing TLB entries, and cold cache effects make context switches expensive. OS schedulers minimize unnecessary switches.
A user program calls printf("Hello
"). Trace the path from user space to the terminal display, identifying where system calls occur.
A parent process forks a child. The child exits immediately, but the parent never calls wait(). What happens? Why is this a problem?
What is the primary purpose of a system call?
A system call crosses the privilege boundary from user space to kernel space. Calling another program's function (same privilege level) is different.
A syscall is specifically about requesting kernel services (I/O, process creation, etc.). Thread switching is separate, though the kernel scheduler may be involved.
exec() is one system call. The definition of a system call is broader: any controlled user→kernel request for services (read, write, fork, mmap, etc.).
A process in the BLOCKED state is:
RUNNING: currently executing instructions on a CPU core. BLOCKED: waiting for an event (I/O completion, semaphore signal, timer).
READY: in memory, waiting for a CPU to become available. BLOCKED: waiting for a non-CPU event like I/O completion.
A zombie is in the TERMINATED state, not BLOCKED. BLOCKED processes are still alive but paused waiting for an event.
The Process Control Block (PCB) stores:
Source code is a file on disk. The PCB holds saved registers, memory maps, open files, PID, and scheduling info — everything the OS needs to manage and resume a process.
The PCB (task_struct in Linux) contains PID, PPID, state, all CPU registers, memory maps, open file descriptors, signal handlers, priority, and more.
File system structures (inodes, block maps) track disk usage. The PCB tracks runtime CPU and memory state.
Which of the following is NOT saved during a context switch?
The PC is one of the most critical registers to save — it holds the address of the next instruction to execute.
Every register must be saved: arithmetic registers, stack pointer, flags, etc. Missing one would corrupt the process's state on resume.
The CR3 register (x86) points to the page table. It must be saved/restored to give each process its correct address space view.
A zombie process is one that has:
SIGTSTP puts a process in a stopped/suspended state. A zombie has actually exited but its PCB hasn't been freed because the parent hasn't called wait().
A crashed process exits (possibly abnormally). If the parent never calls wait(), it becomes a zombie — but the crash itself doesn't define the zombie state.
A zombie has already exited — it uses no CPU at all. It only occupies a PCB entry in the process table.