Overview Flashcards
Introduction, Virtual Machines, Systems programming languages
Operating System
An operating system is a program that controls execution of application programs and acts as an interface between applications and computer hardware.
“The one program running at all times on the computer” is the kernel, core component of the operating system.
Everything else is either
- A system program, or
- An application program
An operating system is interrupt driven.
Aims of an Operating System
- Execute user programs and make solving user problems easier
- Make the computer system convenient to use
- Use the computer hardware in an efficient manner
Abstract View of Components of Computer
User
↕
Application Programs
(compilers, web browsers, development kits, etc.)
↕ ↕ ↕
Operating system
↕ ↕ ↕
Computer Hardware
(CPU, memory, I/O, etc.)
System Program
A program that is associated and ships with the operating system, but not part of the kernel.
Application Program
All programs not associated with the operating system.
Interrupt Handling
The operating system preserves the state of the CPU by storing the registers and the program counter.
Determines which type of interrupt has occurred:
- Hardware interrupt by one of the devices
- Software interrupt(exception or trap):
- Software error
- Request for operating system service – system call
Separate segments of code determine what action should be taken for each
type of interrupt
Middleware
Mobile operating systems often include not only a core kernel but also middleware—a set of software frameworks that provide additional services to application developers.
Minimalist Understanding of an Operating System
OS software is the minimum amount of software required to allow the computer to function.
kernel – usually in memory always
* process/thread management
* communications
* memory management
* file management
* security model
* device management
This is the understanding used in the course.
Maximalist Understanding of an Operating System
- All the software which comes with a standard release of the OS.
- many utilities and programs
This is the understanding that most people have about an OS.
Bus
Provides access between components and shared memory
Device Controller
Controller in charge of a specific type of device.
Depending on the controller, more than one device may be attached. A device controller maintains some local buffer storage and a set of special-purpose registers.
The device controller is responsible for moving the data between the peripheral devices that it controls and its local buffer storage.
Device Driver
Typically, operating systems have a device driver for each device controller. This device driver understands the device controller and provides the rest of the operating system with a uniform interface to the device.
The CPU and the device controllers can execute in parallel, competing for memory cycles. To ensure orderly access to the shared memory, a memory controller synchronizes access to the memory.
Multiprogramming (Batch System)
- Single program cannot always keep CPU and I/O devices busy
- Multiprogramming organizes jobs (code and data), so CPU always has one to execute
- A subset of total jobs in system is kept in memory
- One job selected and run via job scheduling
- When job has to wait (for I/O for example), OS switches to another job.
Multitasking (Timesharing)
- A logical extension of Batch systems – the CPU switches jobs so frequently that users can interact with each job while it is running, creating interactive computing.
- Response time should be < 1 second
- Each user has at least one program executing in memory → process
- If several jobs ready to run at the same time → CPU scheduling
- If processes don’t fit in memory, swapping moves them in and out to run
- Virtual memory allows execution of processes not completely in memory
Dual-Mode Operation
Dual-mode operation allows OS to protect itself and other system components
* User mode and kernel mode
* Mode bit provided by hardware
* Provides ability to distinguish when system is running user code or kernel code.
* When a user is running → mode bit is “user”
* When kernel code is executing → mode bit is “kernel”
* System call changes mode to kernel, return from call resets it to user
* Some instructions designated as privileged, only executable in kernel mode.
Transition from User to Kernel Mode
User Process
|User mode (mode bit = 1)|
User process executing
↓
Calls System Call
↓ trap mode bit = 0
|Kernel mode (mode bit = 0)|
Execute the System Call
↓ return mode bit = 1
|User mode (mode bit = 1)|
Return from System Call
Interrupt
A hardware mechanism that enables a device to notify the CPU that it needs attention.
Hardware may trigger an interrupt at any time by sending a signal to the CPU, usually by way of the system bus.
MS-DOS
An operating system structure written to provide the most functionality in the least space
* not divided into modules
* Although MS-DOS had some structure, its interfaces and levels of
functionality were not well separated
MS-DOS Structure
Application Program
↓
Resident System Program
↓
MS-DOS Device Drivers
↓
ROM Device Drivers
Monolithic Structure - Original UNIX
UNIX – limited by hardware functionality, the original UNIX operating system had limited structuring.
* The UNIX OS consists of two separable parts
* Systems programs
* The kernel
* Consists of everything below the system-call interface and above the physical hardware
* Provides the file system, CPU scheduling, memory management, and other operating-system functions; a large number of functions for one level
* Monolithic kernel - Pros/Cons
* little overhead in the system-call interface
* communication within the kernel is fast
* tightly coupled system – difficult to implement and extend.
Traditional UNIX System Structure
Shells and Commands
Compliers and Interpreters
System Libraries
—
System-Call Interface to the Kernel
—
Signals Terminal Handling, Character I/O System, Terminal Drivers, File System, Swapping Block I/O System, Disk and Tape Drivers, CPU Scheduling, Page Replacement, Demand Paging, Virtual Memory.
—
Kernel Interface to Hardware
—
Terminal Controllers | Device Controllers | Memory Controllers
—
Terminals | Disks and Tapes | Physical Memory
Layered Approach Operating System
A number of layers (levels) with specific and limited functionality, each built on top of lower layers.
* With modularity, layers are selected such that each uses functions (operations) and services of only lower-level layers
* Pros/Cons
* Simplifies verification and debugging
* Very hard to get the design correct
* Can be inefficient – lots of layers to go through to get work done.
Layered Approach Structure
- A layered design was first used in the “THE” operating system.
- Its six layers were:
Layer 5: User Programs
Layer 4: Buffering for I/O
Layer 3: Operator Console Device Driver
Layer 2: Memory Management
Layer 1: CPU Scheduling
Layer 0: Hardware
Microkernel
- Move as much from the kernel into user space
- Mach is an example of microkernel
- macOS and iOS kernel (Darwin) partly based on Mach
- Communication takes place between user modules using message passing
- Pros:
- Easier to extend a microkernel
- Easier to port the operating system to new architectures
- More reliable (less code is running in kernel mode)
- More secure
- Cons:
- Performance overhead of user space to kernel space communication
Microkernel Structure
Application Program | File System | Device Driver
↑ ↑ ↑
—
messages
↔ ⟷
Inter-process communication | Memory Management | CPU Scheduling
Microkernel
— ↕
Hardware
Windows NT Client / Server
- Windows NT provided environmental subsystems to run code written to different OS APIs.
- Windows NT (and successors) is a hybrid system.
- Parts are layered but some of the layers have been merged to improve performance.
- Many OS services are provided by user-level servers
- e.g. the environmental subsystems.
- Now in Windows 10/11 there is the Windows subsystem for Linux.
Windows NT Client / Server Structure
Win32 Application | Win32 Server | OS/2 Application | OS/2 Server | Posix Application|| Posix Application
—↑ ↑ ↑ ↑ ↑ ↑
↔ ↔ ↔
Kernel
(where each application server pair connects through the kernel)
Modules
- Many modern operating systems implement loadable kernel modules (LKMs)
- Uses object-oriented approach
- Each core component is separate
- Each talks to the others over known interfaces
- Each is loadable as needed within the kernel
- Overall, similar to layers but more flexible
- Linux, Solaris, etc.
Linux System Structure
Applications | glibc Standard C Library
—↓ ↓
System Call Interface
—↓ ↓
File Systems | CPU Scheduler | Networks (TCP/IP) | Memory Manager | Block Devices | Character
—↓ ↓
Device Drivers
—↓ ↓
Hardware
Hybrid Systems
- Most modern operating systems are not one pure model
- Hybrid combines multiple approaches to address performance, security, usability needs
- Linux and Solaris kernels in kernel address space, so monolithic, plus modular for dynamic loading of functionality
- Windows mostly monolithic, plus microkernel for different
subsystem personalities, and supports dynamically loadable
kernel modules. - Apple macOS hybrid, layered.
- The kernel consisting of Mach microkernel and BSD UNIX kernel, plus I/O kit and dynamically loadable modules (called kernel extensions)
Emulation
- Emulation used when source CPU type different from target type (i.e., PowerPC to Intel x86)
- Generally slowest method
- Interpreter translates the CPU instructions required for the source architecture and executes it on target architecture.
Virtualization
- Virtualization – OS natively compiled for CPU, running guest OSs also natively compiled
- Use cases involve laptops and desktops running multiple OSes for exploration or compatibility
- An extra level of safety – each user’s virtual machine is completely separate from all the others.
- Virtual servers - Executing and managing compute environments within data centers providing huge flexibility.
Hypervisor/ VMM (Virtual Machine Manager)
Provides virtualization services.
Host OS
The operating system which the VMM is running on (or VMM itself acts as host OS).
Guest OS
The operating system running inside a VM.
Fidelity
Software should run identically (except for speed) on the Virtual Machine as on the real machine.
Performance
Most instructions in a VM must run directly on the hardware (therefore at the same speed as on the real machine). Not the same as emulation.
Safety (AKA Resource Control)
The Virtual Machine Monitor/Manager (VMM) is in complete control of system resources and must be safe from any actions of the VM. Also, one VM must be safe from the actions of another VM.
Non VM System Model
Processes
—↓
Kernel
—↓
Hardware
VM System Model
Processes | Processes | Processes
—↓ ↓ ↓
Kernel | Kernel | Kernel
—
VM1 | VM 2 | VM 3
—↓
Hardware
Type 0 Hypervisors
- Type 0 (not universally accepted as a type)
- implemented in hardware and firmware, it loads at boot time.
- The guest OSes load into partitions separated by the hardware.
- They are allocated dedicated resources
e.g., processors, memory, devices. - Guests OSs are native with a subset of the hardware.
Type 0 Hypervisor Structure
CPUs Memory | CPUs Memory | CPUs Memory
—
Hypervisor | I/O
Type 1 Hypervisors
- Special purpose OSs that run natively on HW
- they also load at boot time and provide the optimised environment to run guest OSs
- Create run and manage guest Oss (Guests generally don’t know they are running in a VM)
- Run in kernel mode (or below)
- Implement device drivers and the guests access the devices through them
- Provide services to manage the guests - backup, monitoring
- Provide other traditional OS services like CPU and memory management
- Commonly found in company datacenters or the cloud
- Consolidation of multiple OSes and apps onto less HW
- Move guests between systems to balance performance
- Snapshots and cloning - save the states of guests and duplicate those states
- Some standard OSs can also be made to run as Type 1
Type 2 Hypervisors
- VMM is simply another process/application, run and managed by
native, installed host OS - Even the host doesn’t know they are a VMM running guests
- In modern type 2 VMs part of the VMM runs in kernel mode.
- Tend to have poorer overall performance because can’t take
advantage of some HW features - Require no changes to host OS
- e.g., VMware Workstation (or Player) and VirtualBox.
Type 2 Hypervisor Structure
Guest OS | Guest OS | Guest OS
—
Virtualisation Layer
—
Host OS
—
CPU | Memory | I/O Devices
Virtualization Implementation
- Generally difficult to provide an exact duplicate of underlying machine
- Especially if only dual-mode operation available on CPU
- But getting easier over time as CPU features and support for VMM improves
- Most VMMs implement virtual CPU (VCPU) to represent state of CPU per guest as guest believes it to be
*When guest context switched onto CPU by VMM, information
from VCPU loaded and stored
Why Trap and Emulate
- Dual mode CPU means virtual machine guest executes in user mode
- Just as the physical machine has two modes, so must the virtual
machine. - So VM needs two modes – virtual user mode and virtual kernel mode
- Both of which run in real user mode
- Actions in guest that usually cause switch to kernel mode must
cause switch to virtual kernel mode
Trap-and-emulate
- Attempting a privileged instruction in user mode causes an error -> trap
- VMM gains control, analyzes error, executes operation as attempted by guest -> emulates
- Returns control to guest in user mode
- User mode code in guest runs at same speed as if not a guest
- But kernel mode (or privileged) instructions code runs slower due to trap-and-emulate
- Especially a problem when multiple guests running, each needing trap-and-emulate
- CPUs adding hardware support (for e.g., more CPU modes) to improve
virtualization performance
Trap-and-emulate Problems
- Some CPUs don’t have clean separation between privileged and nonprivileged instructions
- Earlier Intel x86 CPUs are among them
- Consider Intel x86 popf instruction
- Loads CPU flags register from contents of the stack
- If CPU in privileged mode -> all flags replaced
- If CPU in user mode -> only some flags replaced
- No trap is generated
Binary Translation
Solves virtualization problem
1. If guest VCPU is in user mode, guest can run instructions natively
2. If guest VCPU in kernel mode (guest believes it is in kernel mode)
a) VMM examines every instruction guest is about to execute by reading a few
instructions ahead of program counter
b) Non-special-instructions run natively
c) Special instructions translated at run-time into new set of instructions that
perform equivalent task.
Why Binary Translation
- The translation is very simple (and hence efficient).
- Only translates code which is actually run.
- Much of the code is exactly the same as the original.
- The translated code is cached and reused.
- Uses all sorts of tricks to speed up emulation.
Nested Page Tables (NPTs)
- Memory management another general challenge to VMM implementations
- Common method (for trap-and-emulate and binary translation) is nested page tables (NPTs)
- Each guest maintains page tables to translate virtual to physical addresses
- VMM maintains per guest NPTs to represent guest’s page-table state
- When guest on CPU -> VMM makes that guest’s NPTs the active system page tables
- Guest tries to change page table -> VMM makes equivalent change to NPTs and its own page tables
- Can cause many more TLB misses -> much slower performance
Hardware Assistance
All virtualization needs some HW support
* More support -> more feature rich, stable, better performance of guests
* Intel added new VT-x instructions in 2005 and AMD the AMD-V
instructions in 2006
* CPUs with these instructions remove need for binary translation
* Generally, define more CPU modes – “guest” and “host”
* VMM can enable host mode, define characteristics of each guest VM, switch to guest
mode and guest(s) on CPU(s)
* CPU maintains VCPU, context switches between guests in the hardware.
* HW support for Nested Page Tables, DMA, interrupts as well over time
Application Containment (or OS Level Virtualization)
If virtualizing servers we can often use the same OS. This means we virtualize less.
* Containers look like servers – they can be rebooted separately, have their own IP addresses, root, programs etc.
* But they all use the same underlying kernel.
* And they are still separate from each other
Paravirtualization
Xen – software approach. Requires modifications to the OS source code to use the Xen layer. e.g. To read from a file the guest directly calls host read
routines.
Application Virtualization
An application runs on a layer which provides the
resources it needs even though it may be running on a different OS e.g. Wine for running programs from old versions of Windows on a newer one.
Programming-Environment Virtualization
- Implement a different architecture on top of any hardware/OS.
- Programs are compiled to the Java VM or CLR architecture then run by either compiling or interpreting that code.
- Earlier versions – late 70’s UCSD Pascal system
Windows Subsystem for Linux V1
NT kernel (underneath all versions of Windows for the last 25 years or more) was designed to run programs written for more than 1 OS API (Win32, OS/2, Posix).
* Uses user level pico processes and corresponding kernel drivers
Windows Subsystem for Linux V2
- Two main problems with the initial version of WSL.
- I/O was slow - all file access had to be translated from Linux calls into
corresponding Windows calls. - The Linux kernel wasn’t there (so we couldn’t add Linux kernel modules into the subsystem, e.g., FUSE).
- The solution was to revert to a more traditional Linux running in a VM on top of Hyper-V (which is part of most installations of Windows).
C
C is designed for OS implementation:
* Ken Thompson and Dennis Ritchie converted UNIX from assembly language to C to provide portability.
* Close to the hardware.
* Low-level access to memory
* Maps easily to machine instructions
* Easy to inline assembly language code (depends on the compiler)
* Has small requirements for runtime support
* Sometimes referred to as a high-level assembler.
Direct Access to Memory
- C pointers can have integers assigned to them
- This means that actual addresses can be stored in a pointer and then used to access that address
- Memory mapped devices can then be controlled directly from normal C.
Memory Layout of A C Program
Stack
—
↓
↑
Heap
—
Uninitialized Data
—
Initialized Data
—
Text (Low Memory)
The GNU Size command Can be used to find the size of sections
Accessing Registers
You can use the “register” storage class specifier to say that a variable should
be kept in a processor register. e.g. register long number = 1234;
* This does not guarantee that a value is stored in a register, it depends on the number of available registers.
* Also, compilers optimize register usage well, and programmers rarely work at this level of
optimization.
* Memory mapped registers can be accessed directly using pointer manipulation
Volatile
- Volatile is a type qualifier
volatile unsigned char *reg; - The variable may change in a non-local way, the compiler doesn’t know whether the value has changed or not between references.
- The compiler is not allowed to optimize accesses. Every single read must go back to the
main store to retrieve the current value. - memory mapped device registers
- values modified in interrupt routines
- values modified in another thread
Memory Management
- All local variables disappear when functions are returned from.
- Space is allocated on the stack for the variables in each function invocation.
- There is a limit to the size of the stack (especially for extra threads as each thread
needs its own stack) - Areas of static memory
- Global variables
- Static variables - can be static in a file or in a function.
- If in a function it maintains its value even when the function is returned from
- The advantage of static memory is that it is allocated at compile time and hence
has no allocation overhead at run time. - The disadvantage is that it cannot easily be released.
Dynamic Memory
- C requires explicit control of dynamic memory.
- This is suitable for OS programming as there is no garbage collection available.
- garbage collection adds a layer of complexity and unpredictability to the
programming environment - this is important in small systems - such as embedded systems (or phones?)
- especially important in real-time systems
To allocate memory we use malloc (or calloc). - To deallocate memory, we use free.
free(thread);
Running Commands From C Program
- Because of the large number of standard useful commands in Unix it is helpful to
be able to use them from inside C programs. - Type man system
- e.g.
system(“ps -x”); - This creates a shell and gets it to execute the command.
- If you need to use the output (or provide input) in your program, you need to
use the popen C function.
C++
Some operating systems are written in C++. Sometimes with a small section in C. Windows has a C kernel with C++ (and some C#) outside this.
Objective C
MacOS was written in C with Objective-C on top, also some C++ and in more recent versions Swift.
Java
Some operating systems are written largely (but not exclusively) in Java.
Assembly
The original operating system implementation language.
Rust
A popular new systems programming language.