What is an OS? — Architecture Overview

What is an Operating System?

An operating system (OS) is the foundational software layer that manages hardware resources and provides a consistent interface for application programs. It sits between the bare metal (CPU, memory, disks, network cards) and the software you actually run, turning raw hardware into a set of clean, reusable abstractions.

Without an OS, every program would have to negotiate directly with hardware: twiddling interrupt controllers, writing to device registers, and manually partitioning memory. The OS centralizes that work so that programs get a clean virtual machine: a private address space, a virtual CPU via scheduling, and named files and sockets instead of raw disk blocks and wire signals.

The OS pursues two jobs at once:

  • Resource manager — fairly and safely divides CPU time, memory, storage, and I/O among competing programs.
  • Abstraction provider — gives applications portable, hardware-independent interfaces (processes, files, sockets) via system calls.

Why Do We Need an OS?

  • Safety: applications must not crash each other or corrupt the kernel. The OS enforces isolation so one buggy program can’t read another process’s memory.
  • Fairness & efficiency: without scheduling, a runaway loop would starve everything else. The OS multiplexes scarce resources.
  • Portability: a program written against POSIX system calls runs on Linux, macOS, and BSD alike — the OS hides the hardware differences beneath it.
  • Convenience: files, directories, pipes, and sockets are far more usable than “track 42, sector 7.”

The Kernel

The kernel is the core of the OS — the always-resident portion that runs in privileged mode and has unrestricted access to hardware. Everything else is system software (shells, compilers, daemons) or user applications.

The kernel is responsible for:

  • Process & thread management — creation, scheduling, context switching, and synchronization.
  • Memory management — virtual address spaces, paging, and protection.
  • File systems & storage — organizing persistent data into files and directories.
  • Device drivers — mediating access to hardware through interrupts and register I/O.
  • Networking & IPC — sockets, pipes, signals, and shared memory between processes.
  • Security & access control — permissions, users, and capability checks on every operation.

User Mode vs Kernel Mode

Modern CPUs have at least two privilege levels. On x86 these are rings, with ring 0 (kernel) and ring 3 (user); most OSes use just two effectively.

  • User mode: applications run here with restricted instructions and no direct hardware access. They only see their own virtual address space.
  • Kernel mode: the OS runs here with access to all instructions, all memory, and all devices.

The transition between them is what makes the model safe. A user program cannot just jump into kernel code — it must go through controlled entry points (see below). When the CPU is in user mode, privileged instructions (like directly writing to the page table or disabling interrupts) are trapped and routed to the kernel.

System Calls

System calls are the only bridge from user space to kernel space. They are the API of the OS — the documented, controlled entry points through which a program requests kernel services.

The flow for every syscall:

  1. The program sets up arguments (registers or a memory block) and executes a special instruction (syscall on x86-64, svc on ARM).
  2. The CPU switches to kernel mode and jumps to a kernel handler for the syscall number.
  3. The kernel validates arguments, performs the operation (with permission checks), and returns to user mode with a result or error.

Common POSIX syscalls:

  • Process: fork, exec, wait, exit, kill
  • Files: open, read, write, close, fsync
  • Memory: mmap, munmap, brk
  • IPC/Networking: pipe, socket, connect, send, recv

A syscall is not a function call: a library call (read() in glibc) may stay entirely in user space or wrap one syscall, and syscalls are far more expensive because they require a mode switch.

OS Abstractions

The OS virtualizes hardware into three core abstractions:

  • Process — the OS’s virtual CPU. Each process believes it has the whole processor to itself; the scheduler interleaves many processes.
  • File — the OS’s virtual storage. A file is a named, byte-addressed object; the kernel maps it onto disks, SSDs, pipes, or even other processes.
  • Socket / pipe — the OS’s virtual network and IPC. Programs exchange bytes through these named channels without knowing the physical link underneath.

The key idea: virtualization. The OS makes a single piece of hardware look like an infinite supply of safe, independent resources.

Kernel Architectures

Kernels differ in how much they put in privileged space and how components talk to each other.

ArchitectureWhat runs in kernelStrengthsWeaknesses
Monolithic (Linux, BSD)Everything — scheduling, drivers, file systems, network stackFast, tight integrationA bug in any driver can crash the whole kernel
Microkernel (QNX, seL4, Minix)Minimal core (IPC, scheduling, basic memory) only; drivers/services run as user-space processesStrong isolation, fault toleranceMore IPC overhead, harder to build fast
Hybrid (Windows NT, macOS/XNU)Core kernel + selected drivers/services in privileged spaceBalance of speed and modularityMore attack surface than a microkernel

Linux is monolithic in the classic sense but mitigates it with loadable kernel modules (LKM) — drivers can be inserted and removed at runtime without rebuilding the kernel, and modern hardening (KASLR, module signing) reduces the blast radius.

The Boot Sequence

How does the OS get from power-on to a running system?

  1. BIOS/UEFI runs from firmware, initializes hardware, and selects a boot device.
  2. The bootloader (GRUB, systemd-boot) loads the kernel image and an initial RAM disk into memory.
  3. The kernel decompresses and initializes CPU/memory structures, sets up page tables, and enables interrupt handling.
  4. The kernel mounts the real root file system and launches the first user-space process (initsystemd, sysvinit, or a container runtime).
  5. init starts services (daemons, network, display manager), and the system reaches a usable state — possibly letting you log in.

Everything that happens before the kernel hands off to init is largely invisible to user-space code, which is why boot is a common source of “it worked yesterday” mysteries.

Worked Example: A Single read() Call

Trace what happens when a C program reads from a file:

  1. The program calls read(fd, buf, 100) — a glibc wrapper.
  2. The wrapper issues a syscall instruction with the read syscall number.
  3. The CPU traps to kernel mode; the kernel looks up the file descriptor, checks the process’s permissions and buffer validity.
  4. The kernel reads the data from the page cache or disk and copies it into the user buffer.
  5. The CPU returns to user mode; read returns the byte count.

That single call crosses the user/kernel boundary twice — the fundamental cost of using an OS.

Practice Trajectory

  1. Boot a Linux machine and run dmesg and ls /proc — identify what the kernel initialized and which processes are live.
  2. Compare cat /proc/cpuinfo with the output of uname -a; note how the kernel abstracts the CPU.
  3. Use strace -e trace=open,read ls to watch a trivial command make syscalls — count the mode switches.
  4. List every abstraction the OS provides that a bare-metal program would have to build itself.
  5. Explain the trade-off between a monolithic and a microkernel design for an embedded device vs a server.

When It’s the Right Tool

SituationTakeaway
Learning OS internalsStart from the kernel/syscall boundary — everything else hangs off it
Choosing a design for safety-critical systemsMicrokernels (QNX, seL4) contain faults; monolithic kernels maximize throughput
General-purpose servers & cloudLinux’s monolithic-plus-modules design is the pragmatic default
Debugging application issuesTrace the syscall boundary first: strace/perf separate app bugs from kernel behavior