OS Organization
OS must arrange for isolation between the processes. If one process has a bug and fails, it shouldn’t affect others that don’t depend on the failed process.
An operating system must fulfill three requirements: multiplexing, isolation, and interaction.
Abstracting physical resources.
Three modes that CPU supports
CPUs provide hardware support for strong isolation. For example, RISC-V has three modes in which the CPU can execute instructions: machine mode, supervisor mode, and user mode.
Instructions executing in machine mode have full privilege; a CPU starts in machine mode. Machine mode is mostly intended for configuring a computer.
In supervisor mode the CPU is allowed to execute privileged instructions: for example, enabling and disabling interrupts, reading and writing the register that holds the address of a page table, etc.
An application can execute only user-mode instructions.
App wants to invoke a kernel function (system call)
An application that wants to invoke a kernel function (e.g., the read system call in xv6) must transition to the kernel. CPUs provide a special instruction that switches the CPU from user mode to supervisor mode and enters the kernel at an entry point specified by the kernel. (RISC-V provides the ecall
instruction for this purpose.)
Kernel control the entry point for transitions to supervisor mode for security reasons.
Process Overview
The unit of isolation in xv6 is a process.
Layout of a user process
Each process has its own separate page table.
Xv6 runs on RISC-V with 39 bits for virtual addresses, but uses only 38 bits. Thus, the maximum address is 2 38 − 1 = 0x3fffffffff, which is MAXVA (kernel/riscv.h:349).
Lifetime
Each process has a thread of execution (or thread for short) that executes the process’s instructions. A thread can be suspended and later resumed. To switch transparently between processes, the kernel suspends the currently running thread and resumes another process’s thread (context switch).
Start xv6 and run the first process
Kernel start
When the RISC-V computer powers on, it initializes itself and runs a boot loader which is stored in read-only memory. The boot loader loads the xv6 kernel into memory. Then, in machine mode, the CPU executes xv6 starting at _entry (kernel/entry.S:12). Xv6 starts with the RISC-V paging hardware disabled: virtual addresses map directly to physical addresses.
The boot loader loads the xv6 kernel into memory at physical address 0x80000000, because the address range 0x0:0x80000000 contains I/O devices.
The instructions at _entry set up a stack so that xv6 can run C code. The code at _entry loads the stack pointer register sp with the address
stack0+4096
, the top of the stack, because the stack on RISC-V grows down.Now xv6 has a stack, and able to run C code.
_entry calls into C code at start (kernel/start.c:21).
Perform some configurations that is only allowed in machine mode.
Set Program Counter to
main
.Disable paging by set
satp
to 0.Enable clock interrupts.
Switch to supervisor mode and jump to
main()
.
First process
In main
, after initializes several devices and subsystems, it creates the first process by calling userinit
.
The 1st process executes a small program: initcode
. In code, we have
The above is the octal data format of the binary built from initcode.S
.
initcode.S
:
The above initcode
program re-enters kernel by invoking exec
system call to run a new program init
.
The init
:
This program creates file descriptors 0, 1, 2. Start a console shell. Wait for shell exists, and repeat.
Now the system is up!
Last updated