Lecture 3: processes, isolation, context switching

Processes

Terminology:

Each process has its own address space; some region of memory that it controls. One possible way to manage this is by splitting memory into large chunks, and using registers to indicate the start and end of the currently running process's region. These registers are called base and limit registers.

We will also allocate a region of space for the operating system itself; this is often referred to as "kernel space".

Each process also has some state that lives in the processor: the register file (including the stack pointer, instruction pointer, etc.), and the processor flags. If we save all of the processor state, we can reload it later; from the program's perspective, nothing will have changed.

Keeping track of processes

For each process, the OS maintains a process control block (PCB) (a data structure that lives in kernel space), containing the saved state of the registers, the saved virtual memory information (such as base/limit registers or a page table base register, more on this when we discuss memory).

The PCB stores all of the information the OS needs about a process. This includes (but is not limited to):

The kernel will typically organize PCBs into different queues based on their state; this way it is easy to select a new process to schedule (by looking in the ready queue), or to make runnable when input is provided (by looking at the appropriate waiting queue).

Privilege mode and traps

In order to make it possible for the operating system to provide isolation and access control, the processor has a special "privilege bit" that prevents certain instructions from being executed. There are many words meaning that a cpu has this bit set:

The processor will prevent certain instructions from executing when the privilege bit is cleared. For example:

The privilege bit is set in two ways:

There are three kinds of traps:

The privilege bit is cleared by a special "return from system call" instruction, which the OS will execute when it is done processing a trap or done with initialization.

Terminology:

Writing an operating system

If you want to write an operating system, you have to write four functions: the initialization routine, the interrupt service routine, the system call handler routine, and the exception handler routine. That is the entire interface that you need to implement.

Typically, the initialization routine will:

The init process typically reads some configuration files, and forks off other processes such as the shell, servers, etc.

The system call handler routine will: - save the caller-saved registers (like a function call) - look at the arguments to the call to determine what is being requested - determine whether the request is authorized (by comparing the permissions in the running process's PCB with the operation being requested) - execute the request - either return to the requesting process, or (if the process needs to wait) saving the state to the PCB and moving it to the waiting queue

Exception and interrupt handlers are similar to system call handlers, except that the program is not expecting them, so the handler routines must save all of the processor state immediately.

Kernel design

Terminology:

We noted a few alternative designs for an operating system: