Exercises

Fundamental Concept Exercises

1. The Four Basic Characteristics of an Operating System

Problem: Briefly describe the four basic characteristics of an operating system, and explain how they relate to one another.

ConcurrencySharingVirtualizationAsynchronism

Approach

Define each characteristic on its own first, then look at the dependency between them: sharing makes concurrency possible, virtualization supplies the resource abstractions that both rely on, and asynchronism is what concurrency looks like from the outside.

Steps

  1. State concurrency: several programs run during the same period of time.
  2. State sharing: the same resources are used by several concurrent programs.
  3. State virtualization: one physical entity appears as several logical ones.
  4. State asynchronism: programs advance at an unpredictable speed.
  5. Connect the four with the relationships listed below.

Answer

The four basic characteristics of an operating system are:

  1. Concurrency

    • Multiple programs or processes execute during the same period of time
    • Concurrency is realized through time slice rotation
    • It raises the utilization of system resources
  2. Sharing

    • Resources in the system can be used jointly by several concurrently running programs
    • It takes two forms: mutually exclusive sharing and simultaneous sharing
    • It involves resources such as CPU time, memory space, and peripherals
  3. Virtualization

    • A technique turns one physical entity into several logical counterparts
    • It includes CPU virtualization, memory virtualization, and device virtualization
    • It gives users more resources than the physical hardware actually provides
  4. Asynchronism

    • A program does not run to completion in one go; it advances in bursts
    • It proceeds forward at an unpredictable speed
    • Synchronization mechanisms are needed to keep the results correct

Relationships:

  • Concurrency and sharing reinforce each other, because concurrent execution needs shared resources
  • Virtualization provides the technical foundation for concurrency and sharing
  • Asynchronism is the natural consequence of concurrent execution

2. The Evolution of Operating Systems

Problem: List the stages in the evolution of operating systems in chronological order, and describe the main characteristics of each stage.

Batch ProcessingTime SharingReal-Time SystemsDistributed Systems

Approach

Walk through the generations in order. For each one, ask what the driving constraint was (hardware cost, user count, response time, geographic spread, or resource budget), because that constraint explains the architectural change that followed.

Steps

  1. Start with the manual-operation era, when there was no operating system at all.
  2. Move to batch systems, which introduced the monitor program.
  3. Continue to time-sharing systems, which brought many users online at once.
  4. Then real-time systems, which promised deterministic response.
  5. Then network systems, which linked machines together.
  6. Then distributed systems, which spread the work across machines.
  7. Finish with embedded systems, which fit into a tight resource budget.

Answer

  1. First generation: the manual-operation stage (1945-1955)

    • No operating system
    • The programmer operated the machine directly
    • CPU utilization was extremely low (below 5%)
    • Serial processing, so efficiency was extremely low
  2. Second generation: batch systems (1955-1965)

    • Introduced the monitor program
    • Jobs were processed in batches
    • CPU utilization increased
    • Less human intervention was needed
  3. Third generation: time-sharing systems (1965-1980)

    • Many users worked on the system at the same time
    • Time slice rotation
    • Interactive operation
    • Resource sharing
  4. Fourth generation: real-time systems (1980-1990)

    • Real-time response
    • Determinism
    • High reliability
    • Strong specialization to a task
  5. Fifth generation: network operating systems (1990-2000)

    • Network connectivity
    • Distributed processing
    • Resource sharing
    • Communication protocols
  6. Sixth generation: distributed operating systems (2000-2010)

    • Several computers working together
    • Transparency
    • Fault tolerance
    • Scalability
  7. Seventh generation: embedded operating systems (2010-present)

    • Strong specialization
    • Constrained resources
    • Real-time requirements
    • Power optimization

3. Kernel Mode and User Mode

Problem: Explain the difference between kernel mode and user mode, and describe the mechanism that switches between them.

Kernel ModeUser ModePrivilege LevelsMode Switching

Approach

Compare the two modes along the same axes (privilege level, instruction set, hardware access, protection), then describe the two transitions as mirrored procedures: one saves the user context and switches up, the other restores it and switches down.

Steps

  1. List the properties of kernel mode.
  2. List the properties of user mode.
  3. List the events that trigger an upward switch.
  4. List the events that trigger a downward switch.
  5. Give the step sequence for each transition.

Answer

Kernel mode:

  • The highest privilege level
  • Able to execute every instruction
  • Able to access hardware directly
  • Able to modify system state
  • Typical operations: memory management, process scheduling, device drivers

User mode:

  • A lower privilege level
  • Able to execute non-privileged instructions only
  • Unable to access hardware directly
  • Protected by the system
  • Typical operations: application execution, user data processing

The switching mechanism:

From user mode to kernel mode:

  • Trigger conditions: system calls, interrupts, exceptions, privileged instructions
  • Switching process: save the user-mode context -> switch to kernel mode -> execute kernel code

From kernel mode to user mode:

  • Trigger conditions: returning from a system call, finishing interrupt handling, finishing exception handling
  • Switching process: restore the user-mode context -> switch to user mode -> resume the user program

4. Interrupts and Exceptions

Problem: Compare interrupts with exceptions, and give examples that show where each one is used.

InterruptExceptionMaskabilityPage Fault

Approach

Separate the two by their timing first (asynchronous versus synchronous), because that single difference explains most of the other rows of the comparison. Then attach a concrete example to each concept so the distinction is memorable.

Steps

  1. Build the comparison table from five axes: timing, maskability, source, handling, priority.
  2. Give three interrupt scenarios.
  3. Give three exception scenarios.

Answer

FeatureInterruptException
When it occursAsynchronousSynchronous
MaskabilityMaskableNot maskable
SourceHardware deviceProgram execution
HandlingInterrupt service routineException handler
PriorityHas priority levelsNo priority levels

Interrupt scenarios:

  • Timer interrupt: used for time slice rotation
  • I/O interrupt: signals that an I/O operation has completed
  • Hardware fault interrupt: handles hardware errors

Exception scenarios:

  • Page fault: accessing a memory page that does not exist
  • Divide-by-zero error: a division whose divisor is zero
  • Illegal instruction: executing an instruction that does not exist

5. System Calls

Problem: What is a system call? Give examples of the common categories of system call.

System CallProcess ManagementFile OperationsInter-Process Communication

Approach

Start with the one-sentence definition of a system call, then group the API by what the caller wants to achieve — manage processes, touch files, manage memory, or talk to other processes.

Steps

  1. Define a system call as the user-space interface to kernel services.
  2. Group the well-known calls into four categories.
  3. Name the representative call of each category.

Answer

A system call is the interface the operating system offers to applications. It lets a user program ask the operating system kernel for a service.

Common categories:

  1. Process management:

    • fork(): create a child process
    • execve(): execute a program
    • wait(): wait for a child process
    • exit(): terminate the process
  2. File operations:

    • open(): open a file
    • close(): close a file
    • read(): read from a file
    • write(): write to a file
  3. Memory management:

    • brk(): resize the data segment
    • mmap(): map memory
    • mprotect(): set memory protection
  4. Inter-process communication:

    • pipe(): create a pipe
    • kill(): send a signal
    • shmget(): create a shared memory segment

Architecture Exercises

6. Comparing Operating System Architectures

Problem: Compare the advantages and disadvantages of the monolithic kernel and the microkernel, and describe the scenario each one fits.

Monolithic KernelMicrokernelInter-Process CommunicationPerformance

Approach

Use the same three axes for both architectures — performance, maintainability, and extensibility — so the comparison is symmetric. The trade-off in the end is simple: a monolithic kernel wins on speed, a microkernel wins on fault isolation.

Steps

  1. Write the advantages of the monolithic kernel, then its disadvantages.
  2. Write the advantages of the microkernel, then its disadvantages.
  3. Match each architecture to the workloads it suits.

Answer

The monolithic kernel:

Advantages:

  • High performance: no inter-process communication overhead
  • Simplicity: the architecture is simple and easy to understand
  • High efficiency: efficient memory access and small system call overhead

Disadvantages:

  • Reliability problems: a bug in one module can crash the whole system
  • Poor maintainability: high coupling between modules
  • Limited extensibility: new features are hard to add

