Learning Question
How do source code, executable files, processes, the kernel, and hardware fit together?
A running program sits at the intersection of several layers.
Source code describes intended behavior.
An executable file stores loadable machine-level content.
A process is the OS-managed running instance.
The kernel manages protected resources and shared machine state.
The hardware executes instructions and enforces low-level protection with OS configuration.
The final mental model is:
Program execution is user code running inside a process, supported and constrained by the kernel, on hardware shared with other execution contexts.
The Main Layers
| Layer | Role |
|---|---|
| source code | human-readable description of program behavior |
| executable file | loadable representation of code, data, and metadata |
| process | OS-managed running instance with address space and resources |
| thread | schedulable execution path inside a process |
| virtual memory | process-specific address view mapped and protected by OS and hardware |
| system call | controlled boundary from user code into kernel-managed work |
| kernel | privileged OS layer managing resources, protection, scheduling, and devices |
| hardware | CPU, memory, devices, and mechanisms that execute and enforce configured behavior |
Confusion often comes from collapsing these layers.
The executable is not the process.
The process address is not necessarily a physical address.
A library call is not always a system call.
A socket is not the remote application.
A thread is not a process.
What User Code Does Directly
User code can execute ordinary instructions directly on the CPU while it is scheduled.
It can compute, branch, call functions, manipulate registers, and access memory that is valid in its address space.
This is the direct execution part of a running program.
But direct execution happens inside boundaries.
The process must be scheduled.
The memory access must be valid.
The instruction must be allowed in user mode.
The program’s authority is limited by its process identity and OS policy.
What Requires Kernel Support
The program relies on the kernel for operations such as:
- creating and managing processes
- mapping and protecting memory
- opening files
- reading and writing descriptors
- communicating through pipes and sockets
- waiting and waking
- scheduling CPU time
- handling signals and exit state
- enforcing permissions
- interacting with devices and networks
These are not merely helper features.
They are the controlled ways a program uses shared machine resources.
Boundaries That Prevent Confusion
Keep these boundaries separate:
- A path names a file-system location. A file descriptor refers to an open resource.
- A process owns an address space. A thread is an execution path inside a process.
- Virtual addresses belong to a process context. Physical memory is managed below that view.
- A system call crosses into the kernel. A normal function call stays in user space.
- A pipe or socket transfers data through the OS. It does not call another process’s functions.
- Exit status records process completion. It is not the same as printed output.
- A signal is an OS-level event. It is not just a text message.
These distinctions make runtime behavior easier to explain without vague phrases.
Reading a Runtime Symptom
When a running program behaves unexpectedly, map the symptom to a layer.
If a file cannot be opened, check path resolution, permissions, descriptors, and system call errors.
If a program uses high CPU, ask whether it is runnable and executing, spinning, or doing CPU-bound work.
If a program uses no CPU but makes no progress, ask what it is blocked on.
If memory access crashes, ask which virtual address was accessed and whether the page was mapped with the needed permission.
If network communication fails, ask about sockets, addresses, connection state, protocol expectations, and blocking behavior.
If a child process finished but remains visible as a zombie, ask whether the parent has waited.
The goal is not to memorize commands first.
The goal is to know which OS-managed structure could produce the visible behavior.
How This Extends the C Execution Model
A lower-level C execution model explains how source becomes machine instructions and how those instructions use registers, stack frames, memory addresses, and executable files.
This operating-system model begins where that explanation reaches the running process.
It asks what supports that process after it exists:
- who gives it an address space
- who maps its memory
- who lets it read files
- who schedules it
- who blocks and wakes it
- who connects it to other processes
- who records its exit
- who denies unauthorized operations
The answer is the operating system, working with hardware support.
Core Mental Model
A program runs when its instructions execute in a process context.
The process provides identity, address space, resources, permissions, and lifetime.
Threads provide schedulable execution paths.
Virtual memory gives the process its memory view.
System calls let the process request kernel-managed work.
The kernel coordinates shared CPU time, memory, files, devices, communication, signals, and protection.
Hardware executes instructions and enforces the low-level mechanisms configured by the OS.
Final Summary
Operating systems support running programs by turning shared hardware into isolated, controllable, observable process environments.
The durable question is:
Is this behavior coming from user code executing directly, from the process context around it, from a system call into the kernel, or from hardware enforcing the OS-managed boundary?