The term operating system is commonly used with two distinct meanings:
- The entire software package that manages a computer’s resources, along with all other software tools such as CLI and GUI utilities, file managers, and system programs.
- More narrowly, the central software that manages and allocates computer resources β specifically the CPU, RAM, and peripheral devices.
The term kernel is typically used for the second, narrower meaning. Programs can technically run on a system without a kernel, but the presence of a kernel greatly simplifies implementation, enhances resource management, and expands the power and flexibility available to programmers.
The kernel is the heart of the operating system. Below are the eight core tasks it is responsible for:
A computer has one or more CPUs to execute program instructions. Linux is a multitasking operating system, meaning multiple processes can reside in memory simultaneously, each receiving CPU time.
More precisely, Linux is a preemptive multitasking operating system β the kernel decides which process receives the CPU and for how long. This is handled by the kernel’s process scheduler, not by the processes themselves.
Physical memory (RAM) is a limited resource that must be shared among multiple processes. It is the kernel’s responsibility to manage and allocate RAM efficiently across all running processes.
Virtual memory management is one of the most powerful features of modern operating systems. Linux employs virtual memory techniques that offer these advantages:
- All processes run in isolation from one another and from the kernel β one process cannot read or modify the memory of another.
- Only the currently needed portion of a process needs to be kept in RAM, reducing memory requirements and allowing more processes to load simultaneously β improving CPU utilisation.
The kernel provides a file system layer that enables users and applications to create, read, update, and delete files. It abstracts the underlying storage hardware and provides a unified interface for file operations.
The kernel can load a new program into memory and provision the necessary resources (CPU time, memory) for it to run. A program in an executing state is called a process. Once a process finishes, the kernel cleans up and releases all allocated resources for reuse.
When devices such as a mouse, monitor, or keyboard are connected, the kernel loads the appropriate device drivers and provides a controlled interface so multiple processes can access these devices safely.
The kernel is responsible for transmitting and receiving network packets on behalf of user processes. This includes routing outgoing packets to the target system and delivering incoming packets to the appropriate process.
Processes make requests to the kernel through well-defined entry points called system calls. This API is the controlled gateway through which user-space programs interact with kernel services.
Modern processors support two operational modes for the CPU: user mode and kernel mode (also called supervisor mode). This distinction is enforced at the hardware level.
- Hardware instructions allow switching between user mode and kernel mode.
- When the switch occurs, the respective virtual memory areas are marked as either user space or kernel space.
| User Mode | Kernel Mode |
|---|---|
| CPU can only access memory marked as user space | CPU can access both user and kernel memory |
| Attempting to access kernel memory causes a hardware exception | Full access to hardware, devices, and privileged instructions |
| Cannot execute privileged instructions (e.g., halt) | Can execute all CPU instructions including halt and I/O |
| Runs regular application code | Runs kernel code, drivers, and system call handlers |
If a process needs to perform a privileged operation β such as halting the system, accessing memory management structures, or performing direct I/O β it must transition to kernel mode. User-space code is not allowed to directly access kernel instructions or kernel data structures.
When a system is running, there are typically many processes active simultaneously. Multiple activities happen asynchronously, and a running process does not know in advance when it will next be scheduled for CPU time.
- A process does not know where in RAM it is loaded, nor whether parts of it are in the swap area.
- A process accesses files by name, not by knowing where on disk the file is stored.
- A process cannot create another process directly or terminate itself without kernel assistance.
- Processes cannot communicate directly with I/O devices β all such communication goes through the kernel via system calls.
- Signals and IPC (inter-process communication) events are handled by the kernel.
The kernel maintains several critical data structures to manage running processes:
- The kernel decides which process gets the CPU next and for how long.
- It maintains data structures with information about all running processes, continuously updating them as processes are created, change state, or terminate.
- It maps virtual memory addresses to physical memory locations and tracks swap areas on disk.
A shell is a Command Line Interface (CLI) program designed to read commands from the user, execute them, and return the output. It is commonly referred to as a command interpreter.
In essence, a shell takes commands from the user, executes them, and displays the result. There are several shell types available in Linux:
| # | Shell Name | Command |
|---|---|---|
| 1 | Bourne Shell | sh |
| 2 | C Shell | csh |
| 3 | Korn Shell | ksh |
| 4 | Bourne Again Shell β most widely used | bash |
Linux is a multi-user operating system, meaning each user on the system is uniquely identified and users may belong to different groups.
Every user has a unique login name and a numeric User ID (UID). This information is stored in /etc/passwd, which contains:
- Login name β unique username
- User ID (UID) β unique numeric identifier
- Group ID (GID) β ID of the primary group
- Home Directory β initial directory after login
- Login Shell β program used to interpret commands
Users can be organised into groups. Group information is stored in /etc/group, which contains:
- Group Name β unique name of the group
- Group ID (GID) β numeric ID of the group
- User List β login names of all users in this group
The superuser is a special privileged account with UID 0 and the login name root. It bypasses all permission checks in the system, allowing unrestricted access to any file or resource regardless of permissions. Used exclusively for system administration.
The kernel maintains a single hierarchical directory structure to organise all files. The root directory / is the top of the hierarchy. All files and directories are children (direct or indirect) of the root.
| Directory | Purpose |
|---|---|
/ |
Root directory β top of the entire file system |
/home |
User home directories (e.g., /home/ravi) |
/etc |
System-wide configuration files |
/bin |
Essential command binaries (ls, cp, mv, etc.) |
/usr |
User programs, libraries, and documentation |
/var |
Variable data such as logs and cache files |
/tmp |
Temporary files (cleared on reboot) |
/dev |
Device files representing hardware |
/proc |
Virtual filesystem exposing kernel and process information |
ls # List directory contents
ls -l # Detailed listing with permissions and sizes
cd /path # Change to specified directory
mkdir dir # Create a new directory
rmdir dir # Remove an empty directory
In Linux, everything is treated as either a process or a file. Common file types include:
A directory is a special type of file that contains references to other files or directories β think of it as a folder that organises files hierarchically.
π Key Points:
- Linux uses a single-rooted tree structure starting from
/ - Everything in Linux is treated as a file, including directories and devices
- Directories map file names to inode numbers β metadata pointers to actual data on disk
A hard link is an additional directory entry pointing to the same inode as the original file.
- Multiple filenames share the same inode
- File data persists until all hard links are removed
- Cannot link to directories
- Cannot cross file system boundaries
ln original.txt hardlink.txt# Check inode numbers
ls -li# Output β both share the same inode
123456 original.txt
123456 hardlink.txt
If you delete the original file with rm original.txt, hardlink.txt still works because the underlying data still exists on disk.
A symbolic link (symlink) is a special file that contains the path to another file or directory.
- Points to a file path, not directly to an inode
- Can link to directories
- Can cross file system boundaries
- Becomes a broken (dangling) link if the target is deleted or moved
ln -s original.txt symlink.txt# Check the link
ls -li# Output
symlink.txt β original.txt
If original.txt is deleted, symlink.txt becomes a broken (dangling) link.
| Feature | Hard Link | Symbolic Link |
|---|---|---|
| Points to | Same inode as original | File path (not inode) |
| Cross filesystems | β No | β Yes |
| Link directories | β No | β Yes |
| Survives original deletion | β Yes (data remains) | β No (becomes broken) |
| Command | ln original link |
ln -s original link |
π‘ When to Use Which?
- Hard Links β when you need the same data accessible under multiple names
- Symbolic Links β for shortcuts, config references, and build system redirects
A pathname specifies the location of a file or directory in the Linux file system. It shows how to navigate to a particular file using / as the separator.
An absolute pathname provides the full path from the root directory / to the target file or directory.
- Always begins with /
- Independent of the current working directory
- Always unambiguous
/home/user/project/main.c
A relative pathname specifies the path relative to the current working directory.
- Does not start with /
- Depends on your current directory (check with
pwd) - Uses
.for current directory and..for parent directory
./scripts/build.sh
| Absolute Path | Relative Path |
|---|---|
Starts with / |
Does not start with / |
| Independent of current directory | Depends on current directory |
| Always unambiguous | Meaning changes based on your location |
/home/user/file.txt |
../file.txt (if in /home/user/subdir) |
In Linux, every file or directory has an owner and is associated with a group.
- Owner (User) β the user who owns the file, generally the creator
- Group β a group of users who share access rights to the file
| Symbol | Permission | For Files | For Directories |
|---|---|---|---|
r |
Read | View file contents | List directory contents |
w |
Write | Modify file contents | Create or delete files inside |
x |
Execute | Run file as a program | Access / traverse directory |
Permissions are assigned to three categories: Owner, Group, and Others.
–rwxr-xr–rwx β Owner: read, write, execute
r-x β Group: read, execute only
r– β Others: read only
chmod 755 file # owner=rwx, group=r-x, others=r-x
chown user file # Change file owner
chgrp group file # Change file group
Linux uses a uniform file I/O model where everything is treated as a file β including regular files, directories, devices, pipes, and sockets. I/O is performed using file descriptors and system calls.
A file descriptor is a small non-negative integer that uniquely identifies an open file within a process. Three standard descriptors are automatically available to every process:
| Descriptor | Name | Description |
|---|---|---|
0 |
stdin | Standard Input β reads from keyboard by default |
1 |
stdout | Standard Output β writes to terminal by default |
2 |
stderr | Standard Error β outputs error messages to terminal |
These are the low-level I/O system calls provided by the Linux kernel:
open() β Opens a file and returns a file descriptor.
read() β Reads data from a file descriptor into a buffer.
write() β Writes data from a buffer to a file descriptor.
The stdio library provides high-level, buffered I/O built on top of system calls. It uses FILE* pointers instead of raw file descriptors β easier to use and better performance through buffering.
fgets(buf, size, fp);
fprintf(fp, “Hello”);
fclose(fp);
| System Calls (Low Level) | stdio Library (High Level) |
|---|---|
| Uses file descriptors (int) | Uses FILE* pointer |
open(), read(), write(), close() |
fopen(), fgets(), fprintf(), fclose() |
| No buffering by default | Buffered by default (better performance) |
| Closer to kernel, more control | Easier to use for most applications |
Command line arguments are inputs passed to a program when it is executed from the terminal. They allow you to control program behaviour without modifying the source code.
In C, command line arguments are accessed via main() parameters:
- argc (argument count) β total number of arguments including the program name
- argv (argument vector) β array of strings containing each argument
argv[0]is always the program name itself
Command entered in terminal:
Values available in your program:
argv[0] = “./myprog”
argv[1] = “file.txt”
argv[2] = “10”
Explore more free Linux kernel programming and embedded systems tutorials on EmbeddedPathashala β completely free, forever.
I hope you are clear with fundamentals of linux system programming, in next lecture we will discuss more about linux system programming concepts
Free learning to all !!
EmbeddedPathashala.
