A modern, general-purpose computer system consists of a CPU and a number of device controllers and adapters that are connected through a common bus that provides access to shared memory.
(Figure 2.1).
For a computer to start running it needs to have an initial program to run. This initial program,or bootstrap program, tends to be simple.
bootstrap program
interrupt
For each type of interrupt, separate segments of code in the operating system determine what action should be taken, and an interrupt service routine is provided to deal with the interrupt.
The straightforward method for handling this transfer would be to invoke a generic routine to examine the interrupt information and then call the interrupt-specific handler.
However, because only a predefined number of interrupts is possible, a table of pointers to interrupt routines can be used instead.
A system call is invoked in a variety of ways, depending on the functionalityprovided by the underlying processor. In all forms, it is the method used by a process to request action by the operating system. A system call usually takes the form of a trap to a specific location in the interrupt vector.
I/O Structure
General-purpose computer system consists of a CPU and multiple device controllers that are connected through a common bus.
Depending on the controller, there may be more than one attached device. For instance, seven or more devices can be attached to the small computer-systems interface (SCSI) controller.
A device controller maintains some local buffer storage and a set of special-purpose registers.
The device controller is responsible for moving the data between the peripheral devices that it controls and its local buffer storage.
The size of the local buffer within a device controller varies from one controller to another, depending on the particular device being controlled. For example, the size of the buffer of a disk controller is the same as or a multiple of the size of the smallest addressable portion of a disk, called a sector, which is usually 512 bytes. Currently, 2MB to 8MB disk controller buffers are common.
I/O Interrupts
synchronous I/O
I/O is started; then, at I/O completion, control is returned to the user process.
asynchronous I/O
Returns control to the user program without waiting for the I/O to complete. The I/O then can continue while other system operations are occurring.
Two I/O methods: (a) synchronous, and (b) asynchronous.
( Figure 2.3 )
Whichever approach is used, waiting for I/O completion is accomplished in one of two ways. Some computers have a special wait instruction that idles the CPU until the next interrupt. Machines that do not have such an instruction may have a wait loop:
Loop: jmp Loop
This tight loop simply continues until an interrupt occurs, transferring control to another part of the operating system. Such a loop might also need to poll any I/O devices that do not support the interrupt structure but that instead simply set a flag in one of their registers and expect the operating system to notice that flag.
If the CPU always waits for I/O completion, as it does when the synchronous approach is used, only one I/O request can be outstanding at a time.
A better alternative is to start the I/O and then continue processing other operating- system or user program code—the asynchronous approach.
A system call is then needed to allow the user program to wait for I/O completion, if desired. If no user programs are ready to run, and the operating system has no other work to do, we still require the instruction or waitidle loop, as before.
We also need to be able to keep track of many I/O requests at the same time. For this purpose, the operating system uses a table containing an entry for each I/O device: the device-status table.
(Figure 2.4).
Each table entry indicates the device's type, address, and state (not functioning, idle, or busy).
If the device is busy with a request, the type of request and other parameters will be stored in the table entry for that device.
Since it is possible for other processes to issue requests to the same device, the operating system will also maintain a wait queue—a list of waiting requests—for each I/O device.
An I/O device interrupts when it needs service.(completion of an I/O request) When an interrupt occurs, the operating system first determines which I/O device caused the interrupt. It then indexes into the I/O device table to determine the status of that device and modifies the table entry to reflect the occurrence of the interrupt.
If there are additional requests waiting in the queue for this device, the operating system starts processing the next request.
Example - keyboard input
It should be clear that the main advantage of asynchronous I/O is increased system efficiency. While I/O is taking place, the system CPU can be used for processing or starting I/Os to other devices. Because I/O can be slow compared to processor speed, the system makes efficient use of its facilities.
Direct memory access (DMA)
Direct memory access (DMA) is used for high-speed I/O devices. After setting up buffers, pointers, and counters for the I/O device, the device controller transfers an entire block of data directly to or from its own buffer storage to memory, with no intervention by the CPU. Only one interrupt is generated per block, rather than the one interrupt per byte generated for low-speed devices.
Main Memory
Main memory and the registers built into the processor itself are the only storage that the CPU can access directly.There are machine instructions that take memory addresses as arguments, but none that take disk addresses. Therefore, any instructions in execution, and any data being used by the instructions, must be in one of these direct-access storage devices. If the data are not in memory, they must be moved there before the CPU can operate on them.
Memory-mapped I/O.
Ranges of memory addresses are set aside and mapped to the device registers. Reads and writes to these memory addresses cause the data to be transferred to and from the device registers. This method is appropriate for devices that have fast response times, such as video controllers. In the IBM PC, each location on the screen is mapped to a memory location. Displaying text on the screen is almost as easy as writing the text into the appropriate memory-mapped locations.
I/O ports
Memory-mapped I/O is also convenient for other devices.The CPU transfers data through these kinds of devices by reading and writing a few device registers, called I/O ports.
rogrammed I/O (PIO)
To send out a long string of bytes through a memory-mapped serial port, the CPU writes one data byte to the data register, then sets a bit in the control register to signal that the byte is available. The device takes the data byte and then clears the bit in the control register to signal that it is ready for the next byte. Then the CPU can transfer the next byte. The CPU may use polling to watch the control bit, constantly looping to see whether the device is ready; this method of operation is called programmed I/O (PIO).
Interrupt driven
If the CPU does not poll the control bit, but instead receives an interrupt when the device is ready for the next byte, the data transfer is
interrupt driven.
Cache
Registers that are built into the CPU are generally accessible within one cycle of the CPU clock. Most CPUs can decode instructions and perform simple operations on register contents at the rate of one or more operations per clock tick. The same cannot be said of main memory, which is accessed via a transaction on the memory bus. Accessing memory may take many cycles of the CPU clock, in which case the processor normally needs to stall, since it does not have the data required to complete the instruction that it is executing. Because memory is accessed so frequently, this situation is intolerable. The remedy is to add fast memory between the CPU and main memory. A memory buffer used to accommodate a speed differential, called a cache.
cache coherency
In a hierarchical storage structure, the same data may appear in different levels. For example, suppose that integer A is located in file B, which resides on magnetic disk. Integer A is to be incremented by 1. The increment operation proceeds by first issuing an I/O operation to copy the disk block on which A resides to main memory. Next, A is copied to the cache and to an internal register. Thus, the copy of A appears in several places: on the magnetic disk, in main memory, in the cache, and in an internal register (see Figure 2.7). Once the increment takes place in the internal register, the values of A in the various storage systems differ. The values become the same only after the new value of A is written from the internal register back to the magnetic disk.
In such an environment, a copy of A may exist simultaneously in several caches.We must make sure that an update to the value of A in one cache is immediately reflected in all other caches where A resides. This situation is called cache coherency, and it is usually a hardware problem (handled below the operating-system level).
Dual-Mode Operation
At system boot time, the hardware starts in monitor mode. The operating system is then loaded and starts user processes in user mode. Whenever a trap or interrupt occurs, the hardware switches from user mode to monitor mode (that is, changes the state of the mode bit to 0). Thus, whenever the operating system gains control of the computer, it is in monitor mode. The system always switches to user mode (by setting the mode bit to 1) before passing control to a user program.
The dual mode of operation provides us with the means for protecting the operating system from errant users—and errant users from one another. We accomplish this protection by designating some of the machine instructions that may cause harm as privileged instructions. The hardware allows privileged instructions to be executed.only in monitor mode. If an attempt is made to execute a privileged instruction in user mode, the hardware does not execute the instruction but rather treats it as illegal and traps it to the operating system.
system call
The concept of privileged instructions also provides the means for a user program to ask the operating system to perform tasks that are reserved to the operating system on the user program's behalf. Each such request is invoked by the user executing a privileged instruction. Such a request is known as a system call (also called a monitor call or an operating-system function call)
When a system call is executed, it is treated by the hardware as a software interrupt. Control passes through the interrupt vector to a service routine in the operating system, and the mode bit is set to monitor mode. The system-call service routine is a part of the operating system. The monitor examines the interrupting instruction to determine what system call has occurred; a parameter indicates what type of service the user program is requesting. Additional information needed for the request may be passed in registers, on the stack, or in memory (with pointers to the memory locations passed in registers). The monitor verifies that the parameters are correct and legal, executes the request, and returns control to the instruction following the system call.
The lack of a hardware-supported dual mode can cause serious shortcomings in an operating system. For instance, MS-DOS was written for the Intel 8088 architecture, which has no mode bit and, therefore, no dual mode. A user program running awry can wipe out the operating system by writing over it with data; and multiple programs are able to write to a device at the same time, with possibly disastrous results.
I/O Protection
To prevent users from performing illegal I/O, we define all I/O instructions to be privileged instructions. Thus, users cannot issue I/O instructions directly; they must do it through the operating system by means of a system call (Figure 2.8). The operating system, executing in monitor mode, checks to make sure that the request is valid and (if it is valid) performs the I/O requested. The operating system then returns to the user.
Consider a computer executing in user mode. It will switch to monitor mode whenever an interrupt or trap occurs, jumping to the address determined from the interrupt vector. If a user program, as part of its execution, stores a new address in the interrupt vector, this new address could overwrite the previous address with an address in the user program. Then, when a corresponding trap or interrupt occurred, the hardware would switch to monitor mode and would transfer control through the (modified) interrupt vector to the user program!
Memory Protection
We see, then, that we must provide memory protection at least for the interrupt vector and the interrupt-service routines of the operating system. In general, we want to protect the operating system from access by user programs and, in addition, to protect user programs from one another.
To separate each program's memory space from the others', we need the ability to determine the range of legal addresses that the program may access and to protect the memory outside that space. We can provide this protection by using two registers, usually a base and a limit, as illustrated in Figure 2.9. The base register holds the smallest legal physical memory address; the limit register contains the size of the range.
Any attempt by a program executing in user mode to access monitor memory or other users' memory results in a trap to the monitor, which treats the attempt as a fatal error (Figure 2.10).
The base and limit registers can be loaded only by the operating system, which uses a special privileged instruction. Since privileged instructions can be executed only in monitor mode, and since only the operating system executes in monitor mode, only the operating system can load the base and limit registers.
CPU Protection
We must prevent a user program from, for example,getting stuck in an infinite loop and never returning control to the operating system. To accomplish this goal, we can use a timer. A timer can be set to interrupt the computer after a specified period. The period may be fixed (for example, 1/60 second) or variable (for example, from 1 millisecond to 1 second). A variable timer is generally implemented by a fixed-rate clock and a counter. The operating system sets the counter. Every time the clock ticks, the counter is decremented. When the counter reaches 0, an interrupt occurs.
context switch
A more common use of a timer is to implement time sharing. In the most straightforward case, the timer could be set to interrupt every N milliseconds, where N is the time slice that each user is allowed to execute before the next user gets control of the CPU. The operating system is invoked at the end of each time slice to perform various housekeeping tasks, such as adding the value N to the record that specifies (for accounting purposes) the amount of time the user program has executed thus far. The operating system also saves registers, internal variables, and buffers and changes several other parameters to prepare for the next program to run. This procedure is known as a context switch
Another use of the timer is to compute the current time. A timer interrupt signals the passage of some period, allowing the operating system to compute the current time in reference to some initial time.
(Figure 2.1).
For a computer to start running it needs to have an initial program to run. This initial program,or bootstrap program, tends to be simple.
bootstrap program
- Stored in read-only memory (ROM) such as firmware or EEPROM within the computer hardware.
- It initializes all aspects of the system, from CPU registers to device controllers to memory contents.
- The bootstrap program must know how to load the operating system and how to start executing that system.
- To accomplish this goal, the bootstrap program must locate and load into memory the operating-system kernel.
- The operating system then starts executing the first process, such as "init," and waits for some event to occur.
- Event is usually signalled by an interrupt from either the hardware or the software.
- Hardware may trigger an interrupt at any time by sending a signal to the CPU, usually by way of the system bus.
- Software may trigger an interrupt by executing a special operation called a system call (also called a monitor call).
interrupt
For each type of interrupt, separate segments of code in the operating system determine what action should be taken, and an interrupt service routine is provided to deal with the interrupt.
- When the CPU is interrupted, it stops what it is doing and immediately transfers execution to a fixed location.
- The fixed location usually contains the starting address where the service routine for the interrupt is located.
- The interrupt service routine executes; on completion, the CPU resumes the interrupted computation.
(Figure 2.2.)
The straightforward method for handling this transfer would be to invoke a generic routine to examine the interrupt information and then call the interrupt-specific handler.
However, because only a predefined number of interrupts is possible, a table of pointers to interrupt routines can be used instead.
A system call is invoked in a variety of ways, depending on the functionalityprovided by the underlying processor. In all forms, it is the method used by a process to request action by the operating system. A system call usually takes the form of a trap to a specific location in the interrupt vector.
I/O Structure
General-purpose computer system consists of a CPU and multiple device controllers that are connected through a common bus.
Depending on the controller, there may be more than one attached device. For instance, seven or more devices can be attached to the small computer-systems interface (SCSI) controller.
A device controller maintains some local buffer storage and a set of special-purpose registers.
The device controller is responsible for moving the data between the peripheral devices that it controls and its local buffer storage.
The size of the local buffer within a device controller varies from one controller to another, depending on the particular device being controlled. For example, the size of the buffer of a disk controller is the same as or a multiple of the size of the smallest addressable portion of a disk, called a sector, which is usually 512 bytes. Currently, 2MB to 8MB disk controller buffers are common.
I/O Interrupts
- To start an I/O operation, the CPU loads the appropriate registers within the device controller.
- The device controller, in turn, examines the contents of these registers to determine what action to take.
- For example, if it finds a read request, the controller will start the transfer of data from the device to its local buffer.
- Once the transfer of data is complete,the device controller informs the CPU that it has finished its operation. It accomplishes this communication by triggering an interrupt.
synchronous I/O
I/O is started; then, at I/O completion, control is returned to the user process.
asynchronous I/O
Returns control to the user program without waiting for the I/O to complete. The I/O then can continue while other system operations are occurring.
Two I/O methods: (a) synchronous, and (b) asynchronous.
( Figure 2.3 )
Whichever approach is used, waiting for I/O completion is accomplished in one of two ways. Some computers have a special wait instruction that idles the CPU until the next interrupt. Machines that do not have such an instruction may have a wait loop:
Loop: jmp Loop
This tight loop simply continues until an interrupt occurs, transferring control to another part of the operating system. Such a loop might also need to poll any I/O devices that do not support the interrupt structure but that instead simply set a flag in one of their registers and expect the operating system to notice that flag.
If the CPU always waits for I/O completion, as it does when the synchronous approach is used, only one I/O request can be outstanding at a time.
A better alternative is to start the I/O and then continue processing other operating- system or user program code—the asynchronous approach.
A system call is then needed to allow the user program to wait for I/O completion, if desired. If no user programs are ready to run, and the operating system has no other work to do, we still require the instruction or waitidle loop, as before.
We also need to be able to keep track of many I/O requests at the same time. For this purpose, the operating system uses a table containing an entry for each I/O device: the device-status table.
(Figure 2.4).
Each table entry indicates the device's type, address, and state (not functioning, idle, or busy).
If the device is busy with a request, the type of request and other parameters will be stored in the table entry for that device.
Since it is possible for other processes to issue requests to the same device, the operating system will also maintain a wait queue—a list of waiting requests—for each I/O device.
An I/O device interrupts when it needs service.(completion of an I/O request) When an interrupt occurs, the operating system first determines which I/O device caused the interrupt. It then indexes into the I/O device table to determine the status of that device and modifies the table entry to reflect the occurrence of the interrupt.
If there are additional requests waiting in the queue for this device, the operating system starts processing the next request.
Example - keyboard input
- In a simple terminal-input driver, when a line is to be read from the terminal the first character typed is sent to the computer.
- When that character is received, the asynchronous-communication (or serial-port) device to which the terminal line is connected interrupts the CPU.
- When the interrupt request from the terminal arrives, the CPU is about to execute some instruction. The address of this interrupted instruction is saved, and control is transferred to the interrupt service routine for the appropriate device.
- The interrupt service routine saves the contents of any CPU registers that it will need to use.
- It checks for any error conditions that might have resulted from the most recent input operation.
- It then takes the character from the device and stores that character in a buffer.
- The interrupt routine must also adjust pointer and counter variables, to be sure that the next input character will be stored at the next location in the buffer.
- The interrupt routine next sets a flag in memory indicating to the other parts of the operating system that new input has been received.
- The other parts are responsible for processing the data in the buffer and for transferring the characters to the program that is requesting input.
- Then, the interrupt service routine restores the contents of any saved registers and transfers control back to the in interrupted instruction.
It should be clear that the main advantage of asynchronous I/O is increased system efficiency. While I/O is taking place, the system CPU can be used for processing or starting I/Os to other devices. Because I/O can be slow compared to processor speed, the system makes efficient use of its facilities.
Direct memory access (DMA)
Direct memory access (DMA) is used for high-speed I/O devices. After setting up buffers, pointers, and counters for the I/O device, the device controller transfers an entire block of data directly to or from its own buffer storage to memory, with no intervention by the CPU. Only one interrupt is generated per block, rather than the one interrupt per byte generated for low-speed devices.
Main Memory
Main memory and the registers built into the processor itself are the only storage that the CPU can access directly.There are machine instructions that take memory addresses as arguments, but none that take disk addresses. Therefore, any instructions in execution, and any data being used by the instructions, must be in one of these direct-access storage devices. If the data are not in memory, they must be moved there before the CPU can operate on them.
Memory-mapped I/O.
Ranges of memory addresses are set aside and mapped to the device registers. Reads and writes to these memory addresses cause the data to be transferred to and from the device registers. This method is appropriate for devices that have fast response times, such as video controllers. In the IBM PC, each location on the screen is mapped to a memory location. Displaying text on the screen is almost as easy as writing the text into the appropriate memory-mapped locations.
I/O ports
Memory-mapped I/O is also convenient for other devices.The CPU transfers data through these kinds of devices by reading and writing a few device registers, called I/O ports.
rogrammed I/O (PIO)
To send out a long string of bytes through a memory-mapped serial port, the CPU writes one data byte to the data register, then sets a bit in the control register to signal that the byte is available. The device takes the data byte and then clears the bit in the control register to signal that it is ready for the next byte. Then the CPU can transfer the next byte. The CPU may use polling to watch the control bit, constantly looping to see whether the device is ready; this method of operation is called programmed I/O (PIO).
Interrupt driven
If the CPU does not poll the control bit, but instead receives an interrupt when the device is ready for the next byte, the data transfer is
interrupt driven.
Cache
Registers that are built into the CPU are generally accessible within one cycle of the CPU clock. Most CPUs can decode instructions and perform simple operations on register contents at the rate of one or more operations per clock tick. The same cannot be said of main memory, which is accessed via a transaction on the memory bus. Accessing memory may take many cycles of the CPU clock, in which case the processor normally needs to stall, since it does not have the data required to complete the instruction that it is executing. Because memory is accessed so frequently, this situation is intolerable. The remedy is to add fast memory between the CPU and main memory. A memory buffer used to accommodate a speed differential, called a cache.
cache coherency
In a hierarchical storage structure, the same data may appear in different levels. For example, suppose that integer A is located in file B, which resides on magnetic disk. Integer A is to be incremented by 1. The increment operation proceeds by first issuing an I/O operation to copy the disk block on which A resides to main memory. Next, A is copied to the cache and to an internal register. Thus, the copy of A appears in several places: on the magnetic disk, in main memory, in the cache, and in an internal register (see Figure 2.7). Once the increment takes place in the internal register, the values of A in the various storage systems differ. The values become the same only after the new value of A is written from the internal register back to the magnetic disk.
In such an environment, a copy of A may exist simultaneously in several caches.We must make sure that an update to the value of A in one cache is immediately reflected in all other caches where A resides. This situation is called cache coherency, and it is usually a hardware problem (handled below the operating-system level).
Dual-Mode Operation
At system boot time, the hardware starts in monitor mode. The operating system is then loaded and starts user processes in user mode. Whenever a trap or interrupt occurs, the hardware switches from user mode to monitor mode (that is, changes the state of the mode bit to 0). Thus, whenever the operating system gains control of the computer, it is in monitor mode. The system always switches to user mode (by setting the mode bit to 1) before passing control to a user program.
The dual mode of operation provides us with the means for protecting the operating system from errant users—and errant users from one another. We accomplish this protection by designating some of the machine instructions that may cause harm as privileged instructions. The hardware allows privileged instructions to be executed.only in monitor mode. If an attempt is made to execute a privileged instruction in user mode, the hardware does not execute the instruction but rather treats it as illegal and traps it to the operating system.
system call
The concept of privileged instructions also provides the means for a user program to ask the operating system to perform tasks that are reserved to the operating system on the user program's behalf. Each such request is invoked by the user executing a privileged instruction. Such a request is known as a system call (also called a monitor call or an operating-system function call)
When a system call is executed, it is treated by the hardware as a software interrupt. Control passes through the interrupt vector to a service routine in the operating system, and the mode bit is set to monitor mode. The system-call service routine is a part of the operating system. The monitor examines the interrupting instruction to determine what system call has occurred; a parameter indicates what type of service the user program is requesting. Additional information needed for the request may be passed in registers, on the stack, or in memory (with pointers to the memory locations passed in registers). The monitor verifies that the parameters are correct and legal, executes the request, and returns control to the instruction following the system call.
The lack of a hardware-supported dual mode can cause serious shortcomings in an operating system. For instance, MS-DOS was written for the Intel 8088 architecture, which has no mode bit and, therefore, no dual mode. A user program running awry can wipe out the operating system by writing over it with data; and multiple programs are able to write to a device at the same time, with possibly disastrous results.
I/O Protection
To prevent users from performing illegal I/O, we define all I/O instructions to be privileged instructions. Thus, users cannot issue I/O instructions directly; they must do it through the operating system by means of a system call (Figure 2.8). The operating system, executing in monitor mode, checks to make sure that the request is valid and (if it is valid) performs the I/O requested. The operating system then returns to the user.
Consider a computer executing in user mode. It will switch to monitor mode whenever an interrupt or trap occurs, jumping to the address determined from the interrupt vector. If a user program, as part of its execution, stores a new address in the interrupt vector, this new address could overwrite the previous address with an address in the user program. Then, when a corresponding trap or interrupt occurred, the hardware would switch to monitor mode and would transfer control through the (modified) interrupt vector to the user program!
Memory Protection
We see, then, that we must provide memory protection at least for the interrupt vector and the interrupt-service routines of the operating system. In general, we want to protect the operating system from access by user programs and, in addition, to protect user programs from one another.
To separate each program's memory space from the others', we need the ability to determine the range of legal addresses that the program may access and to protect the memory outside that space. We can provide this protection by using two registers, usually a base and a limit, as illustrated in Figure 2.9. The base register holds the smallest legal physical memory address; the limit register contains the size of the range.
Any attempt by a program executing in user mode to access monitor memory or other users' memory results in a trap to the monitor, which treats the attempt as a fatal error (Figure 2.10).
The base and limit registers can be loaded only by the operating system, which uses a special privileged instruction. Since privileged instructions can be executed only in monitor mode, and since only the operating system executes in monitor mode, only the operating system can load the base and limit registers.
CPU Protection
We must prevent a user program from, for example,getting stuck in an infinite loop and never returning control to the operating system. To accomplish this goal, we can use a timer. A timer can be set to interrupt the computer after a specified period. The period may be fixed (for example, 1/60 second) or variable (for example, from 1 millisecond to 1 second). A variable timer is generally implemented by a fixed-rate clock and a counter. The operating system sets the counter. Every time the clock ticks, the counter is decremented. When the counter reaches 0, an interrupt occurs.
context switch
A more common use of a timer is to implement time sharing. In the most straightforward case, the timer could be set to interrupt every N milliseconds, where N is the time slice that each user is allowed to execute before the next user gets control of the CPU. The operating system is invoked at the end of each time slice to perform various housekeeping tasks, such as adding the value N to the record that specifies (for accounting purposes) the amount of time the user program has executed thus far. The operating system also saves registers, internal variables, and buffers and changes several other parameters to prepare for the next program to run. This procedure is known as a context switch
Another use of the timer is to compute the current time. A timer interrupt signals the passage of some period, allowing the operating system to compute the current time in reference to some initial time.
No comments:
Post a Comment