xv6笔记:chapt2 Operating system organization
Requirements for an OS
support several activities at once
multiplexing: time-share the resources of the computer among these processes, every process has a chance to execute.
isolation: if one process has a bug and malfunctions, it shouldn’t affect processes that don’t depend on the buggy process
interaction: for instance, pipelines
Focus
This chapter focus on the mainstream designs centered around a monolithic kernel.(used by many operating systems like linux)
xv6 runs on RISC-V microprocessor, RISC-V is a 64-bit CPU, and xv6 is written in “LP64”C.
RISC-V reference: https://riscv.org/technical/specifications/
The Support Hardware
Xv6 is written for the support hardware simulated by qemu’s “-machine virt” option
hardware includes:
- RAM
- ROM containing boot code
- serial connection to the keyboard/screen
- disk
Abstracting physical resources
why need strong isolation?
- the applications may not be well behaved (we do not trust application to periodically give up the CPU)
- the applications may have bugs
How to achieve strong isolation?
- forbid applications from directly accessing sensitive hardware resources
- instead to abstract the resources into services
Example 1
for example, Unix applications interact with storage only through the file system’s open, read, write, close system calls, instead of reading and writing disk directly.
- application will not pay attention to the details, they only need pathnames.
Example 2
the details are transparent to the application
- the applications don’t have to be aware of the time sharing
- Unix transparently switches hardware CPUs among processes
Example 3
- Unix processes use exec to build up their memory image(instead of directly interacting with physical memory)
- let the OSto decide where to place a process in memory
- OS may also store some of a process’ s data on disk if the memory is tight
Example 4
- many forms of interaction among Unix processes occur via file descriptors.
- file descriptors abstract away many details (where data in a pipe is stored)
- file descriptors simplify the interactions ( if one application in a pipeline fails, the
kernel generates an end-of-file signal for the next process in the pipeline)
User mode, supervisor mode, and system calls
Three modes in RISC-V
- machine mode :
- full privilege
- CPU starts in machine mode
- this mode is intended for configuring a computer
- supervisor mode:
- execute privileged instructions :
- such as enabling and disabling interrupts
- reading and writing the register that holds the address of a page table
- the software in supervisor mode can also execute privileged instructions and is said to be running in kernel space
- The software running in kernel space (or in supervisor mode) is called the kernel.
- It is important that the kernel control the entry point for transitions to supervisor mode; (avoid the malicious application)
- user mode
Kernel organization
monolithic kernel
the entire operating system resides in the kernel ( linux )
advantages
- convenient, OS designer doesn’t have to decide which part of OS doesn’t need full hardware privilege
- easier for different parts of the operating system to cooperate
- high performance to OS-intensive applications , because subsystems of the kernel can be tightly integrated
disadvantages
- interfaces between different parts of the operating system is complex
- easy for os developer to make a mistake
microkernel
kernel is simple (Minix, L4, QNX), used widely in ebedded settings
- minimize the amount of operating system code that runs
- execute the bulk of the operating system in user mode
- This organization allows kernel to be relatively simple
in the above picture, file system runs as a user-level process
OS services running as processes are called servers
application interacts with the server by an inter-process communication mechanism to send messages from one user-mode process to another
the kernel interface consists of a few low-level functions for starting applications, sending messages, accessing device hardware, etc
Which one is better?
It depends
- faster performance (mono)
- smaller code size
- reliability of the kernel (micro)
- reliability of the complete operating system
Code: xv6 kernel organization
It is kind of simple surprisingly. With about 30 files, you can build a real world kernel!
The inter-module interfaces are defined in defs.h
Process overview
In Unix OS, the unit of isolation is process
process abstraction can prevent one process from destroying or spying on another process’s memory, CPU, file descriptors, etc.
process abstraction also prevents a process from wrecking the kernel itself
process abstraction needs to be carefully designed and implemented so that no buggy or malicious applications may trick the kernel or hardware into doing something bad (for example, avoiding isolation)
key design ideas in abstracting process
- an address space to give a process the illusion of its own memory
- a thread to give the process the illusion of its own CPU
In xv6, a process consists of one address space and one thread, in the real world, a process may have more than one thread to take advantage of multiple CPUs
mechanism to implement process
the user/supervisor mode flag
address spaces
time-slicing of threads
How to enforce isolation?
provides the illusion to a program that it has its own private machine
provides a program with what appears to be a private memory system, or address space
so other process cannot read or write
How to implement process in xv6?
xv6 uses page tables(which are implemented by hardware ) to give each process its own address space.
The RISC-V page table translates (or “maps”) a virtual address (the address that an RISC-V instruction manipulates) to a physical address (an address that the CPU chip sends to main memory).
each process has a separate page table that defines process’s address space. Process’s address space includes:
- user memory starting at address 0
- instructions
- global variables
- stack
- heap
- At the top of the address space xv6 reserves a page for a trampoline and a page mapping the process’s trapframe.
transition into kernel and back
xv6 use these two pages to transition into the kernel and back:
- the trampoline page contains the code to transition in and out of the kernel
- a page mapping the process’s trapframe is necessary to save/restore the state of the user process
What limit the maximum size of a process’s address space?
- pointers on the RISC-V are 64 bits wide
- hardware only uses low 39 bits
- xv6 only uses 38 of those 39 bits
- Thus, the maximum address is 2^38 - 1 = 0x3fffffffff , which is MAXVA, (kernel/riscv.h)
The process state structure in xv6
- xv6 maintains many pieces of state for each process:
struct proc
(kernel/proc.h) - the most important pieces of kernel state:
- page table
- kernel stack
- run state
- use notation:
p->xxx
to refer to the elements of the proc structure - p->state indicates whether the process is allocated, ready to run, running, waiting for I/O, or
exiting. - p->pagetable holds the process’s page table, in the format that the RISC-V hardware expects.
Thread and Process
- each process has a thread of execution which can be suspended and later resumed.
- much of the state of a thread is stored on the thread’s stacks.
- each process has two stacks:
- user stack
- kernel stack(p->kstack): when the process enters the kernel, the kernel code executes on the process’s kernel stack
- Thread alternates between actively using its user stack and its kernel stack
- The kernel stack is separate and protected from user code, so that even if a process has wrecked its user stack, the kernel can execute.
Code: starting xv6, the first process and system call
How the kernel starts and runs the first process?
- initialize itself
- run a boot loader (stored in read-only memory), the boot loader loads the xv6 kernel into memory
The loader loads the xv6 kernel into memory at physical address 0x80000000. (because the address range 0x0:0x80000000 contains I/O devices )
- in machine mode, the CPU executes xv6 starting at
_entry
(kernel/entry.S)
The RISC-V starts with paging hardware disabled: virtual addresses map directly to physical addresses.
The instructions at _entry
set up a stack so that xv6 can run C code.
Xv6 declares space for an initial stack,
stack0
, in the file start.c. The code at_entry
loads the stack pointer registersp
with the addressstack0+4096
, the top of the stack, because the stack on RISC-V grows down.
- Now kernel has a stack.
_entry
calls into C code atstart
start performs some configuration that is only allowed in machine mode, and then switches to supervisor mode
- Before jumping into supervisor mode, it programs clock chip to generate timer interrupts.
- start “returns” to supervisor mode by calling
mret
. This causes the program counter to change to main - main initializes several devices and subsystems
- main then creates the first process by calling
userinit
- In the first process, it makes the first system call exec loads the number into register a7 and calls
ecall
to re-enter the kernel
- the kernel use the number stored in a7 to call the desired system call
- the system call table maps SYS_EXEC to sys_exec
- exec replaces the memory and registers of the current process with the new program
- In this case, the new program will be the following, once the kernel has completed
exec
, it returns to user space in the/init
process. - Init creates a new console device if needed, then open it as file descriptors 0,1,2. Then it starts a shell on the console. The system is up.
Security Model
How operating system deals with buggy or malicious code?
Typical security assumptions and goals
for user code
for kernel code
Kernel code is expected to be bug-free
certainly to contain nothing malicious
Real life things are not so straightforward
It’s difficult to prevent clever user code from making a system unusable (or causing it to panic) by consuming kernel-protected resources – disk space, CPU time, process table slots, etc.
It’s usually impossible to write bug-free code or design bug-free hardware;
- Post title:xv6笔记:chapt2 Operating system organization
- Post author:sixwalter
- Create time:2023-08-05 11:14:26
- Post link:https://coelien.github.io/2023/08/05/course-learning/MIT6.S081/chapt2/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.