The Boundary: User Space vs. Kernel Space
When your C program runs, it lives in User Space. It is isolated from other programs and from the hardware itself by the CPU’s memory protection hardware. If you want to perform any action that affects the outside world (like writing to a file or sending a network packet), you must cross the boundary into Kernel Space.
The System Call (Syscall)
A system call is the mechanism for a program to request a service from the operating system kernel.
- The program places arguments in specific CPU registers.
- It executes a special assembly instruction (like
syscallon x86-64 orsvcon ARM). - The CPU switches to a higher privilege level (Ring 0) and jumps to the kernel’s entry point.
The Standard Library as a Wrapper
Functions like printf() or fopen() are not system calls themselves. They are part of the C Standard Library, which performs buffering and formatting before eventually calling the true system-level functions (like write() or open() on POSIX systems).
Interfacing with Hardware
In kernel drivers or embedded C, we interact with hardware via Memory-Mapped I/O (MMIO). Specific memory addresses are physically wired to hardware devices.
// Force the compiler to read/write the actual memory address
// every single time, because the hardware could change it.
volatile uint32_t *led_control = (uint32_t *)0x40021018;
*led_control = 0x01; // Turn on a physical LED
The Application Binary Interface (ABI)
The ABI is the low-level contract between the compiler and the machine. It defines:
- Calling Conventions: Which registers are used to pass function arguments.
- Stack Alignment: How the stack pointer must be positioned.
- Data Layout: How
structpadding is handled.
Understanding the ABI is essential for writing assembly code that calls C functions, or vice versa.
Hardware Keywords
// used to prevent optimization for MMIO uint32_t *reg = (uint32_t*)0x1234;
Interrupts and Callbacks
In systems programming, we often deal with Interrupts. An interrupt is a hardware signal that tells the CPU to stop what it’s doing and jump to a specific function called an Interrupt Service Routine (ISR).
- ISRs must be incredibly fast.
- They cannot perform blocking I/O or allocate memory from the standard heap.
Performance: The Inline Advantage
Technically, a function call has overhead (pushing to the stack). For performance-critical system code, we use the inline keyword. This asks the compiler to copy the function body directly into the calling site, eliminating the call overhead while keeping the code modular.
Interactive Lab
Waiting for signal...
Final Thoughts
Mastering C means mastering the machine. By understanding how the preprocessor, compiler, and linker collaborate with the Operating System, you gain the power to build the tools that empower all other software. From here, the journey continues into OS Development, Compiler Design, and High-Performance Systems.