Does a program that prints text directly operate the display or SSD itself? Ordinary applications request services through interfaces supplied by the OS. This boundary helps prevent an error in one program from immediately corrupting another program's memory or the configuration of a device.
What you will learn
You will distinguish user mode from kernel mode and interpret the arguments to write. You will also distinguish a system call's privilege transition from switching execution to another thread.
Separate CPU privilege from the OS's responsibilities
The kernel is the core of the OS that manages memory allocation, scheduling, and access to files and devices. Applications normally run in user mode with restricted privileges. Operations that affect the wider system, such as changing page tables, are performed by code running with the required hardware privileges.
A privileged CPU mode is not the same as an all-powerful user account. CPU execution modes and OS credentials such as root are separate mechanisms. Even a program running as root normally executes application instructions in user mode and requests necessary services from the kernel.
Reading a call to write
#include <unistd.h>
int main(void) {
const char message[] = "Hello\n";
ssize_t n = write(STDOUT_FILENO, message, sizeof(message) - 1);
return n == (ssize_t)(sizeof(message) - 1) ? 0 : 1;
}The first argument is a file descriptor identifying the destination, the second is the address of the data, and the third is the number of bytes to write. STDOUT_FILENO normally has the value 1 and identifies standard output. The code subtracts one from the array's size so that the terminating zero byte is not printed.
In many environments, the C library's write wrapper arranges arguments according to the calling convention and uses a dedicated CPU instruction to enter the kernel. The kernel checks whether the destination is valid, whether writing is permitted, and whether the specified user memory can be accessed. It does not simply trust an address supplied by the application as an internal kernel pointer.
Success does not always mean the entire request completed
The return value of write is the number of bytes actually written. It may be smaller than requested, so a general-purpose output routine tracks the remaining range and repeats the operation as necessary. The short example above only checks whether all six bytes were written; it does not retry a partial write. Failure normally returns -1, with the reason available through the C library's errno.
The number of application function calls is not necessarily the number of system calls. For example, printf may accumulate data in a user-space buffer before calling write. Conversely, one high-level file operation may invoke several system calls. When investigating behavior, count source-code operations separately from requests made to the OS.
A mode transition is not a switch to another thread
Entering a system call does not always switch execution to another process. The kernel may handle the current thread's request and return directly to that same thread in user mode. If the thread cannot continue, for example because it must wait for I/O, the scheduler can select another runnable thread. A privilege transition concerns entry to and exit from the kernel; a context switch concerns which execution context receives the CPU.
Check your understanding
Question 1: Does a program started as root execute every instruction in kernel mode? No. User credentials and CPU execution mode are separate. Operations requiring kernel privileges go through interfaces such as system calls.
Question 2: write(fd, buf, 100) returns 40. Does that mean all 100 bytes were sent? No. It reports that 40 bytes were written, so the remaining 60 bytes still need to be handled. A retry must update both the buffer position and the remaining length.
Processes, Threads, and Context Switches explains how the kernel manages execution state.