Lecture 2
If you have in depth questions, or want to explore points
of confusion, or points of interest, please come to my
office hours, and I'd be happy to help you.
--Tatyana Ryutov
Address Space
Address space is divided between user space in kernel space, which is done
in the interest of protection.
User mode is an example of sandboxing.
Each user level process has its own sandbox, in which there is an address space.
Anything outside of address space, can't be accessed by anyone else but
the kernel.
The only way a user level process can access something within the kernel space
is if it requests access through a syscall.
A process that spawns within kernel space, just like any other process, has
its own process control block table.
A process that spawns within user space is sandboxed, but those spawning in
kernel space exist in what's known as the "playground," which is not sandboxed.
A kernel level process can access memory beyond its allocated address space.
Each operating system has only one process control block table. Within this
table are entries, one for every process that has spawned on the operating
system. This PCB table is stored in memory. For xv6, a PCB table is structed
in the form of an array, but other operating systems store it as a linked list.
Principles of operating system design
- Abstractions: simplified encapsulations of the complexities contained
therein.
- Mechanisms: operations performed upon an abstraction.
- Policies: define rules governing when/how mechanisms occur
- The separation of mechanisms from the policies governing them. Policies may
change, which is why it is important to have a separation between a
mechanism, "how a process is performed", and a policy, "when a process is to
be performed." Both may change, but they typically change at different times,
and for different reasons. It makes the operating system more flexible,
allowing it to accommodate new workloads, or quickly port/adapt to new
technologies.
- The principle of least privilege, which requires that for a given
abstraction, every module (such as a process, a user, or a
program) can only access the information and resources that are
necessary for it to achieve its legitimate purpose.
- The separation of implemention from interface, which allows you to change the
implementation independently of the interface, making adapting to changing
requirements far more flexible.
- Design for the typical, anticipate the unusual. Edge cases may occur, but
design your process so that it will handle what commonly occurs in a robust,
efficient way.
- Practice indirection, the management of increasing complexity through the
introduction of new layers of abstraction. Indirection can be applied to
solve every problem, with one exception: the reduction of excessive layers of
indirection.
Do not confuse the separation of principle and interface with the separation
of mechanism and policy
System Calls
- syscall
- an interface between user and OS servicees
System calls are one of the offerings an OS provides as an illusionist
Programs access system calls via high level APIs, which are wrappers around the
real system call being performed.
- xv6 makes some of its system calls in C, but uses assembly to make others.
There are a few main categories of syscalls
- process control
e.g. fork() - device management
e.g. ioctl() - file management
e.g. open() - information maintenance
getpid() - communications
pipe() - protection
chmod()
A particular syscall might fall into multiple categories. For instance, read()
can be used for both device management and file management
An operating system typically has hundreds of different syscalls.
The names vary based on which operating system used. For instance, fork() in
Linux is called CreateProcess() in Windows.
Common Linux syscalls include fork(), exit(), wait(), open(), sleep(),
chmod(),
Implementation of a syscall
Note: there will be more details provided next level.
The runtime support system, typically the compiler, provides the instructions
that interface with the actual system call.
- A syscall generates a trap, which invokes the kernel, who takes over,
addresses the syscall, and eventually returns control back to the user.
Much like processes, files are another form of abstraction provided by the
kernel.
Every syscall is associated with a particular number, stored in a table, which a
library (glibc) translates into the syscall made to the operating system. For
this reason, syscalls are an example of separation of interface from
implementation.
xv6 only has about 20 syscalls, and you'll be adding additional syscalls.
Context Switching
- the act of switching the CPU from one active process to a different process
- there are 3 steps:
- save state of current process
- load state of other process
- continue execution of that loaded process
Processor State
- The current content of the CPU registers
Kernel Organization
- Monolithic
- macOS, Linux, Windows
- it's fast because the kernel manages everything except applications, which are added in user mode.
- it's not reliable, it's not secure, just has good performance.
- Layered
- file system, virtual memory, etc., all separated from each other.
- HAL Hardware Abstraction Layer
Dynamically Installed Device Drivers
- Goal: accommodate a wide variety of physical I/O devices
Virtual Machines
Host: the underlying hardware system or OS
Hypervisor: manages the resources of the underlying hardware and provides an abstraction of one or more virtual machines
Guest: the software running within the OS
- All guest software (including the guest OS) run in user mode
Network Interface Controller NIC: a computer hardware component that connects a computer to a computer network. Early network interface controllers were commonly implemented on expansion cards that plugged into a computer bus
Containers are popular because they use fewer resources than virtual machines, the package code and dependencies are bundled together, typically run by application system kernel. A light weight standalone virtual machine. Docker is a container technology from 2012, open source, very popular. Container image becomes container at runtime. They run in the docker image, they virtualize the operating system, instead of virtualizing the hardware.
Hardware Interrupts
NMI, Non-Mask Interrupt: can't be blocked
- No other interrupts can interrupt it.
- Must complete the handler, even another NMI can't interrupt the NMI handler.
Hardware interrupts, peripheral device sends a signal through a specified pin to the processor
Have an interrupt table, stores the code for that happens during a specified interrupt.
CPU Fetch-Execute Cycle
- Interrupts can happen while we are executing an instruction. We won't stop mid-instruction execution to handle an interrupt.
Hypervisors
There are two main types of hypervisors, type-1 and type-2
- Type-1, native or bare-metal hypervisors
- These hypervisors run directly on the host's hardware to control the
hardware and to manage guest operating systems. For this reason, they are
sometimes called bare metal hypervisors. The first hypervisors, which
IBM developed in the 1960s, were native.
- Type-2 or hosted hypervisors
- These hypervisors run on a conventional operating system (OS) just as other
computer programs do. A guest operating system runs as a
process on the host computer. Type-2 hypervisors
abstract guest operating systems from the host operating system.
Parallels Desktop for Mac, QEMU, VirtualBox, VMware Player
and VMware Workstation are examples of type-2 hypervisors.
Type 1 hypervisors run directly on the hardware, and for this reason are more
efficient, and more secure. For this reason, they are popular in data centers,
and cloud service providers.
- In this environment, syscalls made by one of the apps within one of the
virtual machines within a type-1 hypervisor will go directly to the
hypervisor, which sends it to the guest OS, which returns it to the
hypervisor, which sends it back to the app within the VM. In total, there
are 4 hops.
- Less secure, more lines of code, Linux has around 15,000,000 lines of code
Type 2 hypervisors are less efficient, but more convenient for end-users.
- When a syscall is made by one of the apps within one of the virtual machines
within a type-2 hypervisor, it will go directly to the host OS, which sends
it to the hypervisor, which sends it back to the host OS, which sends it to
the guest OS, which sends it back to the host OS, which sends it to back to
the app. In total, there are 8 hops.
- More secure, fewer lines of code, KVM has a mere 10,000 lines of code
| | Performance | Reliability / Security | Flexibility |
|---|
| type 1 | good | good | bad |
| type 2 | bad | bad | good |
Questions
Question 1
- student -> CPU
- program -> book
- library reading room -> memory
- librarian -> OS
- book check out record -> process control block
Question 2
We need syscalls in order to give an operating system the ability to reject a
user-level process from making a harmful requests, be they unintentional/benign
or intentional/malicious. A user-level process may want to access memory that it
ought not be able to, or perhaps ought to, but not until later.
Question 3
When choosing a kernel organization approach, the main tradeoff OS designers
face are typically between three factors
- Performance
- Security / Reliability
- Flexibility
I would choose security because computers typically become more performant as
the underlying hardware gets better and better each year.
Question 4
If I had the choice between multi-boot and VM, I would choose dual-boot if I was
familiar with both operating systems equally, and I didn't need to switch
between one another. If either of those things weren't true, however, I'd use a
virtual machine instead.
Question 5
How could we utilize hardware rings to improve protection for type 1
hypervisors?
There are four hardware rings, which we could allocate as follows:
- Hypervisor
- Guest OS software
- Device drivers
- User level applications