Introduction To Operating Systems
Introduction To Operating Systems
An operating system is a program that manages the computer hardware. It also provides a
basis for application programs and acts as an intermediary between the computer user and
computer hardware.
➢ Mainframe OS are designed primarily to optimize utilization of hardware.
➢ Personal Computer (PC) operating systems support complex games, business
applications and everything in between.
➢ Operating systems for handheld computers are designed to provide an environment in
which a user can easily interface/ interact with the computer to execute programs.
Thus, some operating systems are designed to be convenient, others to be efficient, and
others some combination of the two.
Spooling
Spooling is the acronym for Simultaneous Peripheral Operations Online. I/O devices are
relatively slow compared to the CPU. So, involving CPU in receiving and sending
information through I/O devices may waste valuable time of CPU. Therefore, instead of
involving CPU for input and output of data, if we reserve some space in the secondary
memory (disk) wherein we can directly store the input information received from multiple
input devices, CPU can spend time wholly in executing programs. Whenever the
information received from peripheral devices stored in the disk is required by the CPU, it
can be loaded into the main memory and can be used thereafter for processing. After the
usage, the output data can be stored back into the disk, which can later be sent to the
peripheral output devices directly from the disk. Thus, non-involvement of CPU in I/O of
information through peripheral devices increases the processing speed.
Dual-Mode Operations
To ensure the proper execution of the operating system, we must be able to distinguish
between the execution of operating system code and user-defined code. The approach taken
by most computer systems is to provide hardware support that allows us to differentiate
among various modes of execution. We need two separate modes of operation:
➢ User mode (non-privileged mode)
➢ Kernel mode (supervisor/ system/privileged/ protected/ monitor mode)
A bit called the mode bit, is added to the hardware of the computer to indicate the current
mode: kernel (0) or user (1). With the mode bit, we can distinguish between a task that is
executed on behalf of the operating system and one that is executed on behalf of the user.
When the computer system is executing on behalf of a user application, the system is in
user mode. However, when a user application requests a service from the operating system
(via a system call), there must be a transition from user to kernel mode to fulfill the request.
As we shall see, this architectural enhancement is useful for many other aspects of system
operations as well.
At system boot time, the hardware starts in kernel mode. The operating system is then
loaded and starts user applications in user mode. Whenever a trap or interrupt occurs, the
hardware switches from user mode to kernel mode (i.e., changes the state of mode bit to 0).
Thus, whenever the operating system gains control of the computer, it is in kernel mode.
The system always switches to user mode (by setting the mode bit to 1) before passing
control to a user program.
The dual mode of operation provides us with the means for protecting the operating system
from errant users. We accomplish this protection by designating some of the machine
instructions that may cause harm as privileged instructions.
System Calls
System calls provide an interface to the services made available by an operating system.
These calls are generally available as routines written in C and C++ although certain low-
level tasks (for example, tasks where hardware must be accessed directly), may need to be
written using assembly language instructions. Before how an operating system makes
system calls available, lets first use an example to illustrate how system calls are used:
writing a simple program to read data from a file and copy them to another file.
As we can see, even simple programs may make heavy use of the operating system.
Frequently, systems execute thousands of system-calls per second.
Most programmers never see this level of details. However, typically application developers
design programs according to an Application Programming Interface (API). The API
specifies a set of functions that are available to an application programmer including the
parameters that are passed to each function and the return values the programmer can
expect. Three of the most common APIs available to application programmers are the
Win32 API for windows systems, the POSIX API for POSIX – based systems (which
includes virtually all versions of UNIX, LINUX, and MacOS X), and the Java API for
designing programs that run on the Java virtual machine.
Each operating system has its own name for each system call. Behind the scenes, the
functions that make up an API typically invoke the actual system calls on behalf of the
application programmer. For example, the Win32 function Create Process() (which
unsurprisingly is used to create a new process) calls the NT Create Process() system call in
the Windows kernel.
Why would an application programmer prefer programming according to an API rather that
invoking actual system calls? There are several reasons for doing so. One benefit of
programming according to an API concerns program portability: an application programmer
is designing a program using an API can expect her program to compile and run on any
system that supports the same API (although, architectural differences often make this more
difficult than it may appear). Furthermore, actual system calls can often be more detailed
and difficult to work with than the API available to an application programmer.
The run-time support system (a set of functions built into libraries included with a compiler)
for most programming languages provides a system call interface that serves as the link to
system calls made available by the operating system. The system call interface intersects
function calls in the API and invokes the necessary system call within the operating system.
The system call interface then invokes the intended system call in the operating system
kernel and returns the status of the system call and any return values.
The caller needs to know nothing about how the system call is implemented or what it does
during execution. Rather, it just needs to obey the API and understand what the operating
system will do because of the execution of the system call. Thus, most of the details of the
operating system interface are hidden from the programmer by the API and are managed by
the runtime support library. The relationship between an API, the system call interface and
the operating system are shown in the figure above which illustrates how the operating
system handles a user application invoking the open() system call.
System calls occur in different ways depending on the computer in use. Often, more
information is required than simply the identity of the desired system call. The exact type
and amount of information vary according to the particular operating system and call.
Three general methods are used to pass parameters to the operating system. The simplest
approach is to pass the parameters in registers. In some cases, however, there may be more
parameters than registers. In these cases, the parameters are generally stored in a block or
table, in memory, and the address of the block is passed as parameter in a register. This is
the approach taken by LINUX and SOLARIS. Parameters also can be placed or pushed
onto the stack by the program and popped off the stack by the operating system.
Some operating systems prefer the block or stack method, because those approaches do not
limit the number or length of parameters being passed.
Interrupts
There are two types of Interrupts:
➢ Interrupt: Interrupt is hardware generated which changes the flow of execution within
the system. Interrupt handler deals with hardware generated interrupts to control such
interrupts. Interrupt can be used to signal the completion of I/O.
❖ External event
❖ Asynchronous event
❖ Independent of the currently executed process instructions
❖ Ex: Clock Interrupt, I/O interrupt and Memory fault.
➢ Trap: Trap is a software generated signal either to call operating system routines or to
catch the arithmetic errors.
❖ Exceptions and system calls
❖ Synchronous event
❖ Internal (exceptions) events or external events
Booting of OS
Hardware doesn’t know where the operating system resides and how to load it. Hence it
needs a special program to do this job i.e., a
bootstrap loader. Ex: BIOS (Boot Input Output
System). Bootstrap loader locates the kernel,
loads it into main memory and starts its
execution. In some systems, a simple
bootstrap loader fetches a more complex boot
program from disk, which in turn loads the
kernel.
Booting Process
➢ Reset event on CPU (power up, reboot) causes instruction register to be loaded with a
predefined memory location. It contains a jump instruction that transfers execution to
the location of Bootstrap program.
➢ This program is form of ROM, since RAM is in unknown state at system startup. ROM
is convenient as it needs no initialization and can't be affected by virus.
➢ Run diagnostics to determine state of machine. If diagnostics pass, booting continues.
➢ Runs a Power-On Self-Test (POST) to check the devices that the computer will rely on,
are functioning.
➢ BIOS goes through a preconfigured list of devices until it finds one that is bootable. If it
finds no such device, an error is given and the boot process stops.
➢ Initializes CPU registers, device controllers and contents of the main memory. After
this, it loads the OS.
➢ On finding a bootable device, the BIOS loads and executes its boot sector. In the case of
a hard drive, this is referred to as the Master Boot Record (MBR).
➢ The MBR code checks the partition table for an active partition. If one found, the MBR
code loads that partitions boot sector and executes it.
➢ The boot sector is often operating system specific, however in most operating systems
its main function is to load and execute a kernel, which continues to startup.
➢ If there is no active partition or the active partition’s boot sector is invalid, the MBR
may load secondary boot load and pass control to it and this secondary boot loader will
select a partition (often why user input) and load its boot sector.
➢ Examples of secondary boot loaders:
❖ GRUB: GRand Unified Bootloader
❖ LILO: LInux LOader
❖ NTLDR: NT LoaDeR
➢ Systems such as cellular phones, PDAs and game consoles store entire OS on ROM.
Done only for small OS, simple supporting hardware, and rugged operation.
➢ Changing bootstrap code would require changing ROM chips.