A few more details on our picture from last lecture:
Terminology: the hardware in a device that operates the device (and communicates with the main CPU) is the device controller. It can be as simple as a few gates and a latch (as with the keyboard) or as complex as the CPU itself (in the case of a modern GPU)
With memory-mapped I/O, devices only interact with the CPU, not with main memory. For devices that handle large amounts of data, it is useful to allow the devices to interact directly with main memory. For example, a disk drive can handle a read by copying the data directly to memory without involving the CPU. This approach is referred to as direct memory access (DMA).
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:
by a trap. All traps do two things: set the privilege bit, and jump to a handler routine defined by the operating system, (the interrupt handler, system call handler, or the exception handler as appropriate)
There are three kinds of traps:
interrupts from devices occur when the interrupt line is activated. The interrupt handler will typically invoke a driver to interact with the device.
system calls from applications occur when a syscall instruction is executed. The application will include additional information (such as a system call number) indicating what operation the application is requesting
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.
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.
A program is the code defining an executable. It can be stored in a file, loaded into memory, downloaded from the internet.
A process is a running program. In addition to the code, it has state: the values of registers, and a virtual address space. If you run a program twice, you will create two processes (but there will only be one program).
application is a fuzzy term that I will use when I don't want to make a distinction.
For each process, the OS maintains a process control block (PCB), containing the saved state of the registers, the saved virtual memory information (such as a base/bounds register or a page table base register, more on this when we discuss memory).
The operating system gives the illusion of running multiple processes simultaneously by timesharing the CPU: rapidly switching between running processes.
Before running a user process, the kernel will set a hardware timer. When that timer expires, it will raise an interrupt. The interrupt handler routine will save the state of the currently running process into its PCB, then select another process to run, load its state into the processor, and then execute a return from syscall instruction to branch to the new process.
The PCB stores all of the information the OS needs about a process. This includes (but is not limited to):