Unit-1 Ertos
Unit-1 Ertos
An operating system is a software that manages computer hardware and software resources and provides
common services for computer programs. Here are some of the primary functions of an operating system:
1. Memory management: The operating system manages the allocation of memory to different
programs and processes. It ensures that each program gets the required amount of memory and
prevents programs from accessing memory that belongs to other programs.
2. Process management: The operating system manages the creation, execution, and termination of
processes. It schedules processes and assigns them CPU time, manages process synchronization,
and ensures that processes do not interfere with each other.
3. File system management: The operating system manages the storage and retrieval of files on disk.
It provides a file system that organizes files and directories, controls access to files, and ensures
that files are saved and retrieved correctly.
4. Device management: The operating system manages the interaction between computer
hardware and software. It communicates with device drivers to control input/output operations,
manages the allocation of devices to processes, and handles device errors and interrupts.
5. User interface: The operating system provides a user interface that allows users to interact with
the computer. This interface can take the form of a graphical user interface (GUI) or a command-
line interface (CLI).
6. Security: The operating system provides security features that protect the system and its data
from unauthorized access and malicious software. This includes authentication and authorization
mechanisms, access controls, and encryption.
7. Networking: The operating system provides networking services that allow computers to
communicate with each other over a network. This includes managing network connections,
protocols, and devices.
8. Error handling: The operating system handles errors and exceptions that occur during the
operation of the computer. It provides error messages and alerts, logs errors, and takes corrective
action where possible.
9. Resource allocation: The operating system manages the allocation of system resources, such as
CPU time, memory, and disk space, to different processes and programs. It ensures that resources
are used efficiently and fairly.
10. System configuration: The operating system allows administrators to configure system settings
and parameters, such as startup options, user accounts, and network settings. This allows the
system to be customized for different environments and use cases.
2. Multi-user and multi-tasking: Linux can support multiple users and processes at the same time,
without compromising performance or stability. This makes it ideal for use in servers,
workstations, and other environments where multiple users need to access shared resources and
applications simultaneously.
3. Customizable: Linux is highly configurable, and users can choose from a wide range of graphical
user interfaces (GUIs), shells, text editors, and other tools to create a personalized computing
environment. Users can also modify the source code of the kernel and other software
components to tailor them to their specific needs.
4. Secure: Linux has several built-in security features, including robust access controls, encrypted file
systems, and firewalls. Additionally, because the source code is open and available for review,
security vulnerabilities can be identified and fixed more quickly than in closed-source software.
5. Stability: Linux is designed to be stable and reliable, even under heavy loads or in high-availability
environments. It uses a modular architecture that allows for efficient resource management and
automatic recovery from failures, reducing the risk of system crashes or downtime.
6. Compatibility: Linux is compatible with a wide range of hardware platforms, from smartphones
and tablets to servers and supercomputers. It also supports a variety of programming languages
and development frameworks, making it a versatile platform for software development.
7. Command-line interface: Linux provides a powerful command-line interface that allows users to
perform complex tasks quickly and efficiently, without the need for a GUI. This can be especially
useful in server or headless environments where a graphical interface is not available.
8. Package management: Linux includes package management tools that make it easy to install,
update, and remove software packages. These tools also handle dependency resolution, ensuring
that all necessary software libraries and components are installed and configured correctly.
9. Community support: Linux has a large and active community of developers and users who provide
support, documentation, and help for users. This community includes forums, wikis, mailing lists,
and other resources that can help users solve problems and learn more about the operating
system.
10. Scalability: Linux is highly scalable and can be used in a wide range of environments, from small
embedded systems to large data centers. Its modular architecture and efficient resource
management make it well-suited for high-performance computing and other demanding
applications.
Linux architecture- monolithic kernel and microkernel
Linux is an open-source operating system that is based on the UNIX operating system. It is designed to be
modular, with different components providing different functions. The Linux kernel is the core of the
operating system, and it provides the basic services and hardware abstraction necessary to support the
system's other components.
Hardware abstractions are sets of routines in software that provide programs with access to hardware
resources through programming interfaces. In computers, a hardware abstraction layer (HAL) is a layer
of programming that allows a computer OS to interact with a hardware device at a general or abstract
level rather than at a detailed hardware level. HAL can be called from either the OS's kernel or from a
device driver.
There are two main types of kernels used in operating systems: monolithic kernels and microkernels. Linux
uses a monolithic kernel.
A monolithic kernel is a kernel architecture in which all operating system services, such as process
management, memory management, and device drivers, run in kernel space. This means that all operating
system services share the same address space and can access each other's data and functions directly.
This architecture makes the kernel larger and more complex than a microkernel, but it can provide better
performance and lower overhead because there is less communication between the kernel and user
space.
In a microkernel architecture, only the most essential services, such as process scheduling and inter-
process communication, run in kernel space. Most operating systems services, such as file systems and
device drivers, run in user space as separate processes. This architecture makes the kernel smaller and
simpler than a monolithic kernel, but it can have a higher overhead because there is more communication
between the kernel and user space.
The Linux kernel is a monolithic kernel, but it also includes some features that are typically associated with
microkernels. For example, Linux has a loadable module system that allows device drivers and other
kernel components to be loaded and unloaded dynamically at runtime. This makes it possible to add or
remove functionality from the kernel without having to recompile the entire kernel. Additionally, Linux
provides a user-space driver framework that allows device drivers to run in user space instead of kernel
space, reducing the risk of crashes and security vulnerabilities.
The Linux kernel is the core component of the operating system and manages the hardware resources of
the system. There are two main types of kernel architectures: monolithic and microkernel.
1. Monolithic kernel architecture: In the monolithic kernel architecture, the entire operating system
runs in kernel space. This means that all the device drivers, system calls, and other operating
system functions run in a single address space. This approach provides efficient communication
between kernel components but can also cause stability issues if a single component crashes, as
it can bring down the entire system.
The Linux kernel is primarily a monolithic kernel, but it does include some modular components that can
be loaded and unloaded at runtime, allowing for more flexibility and easier maintenance.
2. Microkernel architecture: In the microkernel architecture, the operating system is broken down
into small, independent modules that run in user space. These modules communicate with each
other using message passing, which can be slower than direct function calls but provides better
isolation and fault tolerance.
Microkernel-based operating systems are typically more modular and easier to maintain than monolithic
kernels, but they may suffer from performance issues due to the overhead of message passing between
modules.
There have been attempts to create a microkernel-based version of Linux, such as the GNU Hurd, but they
have not yet achieved widespread adoption.
1. Monolithic kernel architecture: In a monolithic kernel architecture, all the operating system
services, device drivers, and system call interfaces run in kernel space. The kernel space is a
protected area of memory that can only be accessed by the operating system kernel. The user
space, on the other hand, is where user applications and processes run.
In this architecture, the kernel components are tightly integrated, providing efficient communication and
fast response times. However, a problem with any kernel component can affect the entire system, leading
to stability issues.
As you can see from the figure, all the kernel components are located in the kernel space, which is
protected from user applications and processes.
2. Microkernel architecture: In a microkernel architecture, the operating system is broken down into
small, independent modules that run in user space. These modules communicate with each other
using message passing, as shown in the diagram.
In a microkernel architecture, the kernel only provides basic services, such as message passing and
memory management. All other services, such as device drivers and file systems, run as separate user
space modules. This architecture provides better isolation and fault tolerance, but it can suffer from
performance issues due to the overhead of message passing between modules.
Various differences between the Microkernel and Monolithic Kernel are as follows:
2. The microkernel runs user and kernel services in different address spaces. On the other hand, the
monolithic kernel runs both kernel and user services in the same address space. In microkernels,
only essential processes like IPC, memory management, and scheduling take place in kernel space.
3. The execution of the microkernel is slower because communication between the system's
application and hardware is established by message passing. On the other hand, the execution of
the monolithic kernel is faster because the system call establishes the communication of the
system's application and hardware.
4. Microkernels use the messaging queues to achieve IPC. On the other hand, monolithic kernels use
sockets and signals to achieve IPC.
5. The microkernel size is small than the monolithic kernel because only the kernel services run in
the kernel address space. On the other hand, the monolithic kernel size is larger because both
user and kernel services run in the same address space.
6. The microkernels are more secure than the monolithic kernels because the operating system is
unchanged if a service fails in a microkernel. On the other hand, if a service fails in a monolithic
kernel, the entire system fails.
7. The microkernel is simple to extend as new services are added in user address space, which is
separate from kernel space, and thus the kernel doesn't need to be updated. On the other hand,
the complete kernel must be updated if a new service is used in a monolithic kernel.
8. Microkernel designing needs less code which leads to fewer errors. In contrast, the monolithic
kernel requires more code which leads to more errors.
Here, you will learn the head-to-head comparison between the Microkernel and Monolithic Kernel. The
main differences between the Microkernel and Monolithic Kernel are as follows:
Basic It implements kernel and user services It implements both user and kernel
in different address spaces. services in the same address space.
Security It is more secure than the monolithic It is less secure than the microkernel.
kernel.
Stability A single process failure does not affect In a monolithic kernel, if a service fails,
other processes. the entire system fails.
Extendible It is easy to extend. It is hard to extend.
Inter-Process Communication Microkernels use the The monolithic kernels use signals and
messaging queues to achieve IPC. sockets to achieve IPC.
Example Symbian, L4Linux, K42, Mac OS X, Linux, BSDs, Solaris, OS-9, DOS,
PikeOS, HURD, etc. OpenVMS, etc.
Conclusion
Both kernel architectures have many benefits and limitations. So, there is no simple solution as to which
is better and must be used. The goals and requirements should choose the kernel style. Other types of
kernels have Nano kernels, hybrid kernels, and Exo-kernels.
Linux Operating system: File I/O-open, create, close, lseek, read, write
File I/O is a crucial component of any operating system, and Linux provides a rich set of file I/O functions
that can be used to read from and write to files. Here are some of the most commonly used file I/O
functions in Linux:
1. open(): The open() function is used to open a file, and it returns a file descriptor that can be used
to refer to the open file in subsequent I/O operations. The function takes three arguments: the
file path, a set of flags that determine how the file should be opened (e.g., read-only or write-
only), and an optional mode argument that specifies the file permissions if the file is being created.
2. create(): The create() function is used to create a new file, and it returns a file descriptor that can
be used to refer to the new file. The function takes two arguments: the file path and a set of flags
that determine how the file should be created (e.g., with read-and-write access or with write-only
access).
3. close(): The close() function is used to close an open file, and it takes a single argument: the file
descriptor of the file to be closed.
4. lseek(): The lseek() function is used to change the current file offset for a given file descriptor. The
function takes three arguments: the file descriptor, the offset from the beginning of the file, and
a set of flags that determine how the offset should be applied (e.g., relative to the current position
or the end of the file).
5. read(): The read() function is used to read data from an open file into a buffer. The function takes
three arguments: the file descriptor, a pointer to the buffer that will receive the data, and the
maximum number of bytes to read.
6. write(): The write() function is used to write data from a buffer to an open file. The function takes
three arguments: the file descriptor, a pointer to the buffer containing the data to be written, and
the number of bytes to write.
In addition to these basic file I/O functions, Linux also provides a number of other related functions, such
as truncate(), which can be used to truncate a file to a specified length, and sync(), which can be used to
flush file data to disk. These functions can be used to build more complex file I/O operations in Linux
applications.
1. open():
The open() function is used to open a file, and it returns a file descriptor that can be used to refer to the
open file in subsequent I/O operations. The function takes three arguments:
flags: A set of flags that determine how the file should be opened. The flags can be combined
using the bitwise OR operator. Some of the most commonly used flags are:
O_RDONLY: Open the file in read-only mode
mode: If the O_CREAT flag is used, this argument specifies the file permissions to be used for the
new file.
Here's an example of using the open() function to open a file in read-only mode:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd;
char buf[1024];
fd = open("example.txt", O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
printf("%s\n", buf);
close(fd);
return 0;
}
This code opens the file "example.txt" in read-only mode, reads up to 1024 bytes from the file into a
buffer, and prints the contents of the buffer to the console. Finally, it closes the file using the close()
function.
2. create():
The create() function is used to create a new file, and it returns a file descriptor that can be used to refer
to the new file. The function takes two arguments:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd;
char buf[] = "Hello, world!\n";
fd = creat("example.txt", 0644);
if (fd < 0) {
perror("creat");
exit(1);
}
close(fd);
return 0;
}
This code creates a new file called "example.txt" with read and write permissions for the owner and read
permissions for everyone else. It then writes the string "Hello, world!" to the file using the write() function,
and finally closes the file using the close() function.
3. close():
The close() function is used to close an open file, and it takes a single argument:
int main() {
int fd;
fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
/* ... */
if (close(fd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
return 0;
}
close(fd)
4. lseek():
The lseek() function is used to change the current file position within an open file, and it takes three
arguments:
whence: The reference point to use for the seek operation. This can be one of the following values:
Here's an example of using the lseek() function to set the current file position to the beginning of a file:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd;
off_t pos;
fd = open("example.txt", O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
pos = lseek(fd, 0, SEEK_SET);
if (pos < 0) {
perror("lseek");
exit(1);
}
/* ... */
close(fd);
return 0;
}
This code opens the file "example.txt" in read-only mode, sets the current file position to the beginning
of the file using lseek(), and then closes the file using close() function.
5. read():
The read() function is used to read data from an open file into a buffer, and it takes three arguments:
Here's an example of using the read() function to read data from a file:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int fd;
char buf[1024];
ssize_t nread;
fd = open("example.txt", O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
printf("%s\n", buf);
close(fd);
return 0;
This code opens the file "example.txt" in read-only mode, reads up to 1024 bytes from the file into a buffer
using read() function, and then prints the contents of the buffer to the console.
6. write():
The write() function is used to write data from a buffer to an open file, and it takes three arguments:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd;
char buffer[] = "This is a test.";
ssize_t bytes_written;
close(fd);
return 0;
}
In this example, we first define a buffer containing the data we want to write to the file. We then call the
open() function with the O_WRONLY flag to open the file in write-only mode, O_CREAT flag to create the
file if it doesn't exist, and O_TRUNC flag to truncate the file to zero length if it already exists. The third
argument (0644) specifies the file permissions.
We then call the write() function, passing the file descriptor returned by open(), the buffer containing the
data we want to write, and the size of the buffer. If write() returns -1, it means an error occurred, and we
print an error message using perror() and exit the program. Finally, we close the file using the close()
function.
This program will write the string "This is a test." to a file named "example.txt" in the current working
directory.