Best fit: general-purpose operating systems such as Linux.

The microkernel:

Advantages:

  • High reliability: service isolation means a failure does not affect the whole system
  • Extensibility: new services are easy to add
  • Maintainability: independent modules that are easy to debug

Disadvantages:

  • Performance overhead: inter-process communication overhead and frequent context switches
  • Complexity: the message passing mechanism is complex
  • Compatibility: poor compatibility with existing software

Best fit: real-time and embedded systems such as QNX.

7. Choosing an Architecture

Problem: When designing a real-time embedded operating system, which architecture should you choose, and why?

MicrokernelReal-Time SystemsReliabilityExtensibility

Approach

Decide first, then justify: for a real-time embedded system the deciding factor is predictability plus isolation, which is what the microkernel provides. Back the choice up with five concrete reasons and note the cost you accept in exchange.

Steps

  1. Name the architecture: the microkernel.
  2. Justify it with reliability.
  3. Justify it with real-time behaviour.
  4. Justify it with resource efficiency.
  5. Justify it with extensibility and security.

Answer

You should choose a microkernel architecture, for the following reasons:

  1. High reliability:

    • Real-time systems demand extremely high reliability
    • The service isolation of a microkernel stops a single failing service from taking down the system
    • Recovery from a fault becomes straightforward
  2. Real-time behaviour:

    • The modular design of a microkernel makes real-time scheduling easier to implement
    • Individual services can be optimized for real-time tasks
    • Response times stay predictable
  3. Resource efficiency:

    • A microkernel loads only the services it actually needs
    • Memory footprint shrinks
    • It fits resource-constrained embedded environments
  4. Extensibility:

    • Services can be added or removed to match the application
    • Dynamic loading is supported
    • Customization becomes practical
  5. Security:

    • Service isolation provides better security
    • Fine-grained permission control can be enforced
    • It suits security-sensitive applications

Comprehensive Applied Exercises

8. How a System Call Is Implemented

Problem: Describe the implementation of a typical system call, from the moment the user program invokes it, through the execution of the kernel service, to the return into the user program.

System CallKernel ModeUser ModeRegister Passing

Approach

Follow the call across the privilege boundary in six phases. Two of them happen in user space (argument preparation, result return) and four happen in the kernel (interface entry, mode switch, service execution, mode restoration). The read() example shows the two halves of the same call.

Steps

  1. The user program prepares the arguments and the system call number.
  2. The interface traps into the kernel and the user register state is saved.
  3. The processor switches to the kernel stack and the kernel-mode flag is set.
  4. The kernel validates the arguments, checks permissions, and runs the service.
  5. The result is placed in the designated register.
  6. The user register state is restored and the program returns to user space.

Answer

The implementation of a system call:

  1. Argument preparation:

    • The user program prepares the system call arguments
    • The arguments are placed in registers or on the stack
    • The system call number is placed in the designated register
  2. Calling the interface:

    • Control enters the kernel through the system call interface
    • A switch from user mode to kernel mode is triggered
    • The user-mode register state is saved
  3. Mode switch:

    • The processor switches to the kernel stack
    • The kernel-mode flag is set
    • Control jumps to the kernel code
  4. Service execution:

    • The kernel verifies that the arguments are valid
    • It checks the user permissions
    • It executes the matching kernel service
    • It handles any error that arises
  5. Result return:

    • The result is placed in the designated register
    • The return status is set
    • The return to user mode is prepared
  6. Mode restoration:

    • The user-mode register state is restored
    • The processor switches to the user stack
    • The kernel-mode flag is cleared
    • Control jumps back to the user code

Example (the Linux read system call):

// User program
ssize_t read(int fd, void *buf, size_t count) {
    return syscall(SYS_read, fd, buf, count);
}

// Kernel handler
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) {
    struct file *file;
    ssize_t ret = -EBADF;

    file = fget(fd);
    if (file) {
        ret = vfs_read(file, buf, count, &file->f_pos);
        fput(file);
    }
    return ret;
}

9. The Interrupt Handling Mechanism

Problem: Describe the interrupt handling process in detail, including interrupt detection, context saving, execution of the interrupt service routine, and context restoration.

