Learning Objectives
- Understand what a System Call is.
- Understand why applications cannot access hardware directly.
- Learn User Space and Kernel Space.
- Understand the System Call Interface.
- Study complete execution flow.
- Learn Linux examples.
- Prepare for Embedded Linux interviews.
Prerequisites
- CPU Architecture
- CPU Registers
- Memory Management
- Processes
- Process Control Block
Table of Contents
- Introduction
- What is System Call?
- Need of System Calls
- User Space
- Kernel Space
- Execution Flow
- Examples
- Interview Questions
1. Introduction
An application such as a web browser, text editor, or media player often needs services that only the operating system can provide. Examples include reading files, writing data to storage, creating processes, allocating memory, and communicating with hardware devices. Instead of interacting with hardware directly, applications request these services through system calls. The operating system validates the request, performs the required operation in kernel mode, and returns the result to the application.
2. Why are System Calls Needed?
Modern operating systems protect hardware resources from direct access by user programs. This protection prevents accidental corruption of memory, unauthorized device access, and system instability. System calls allow applications to request privileged operations in a controlled and secure manner.
| Without System Calls | With System Calls |
|---|---|
| Application directly accesses disk | Kernel validates request before accessing disk |
| Any program can modify memory | Kernel enforces memory protection |
| No permission checking | User and file permissions are verified |
| System instability | Controlled and secure execution |
3. User Space vs Kernel Space
Operating systems divide execution into two protection domains:
Applications execute in User Space. Sensitive operating system services execute in Kernel Space. A system call transfers control from user space to kernel space and returns after the requested operation is complete.
4. System Call Interface (SCI)
The System Call Interface (SCI) acts as the communication bridge between an application running in User Space and the operating system kernel running in Kernel Space. Instead of allowing an application to directly manipulate hardware resources, the operating system exposes a controlled set of functions known as system calls. These functions form the official interface through which applications request operating system services.
The System Call Interface validates the request, identifies the required kernel service, transfers execution into kernel mode, and returns the result back to the calling application.
5. User Mode and Kernel Mode
Modern processors operate in different execution modes to protect the operating system and hardware resources.
| User Mode | Kernel Mode |
|---|---|
| Applications execute here | Operating System executes here |
| Restricted permissions | Full hardware access |
| Cannot access device registers | Can access hardware directly |
| Cannot modify page tables | Can manage virtual memory |
| Cannot execute privileged instructions | Can execute privileged instructions |
6. CPU Mode Switching
When an application invokes a system call, the processor changes its execution privilege level. This transition is called a Mode Switch.
Only the processor can change between User Mode and Kernel Mode. Applications cannot directly force themselves into Kernel Mode.
7. Trap Instruction
A system call is initiated using a special processor instruction known as a Trap (also called a Software Interrupt on some architectures). Unlike hardware interrupts generated by external devices, a trap is intentionally generated by the currently running program.
8. Complete System Call Execution Flow
The following diagram illustrates how a simple file read request travels through the operating system.
9. Real World Analogy
Imagine a customer visiting a bank.
| Real World | Operating System |
|---|---|
| Customer | User Application |
| Bank Counter | System Call Interface |
| Bank Employee | Kernel |
| Locker Room | Hardware Resources |
The customer cannot directly enter the locker room. Instead, the customer submits a request at the counter. The bank employee verifies the request, accesses the locker, and returns the requested item. Similarly, applications cannot directly access hardware. They submit requests through system calls, and the kernel performs the operation securely.
Key Points Learned
- System Calls provide controlled access to operating system services.
- User applications execute in User Mode.
- The kernel executes in Kernel Mode.
- A Trap transfers execution from User Mode to Kernel Mode.
- The System Call Interface is the bridge between applications and the kernel.
- The kernel validates every request before interacting with hardware.
10. Types of System Calls
Operating systems provide hundreds of system calls. Although each system call performs a different task, they can be grouped into several categories based on their purpose.
| Category | Purpose | Examples |
|---|---|---|
| Process Control | Create, execute and terminate processes | fork(), exec(), wait(), exit() |
| File Management | Open, read, write and close files | open(), read(), write(), close() |
| Device Management | Communicate with hardware devices | ioctl() |
| Memory Management | Allocate and release memory | mmap(), munmap(), brk() |
| Information Management | Retrieve system information | getpid(), getuid(), uname() |
| Communication | Exchange data between processes | pipe(), socket(), shmget() |
11. Process Control System Calls
Process control system calls are responsible for creating, executing, synchronizing and terminating processes. Every application running on Linux is represented by a process. The kernel manages these processes using process control system calls.
| System Call | Description |
|---|---|
| fork() | Create a new child process. |
| exec() | Replace the current process with another program. |
| wait() | Wait until a child process finishes. |
| exit() | Terminate the current process. |
| kill() | Send a signal to another process. |
12. File Management System Calls
Linux treats almost everything as a file. Regular files, directories, terminals, pipes and many hardware devices are accessed through the file interface. File management system calls allow an application to work with these resources.
| System Call | Purpose |
|---|---|
| open() | Open an existing file. |
| read() | Read data from a file. |
| write() | Write data into a file. |
| close() | Release the opened file. |
| lseek() | Move the current file position. |
open(). The application uses this descriptor for subsequent operations such as read(), write(), and close().
13. Device Management System Calls
Hardware devices such as cameras, keyboards, displays, storage controllers and serial ports are controlled by device drivers. Applications communicate with these drivers through device management system calls.
| System Call | Purpose |
|---|---|
| ioctl() | Send device-specific control commands. |
| read() | Receive data from a device. |
| write() | Send data to a device. |
| poll() | Monitor device events. |
14. Memory Management System Calls
Applications frequently require additional memory while running. Instead of directly manipulating physical memory, they request memory through kernel-managed interfaces.
| System Call | Description |
|---|---|
| mmap() | Map memory into the process address space. |
| munmap() | Release mapped memory. |
| brk() | Change the end of the process data segment. |
15. Information Management System Calls
Some system calls provide information about the running process or the operating system itself.
| System Call | Description |
|---|---|
| getpid() | Return Process ID. |
| getppid() | Return Parent Process ID. |
| uname() | Return operating system information. |
| time() | Return current system time. |
16. Communication System Calls
Modern operating systems allow multiple processes to communicate and exchange information. This mechanism is known as Inter-Process Communication (IPC).
| System Call | Description |
|---|---|
| pipe() | Create a communication channel. |
| socket() | Network communication. |
| shmget() | Create shared memory. |
| msgget() | Create a message queue. |
Summary
System calls can be broadly classified into six categories:
- Process Control
- File Management
- Device Management
- Memory Management
- Information Management
- Communication
Each category provides specialized services that allow applications to interact safely with operating system resources while maintaining protection, stability and efficient resource management.
17. Frequently Used Linux System Calls
Linux provides hundreds of system calls. However, a relatively small set of file-related system calls are used extensively by almost every application. These system calls allow programs to open files, read data, write data, reposition the file pointer, and release resources when finished.
| System Call | Purpose | Header File |
|---|---|---|
| open() | Open or create a file | <fcntl.h> |
| read() | Read bytes from a file | <unistd.h> |
| write() | Write bytes into a file | <unistd.h> |
| close() | Close an opened file | <unistd.h> |
| lseek() | Move the file pointer | <unistd.h> |
18. open() System Call
The open() system call requests the kernel to open an existing file or create a new one. If the request is successful, the kernel returns a File Descriptor (FD), which uniquely identifies the opened file within the process.
Syntax
#include <fcntl.h>
int open(const char *pathname,
int flags);
int open(const char *pathname,
int flags,
mode_t mode);
Parameters
| Parameter | Description |
|---|---|
| pathname | Path of the file to open |
| flags | Specifies how the file should be opened |
| mode | Permission bits when creating a new file |
Common Flags
| Flag | Meaning |
|---|---|
| O_RDONLY | Read only |
| O_WRONLY | Write only |
| O_RDWR | Read and write |
| O_CREAT | Create file if it does not exist |
| O_APPEND | Append data at the end of the file |
| O_TRUNC | Truncate the file before writing |
Example : Opening a File
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd;
fd = open("sample.txt", O_RDONLY);
if(fd == -1)
{
printf("Unable to open file\n");
return 1;
}
printf("File Descriptor = %d\n", fd);
close(fd);
return 0;
}
If the file opens successfully, the kernel returns a non-negative integer known as the file descriptor.
19. read() System Call
The read() system call copies data from the kernel into the application's buffer.
Syntax
ssize_t read(int fd,
void *buffer,
size_t count);
| Parameter | Description |
|---|---|
| fd | File Descriptor |
| buffer | Memory where data is stored |
| count | Maximum bytes to read |
Example : Reading a File
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd;
char buffer[100];
fd = open("sample.txt", O_RDONLY);
int bytes = read(fd, buffer, sizeof(buffer)-1);
buffer[bytes] = '\0';
printf("%s", buffer);
close(fd);
return 0;
}
20. write() System Call
The write() system call copies data from the application's memory into the kernel, which then stores it in the target file or sends it to the appropriate device.
Syntax
ssize_t write(int fd,
const void *buffer,
size_t count);
Example : Writing to a File
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main()
{
int fd;
fd = open("sample.txt",
O_WRONLY | O_CREAT | O_TRUNC,
0644);
char msg[] = "Welcome to Linux System Calls\n";
write(fd, msg, strlen(msg));
close(fd);
return 0;
}
21. close() System Call
When an application finishes using a file, it should release the associated kernel resources by calling close().
Syntax
int close(int fd);
22. lseek() System Call
Each opened file has a current file position maintained by the kernel. The lseek() system call changes this position, allowing applications to read or write at different locations within a file.
Syntax
off_t lseek(int fd,
off_t offset,
int whence);
| Constant | Description |
|---|---|
| SEEK_SET | Beginning of the file |
| SEEK_CUR | Current file position |
| SEEK_END | End of the file |
23. Library Functions vs System Calls
Many beginners assume that every function used in a C program directly invokes the Linux kernel. In reality, this is not the case. A Library Function is implemented in a user-space library (such as the C Standard Library). A System Call is the mechanism used to request services from the operating system kernel. Some library functions internally invoke one or more system calls, while others execute entirely in user space without entering the kernel.
| Library Function | System Call |
|---|---|
| Runs in User Space | Runs in Kernel Space |
| Provided by C Library | Provided by Operating System |
| Generally easier to use | Lower-level interface |
| May call multiple system calls | Direct kernel request |
| Portable across systems | Operating-system specific interface |
24. Example : printf() vs write()
Although both functions can display text on the terminal, they behave differently.
| printf() | write() |
|---|---|
| Library Function | System Call |
| Supports formatting | Writes raw bytes |
| Uses buffering | Generally writes directly through the kernel interface |
| Usually invokes write() internally when output is flushed | Communicates directly with the kernel |
Execution Flow : printf()
Execution Flow : write()
Unlike printf(), the write() system call does not perform formatted output. It simply transfers bytes from the application's memory to the kernel.
Example : printf()
#includeint main() { int value = 100; printf("Value = %d\n", value); return 0; }
Example : write()
#include#include int main() { const char *msg = "Hello from write()\n"; write(STDOUT_FILENO, msg, strlen(msg)); return 0; }
25. Standard File Descriptors
Whenever a Linux process starts, the kernel automatically opens three standard file descriptors.
| Descriptor | Number | Description |
|---|---|---|
| STDIN | 0 | Standard Input |
| STDOUT | 1 | Standard Output |
| STDERR | 2 | Standard Error |
26. File Descriptor Table
Each process maintains a file descriptor table. Every entry in this table corresponds to an open file, terminal, pipe, socket, or device.
The integer returned by open() is simply the index into this table.
27. Example : File Descriptor Allocation
28. Linux Terminal Demonstration
$ ls $ cat sample.txt $ echo "Hello" $ strace ./a.out $ lsof -p 1234 $ ls -l /proc/self/fd
These commands help observe how applications interact with the operating system and how file descriptors are managed during execution.
29. Common Errors
| Problem | Reason | Solution |
|---|---|---|
| open() returns -1 | File not found or permission denied | Check path and permissions |
| read() returns 0 | End of file reached | No more data available |
| write() fails | Invalid file descriptor | Verify descriptor before writing |
| Too many open files | Descriptors not closed | Always call close() |
30. Key Takeaways
- System calls are the gateway between applications and the kernel.
- Library functions and system calls are different layers of software.
- The kernel identifies open files using file descriptors.
- Every Linux process starts with standard input, output, and error descriptors.
- Properly closing file descriptors prevents resource leaks.
- Understanding file descriptors is essential for learning pipes, process creation, sockets, and device drivers.
31. Complete Life Cycle of a System Call
Every system call follows a well-defined sequence of operations. Although the requested service may differ (opening a file, reading data, creating a process, etc.), the overall execution path remains largely the same.
This sequence ensures that applications cannot directly manipulate hardware resources. Instead, every privileged operation is performed by the operating system on behalf of the application.
32. Step-by-Step Execution
| Step | Description |
|---|---|
| 1 | Application invokes a library function or system call. |
| 2 | Arguments are prepared according to the system call interface. |
| 3 | A trap instruction transfers control to the kernel. |
| 4 | The CPU switches from User Mode to Kernel Mode. |
| 5 | The kernel identifies the requested system call. |
| 6 | The requested kernel service executes. |
| 7 | The kernel places the return value in the appropriate register. |
| 8 | The CPU returns to User Mode. |
| 9 | The application resumes execution. |
33. Kernel Validation
Before performing any requested operation, the kernel validates several conditions to maintain system security and stability.
| Validation | Purpose |
|---|---|
| User Permissions | Ensure the process has sufficient privileges. |
| Memory Address Validation | Prevent invalid memory access. |
| File Descriptor Validation | Verify that the descriptor is valid. |
| Access Mode Validation | Check read/write permissions. |
| Resource Availability | Ensure the requested resource exists. |
34. Return Values
Most system calls return a value indicating whether the operation succeeded or failed.
| Return Value | Meaning |
|---|---|
| Positive Integer | Operation completed successfully. |
| Zero | Successful completion with no additional data. |
| -1 | An error occurred. |
int fd = open("sample.txt", O_RDONLY);
if (fd == -1)
{
perror("open");
return 1;
}
When a system call fails, the application can examine the associated error information to determine the reason for the failure.
35. Common Reasons for System Call Failure
| Reason | Example |
|---|---|
| Permission Denied | Attempting to open a protected file. |
| File Not Found | Specified file does not exist. |
| Invalid File Descriptor | Using a descriptor after it has been closed. |
| Insufficient Memory | Memory allocation request cannot be satisfied. |
| Device Busy | Requested hardware is already in use. |
36. System Call Overhead
A system call introduces additional work compared with a normal function call because the processor must switch execution modes and the kernel must perform validation before servicing the request.
Because of these extra steps, system calls are generally more expensive than ordinary function calls.
37. Techniques to Reduce System Call Overhead
| Technique | Benefit |
|---|---|
| Buffering | Reduce the number of write() or read() operations. |
| Batch Processing | Process multiple requests together. |
| Memory Mapping | Reduce repeated file access operations. |
| Efficient Algorithms | Minimize unnecessary kernel interactions. |
38. Real-World Example
Consider a text editor saving a document.
The application never writes directly to the storage device. The operating system performs the operation after validating the request.
39. Device Drivers and System Calls
A device driver is a kernel component that controls a specific hardware device. Applications do not communicate directly with hardware. Instead, they invoke system calls, and the kernel forwards the request to the appropriate device driver.
Each driver understands how to communicate with its corresponding hardware device and translates generic kernel requests into hardware-specific operations.
40. Responsibilities of a Device Driver
| Responsibility | Description |
|---|---|
| Hardware Initialization | Prepare the device for operation. |
| Data Transfer | Move data between hardware and memory. |
| Interrupt Handling | Respond to hardware-generated interrupts. |
| Configuration | Configure hardware settings. |
| Error Reporting | Notify the operating system about hardware errors. |
41. The /dev Directory
Linux represents many hardware devices as special files located in the /dev directory. Applications open these device files using the same system calls used for regular files.
| Device File | Description |
|---|---|
| /dev/null | Discards all written data. |
| /dev/zero | Produces an unlimited stream of zero bytes. |
| /dev/random | Provides random data. |
| /dev/video0 | Camera device. |
| /dev/tty | Terminal device. |
42. Camera Device Example
A camera application opens the camera device using a system call. The kernel forwards the request to the camera driver, which communicates with the hardware.
Once the device is opened, the application can read image frames using additional system calls.
43. Capturing an Image
| System Call | Purpose |
|---|---|
| open() | Open the camera device. |
| ioctl() | Configure camera parameters. |
| read() | Receive image data. |
| close() | Release the device. |
44. ioctl() System Call
Some devices require operations beyond reading and writing data. The ioctl() system call allows an application to send device-specific control commands to a driver.
#include <sys/ioctl.h>
int ioctl(int fd,
unsigned long request,
...);
Examples include setting camera resolution, changing serial port configuration, or controlling hardware-specific features.
45. ioctl() Execution Flow
46. Embedded Linux Example
Consider an embedded system controlling a camera module.
The application interacts only with the operating system interface. The details of image acquisition, memory transfers, and hardware control are handled by the kernel and the device driver.
47. Example Program
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("/dev/video0", O_RDONLY);
if(fd == -1)
{
perror("open");
return 1;
}
printf("Camera opened successfully.\n");
close(fd);
return 0;
}
48. Useful Linux Commands
ls /dev ls -l /dev/video0 cat /proc/devices dmesg lspci lsusb
These commands help inspect available devices, loaded drivers, and kernel messages related to hardware.
49. Key Points
- Applications communicate with hardware through system calls.
- Device drivers execute in Kernel Space.
- Linux exposes many hardware devices through the
/devdirectory. ioctl()provides device-specific control operations.- The kernel isolates applications from hardware implementation details.
50. Process-Related System Calls
One of the most important responsibilities of an operating system is managing processes. Linux provides several system calls that allow applications to create new processes, execute different programs, synchronize execution, and terminate processes. These system calls form the foundation of multitasking.
51. fork() - Creating a New Process
The fork() system call creates a new process by duplicating the currently running process. After the call completes successfully, two independent processes exist:
- Parent Process
- Child Process
fork() call.
| Return Value | Meaning |
|---|---|
| > 0 | Returned to the parent process. The value is the child's Process ID (PID). |
| 0 | Returned to the child process. |
| -1 | Process creation failed. |
52. exec() - Loading a New Program
The exec() family of system calls replaces the current program image with a new program.
Unlike fork(), exec() does not create another process. Instead, it transforms the existing process into a different program while retaining the same Process ID (PID).
exec() completes successfully, the original program does not continue executing because its code and data have been replaced.
53. wait() - Waiting for Child Processes
A parent process often needs to wait until one of its child processes completes execution. The wait() system call suspends the parent until the child terminates or changes state.
54. exit() - Process Termination
The exit() system call terminates the currently executing process. Before removing the process, the operating system performs cleanup activities such as releasing memory, closing open file descriptors, and recording the exit status.
55. Typical Process Creation Flow
56. Automotive Embedded Linux Example
Consider a vehicle infotainment system.
Each software component executes as an independent process. The operating system schedules these processes, allocates CPU time, and manages communication between them using system calls.
57. Embedded Linux Camera Pipeline
The application receives image frames through operating system services rather than communicating directly with the hardware. This abstraction improves portability, security, and maintainability.
Concept Mastery Assessment — Module 14
Verify your conceptual understanding with 12 targeted technical assessment questions. Instant feedback and explanations are provided for every choice.