InterruptContext SavingInterrupt HandlerTimer Interrupt

Approach

Treat interrupt handling as a symmetrical sequence around one core event: the service routine. The first three phases get control to the kernel safely, the routine does the work, and the last three phases put everything back exactly as it was.

Steps

  1. Detect the interrupt and identify its source and type.
  2. Save the interrupted program’s context.
  3. Switch to kernel mode and the kernel stack.
  4. Look up and run the interrupt service routine.
  5. Restore the saved context.
  6. Return to the interrupted program.

Answer

The interrupt handling process:

  1. Interrupt detection:

    • The CPU notices the interrupt signal
    • It determines the interrupt source and the interrupt type
    • It checks whether the interrupt is masked
  2. Context saving:

    • The current program counter (PC) is saved
    • The program status register (PSR) is saved
    • The contents of the general-purpose registers are saved
    • Any other relevant state information is saved
  3. Mode switch:

    • The CPU switches to kernel mode
    • The processor switches to the kernel stack
    • The interrupt-handling flag is set
  4. Running the interrupt service routine:

    • The service routine is looked up by interrupt number
    • The matching interrupt handling code runs
    • The tasks associated with the interrupt are handled
    • The interrupt flag is cleared
  5. Context restoration:

    • The contents of the general-purpose registers are restored
    • The program status register is restored
    • The program counter is restored
    • The interrupt-handling flag is cleared
  6. Program return:

    • The CPU switches back to user mode
    • The interrupted program resumes execution

Example (a timer interrupt handler):

// Timer interrupt service routine
void timer_interrupt_handler(void) {
    // Update the system time
    update_system_time();

    // Check whether the time slice has run out
    if (current_process->time_slice <= 0) {
        // Schedule the next process
        schedule();
    }

    // Clear the interrupt flag
    clear_timer_interrupt();
}

10. Architecture Design Decisions

Problem: Suppose you are designing an operating system for a smartphone. Analyze which architecture you should choose, and justify your reasoning.

Hybrid ArchitectureMicrokernelModular DesignSmartphone OS

Approach

A smartphone is neither a pure desktop nor a pure embedded target: it must survive long uptimes, resist hostile apps, run many vendors’ code, and still start fast on constrained hardware. A hybrid architecture is the only design that satisfies all of those at once, so explain it as a microkernel foundation plus a modular design plus targeted performance work.

Steps

  1. Name the architecture: a hybrid one.
  2. Explain the microkernel foundation: reliability, security, modularity.
  3. Explain the modular design: extensibility, customization, maintenance.
  4. Explain the performance work: critical services, caching, hardware acceleration.
  5. Explain the user experience: fast startup, smooth operation, power saving.
  6. Sketch the resulting directory structure.

Answer

You should choose a hybrid architecture that combines the advantages of the microkernel and the modular design, for the following reasons:

1. A microkernel foundation:

  • High reliability: a smartphone has to run for long stretches without a restart
  • Security: service isolation keeps a malicious app from reaching the rest of the system
  • Modularity: different services can be loaded on demand

2. A modular design:

  • Extensibility: new feature modules can be loaded dynamically
  • Customization: different manufacturers can ship different feature sets
  • Maintainability: independent modules are easier to maintain and upgrade

3. Performance optimization:

  • Critical services: performance-critical services live in the kernel
  • Caching: caching reduces inter-process communication overhead
  • Hardware acceleration: the hardware features of the device are used fully

4. User experience:

  • Fast startup: only the necessary services are loaded
  • Smooth operation: scheduling and memory management are tuned
  • Power saving: the system adapts to how the device is being used

A concrete layout:

Smartphone Operating System
Microkernel
Process Management
Memory Management
Process Communication
Interrupt Handling
System Services
File System Service
Network Service
Graphics Service
Audio Service
Device Drivers
Display Driver
Touch Driver
Camera Driver
Sensor Driver
Applications
System Applications
Third-Party Applications
User Applications

This architecture guarantees the reliability and security of the system while still delivering good performance and a good user experience.

Found an issue with this content?

Tell us what could be improved.