|[ Team LiB ]|
Although the primary role for the BIOS today is to get your computer started, it retains the name it earned from its function as the software-to-hardware interface of your machine. It is a control system that operates at the lowest possible level (the most basic) at which the input and output of your computer are designed to link to programs. In effect, it is like a remote control for a television set. The BIOS allows your software to press buttons at a distance from the hardware, just as you control the channel of your TV from your easy chair—and without prying open the set and ratcheting its tuning circuits. In operation, the BIOS is a universal remote control. It lets you push the same buttons, regardless of the model or brand of television at which you point it.
The original purpose of this one-step-removed BIOS design was to allow computer hardware to be revised and updated without the need to change software correspondingly. It helps guarantee the backward compatibility of computers. The extra BIOS step is needed, because all computers have many hardware elements that are located at specific addresses in memory or within the range of certain input/output ports. Other computer components may have registers of their own, used in their control, that also are addressed at specific locations. Because of the number of separate components inside any computer, the potential number of possible variations in the location of these features is limitless. Software that attempts to control any of this hardware must properly reach out to these registers. As long as all computers are crafted exactly the same, with the same ports used for exactly the same hardware with exactly the same registers, no problems should occur. But if a computer designer wants to change the hardware to a technology that delivers better performance or greater reliability, he may be stymied by the old addresses. Software may expect to reach the old design at one set of ports, whereas the new-and-improved design may be memory-mapped and not use ports at all. In this case, the old software would not know how to reach the new hardware, and the new design simply would not work.
The BIOS gives the software a link. The software reaches into the BIOS for the hardware function it wants. Then the BIOS dips down into the hardware. If the design of a computer system is changed radically, only the BIOS needs to be changed to reflect the new way of getting at the features of the computer. The changed BIOS still works the same way as the software, so all older programs run exactly as they did before the change. In effect, the new system design requires a new route to get to an old destination—a detour. The new BIOS is an updated roadmap that shows only the detour.
Certainly today's driver software easily accomplishes this function of the BIOS. Back in the days when the computer was first created, however, there were no drivers. The original computer BIOS didn't even have provisions for adding extra hardware, and the first operating system had no intrinsic provisions for adding drivers. Not knowing what was to come of the personal computer, IBM put its reliance on BIOS technology in its first computers and reserved the right to alter the hardware at will. The company made no guarantee that any of the ports or registers of the computer would be the same in any later computer.
In effect, IBM created the computer in a well-ordered dream world in which programs would never need to directly address hardware. Instead, each program would call up a software routine in the BIOS, which would have the addressing part of the instruction permanently set in its code. Later computers with different hardware arrangements would use BIOS routines that worked like the old ones and were indistinguishable from the old ones when used by application software. The addresses inside the routines would be changed, however, to match the updated hardware. The same software could work, then, with a wide variety of hardware designs, giving the designer and manufacturer the flexibility to upgrade the entirety of system hardware, if necessary.
In the days when your computer's operating system worked cooperatively with the BIOS instead of co-opting its function, BIOS compatibility was a major issue in buying a new computer. A computer had to have a BIOS functionally equivalent to that of an IBM personal computer to work reliably with the software of the day. Consequently, after the IBM BIOS made its debut, it became the most copied set of software routines in the world. The computer BIOS laid out all the entry points used by subsequent IBM BIOSs and most compatible BIOSs as well. It also defined the functions that could—and must—be expected in any BIOS as well as established the way that the BIOS works. The BIOS that IBM developed for its 1984 Personal Computer AT still defines the minimum level of compatibility for all computers.
Today, computer-makers can buy a compatible BIOS off the shelf from any of several sources. It wasn't always that easy. Achieving off-the-shelf BIOS compatibility was one of the great sagas of computer history.
Because the copyright laws forbade any copying of someone else's work, compatible BIOSs had to be written "clean." That is, the programmers were kept from ever viewing the source code or having any knowledge of the routines it contained. Instead, they worked from a list of instructions and the functions that the BIOS carries out when given each specific instruction. In other words, they looked at the BIOS they wanted to copy as a black box that takes an input and gives an output. The programmers then deduced the instructions for the inside of the box that would give the desired results.
Working in this way was time consuming and expensive. Few computer companies had the resources to do it all themselves. Compaq was the first to successfully tackle the job. The vast majority of compatible computer manufacturers bought the necessary BIOS firmware from specialist firms. The first to offer compatible BIOSs was Phoenix Technologies. Now computer-makers also select BIOS chips from American Megatrends, Inc., Award Software, and Mr. BIOS.
Because each BIOS vendor must develop its own product separately, the exact code used by each BIOS version is different. Functionally, however, they all look the same to your software (including your operating system).
At the other side of the interface—where the BIOS links to your computer's hardware—BIOSs can be quite different. By design, every BIOS is created to match the specific hardware in the computer in which it operates. That is part of its job—uniting different hardware designs so that they work interchangeably with all software. Every BIOS is customized for the computer it controls. Typically, computer motherboard manufacturers modify a generic BIOS from one of the BIOS-makers to suit their own purposes.
Because each BIOS is customized for a particular model of computer, no generic BIOS can hope to work properly in a given computer. BIOSs are not interchangeable. Moreover, should you want to change or upgrade your computer's BIOS for any reason—either through buying new chips or downloading code for Flash memory—you need to get one that matches the exact model of computer you own.
The BIOS design created for the first computers does its linking through a system of software interrupts. To gain access to the underlying hardware, a program sends out an interrupt, which is a special instruction to the microprocessor. The software interrupt causes the microprocessor to stop what it is doing and start a new routine. It does this by suspending the execution of the code on which it is working, saving its place, and then executing the program code of the BIOS routine.
The various functions the BIOS carries out are termed interrupt service routines or interrupt handlers. To call a given interrupt handler, a calling program needs to be able to find the program code that carries out the function. The design of the computer BIOS allows the system to put these interrupt handlers at any convenient address. So that a calling program can find the proper routine, the BIOS reserves part of your computer's memory for a map called a BIOS interrupt vector table. This map consists of a long list of 32-bit addresses, with one address corresponding to each interrupt handler. These addresses point to the first byte of the program code for carrying out the interrupt and are called interrupt vectors. The microprocessor reads the value of the vector and starts executing the code located at the value stored in the vector.
The table of interrupt vectors begins at the very start of the microprocessor's memory, address 00000(hex). Each vector comprises four bytes, and all vectors are stored in increasing order. Table 7.1 summarizes the principal BIOS interrupt vectors and the associated functions.
The interrupt vectors are stored in the RAM of your computer so that the values in the table can be changed. For example, a program or software driver may want to alter or update a BIOS routine to take advantage of a special feature of new hardware you install in your computer. The BIOS code itself loads default values for many of these interrupt vectors into the appropriate RAM locations with the vectors pointing at the routines stored in your computer's ROM.
Sometimes programs add extra routines to a given BIOS function, a process called chaining interrupts. To chain an interrupt, a program looks at the interrupt vector it wants to chain to and remembers its value. It then substitutes the starting location of the program code that it wants to add to the old routine. It then modifies its own code to make the execution of its routines jump to the old interrupt when the processing of the new code finishes. In this way, the new routine added in the interrupt chain executes first and then starts the original interrupt handler.
Because fewer interrupts are available than tasks you might want the BIOS to handle, different functions are available for many of the interrupts. These separate functions are identified through a technique called parameter passing. An interrupt needing service from the BIOS—the calling program—passes a number identifying the command to be carried out to the BIOS as a parameter, a value held in one or more of the registers at the time the software interrupt is issued.
The calling program decides what function it wants the BIOS to carry out, loads the parameter value into the proper register, and issues the interrupt. The BIOS code examines the register to determine what function the programs wants.
This same technique may be used to pass information between the calling program and the BIOS. The data to be passed along is simply loaded into one register and the parameter identifying the command into another. To pass new data back to the calling program, the BIOS loads the data into a register, which the calling program can then read.
Using registers to move data into a BIOS routine has its shortcomings. The functions and parameters are limited to those that are common among computers. There's little room for programs to add their own interrupts. Moreover, the scant number of registers in Intel microprocessors limits the number of parameters that can be passed to and from a function. Most routines use a single byte of data.
To move larger blocks of data, some BIOS routines and most programs use memory. A calling program stores the values it wants to pass to a subroutine in a block of RAM addresses. It then passes to the subroutine the location of the data, and the subroutine digs into the data, changing what it requires, and leaves the block for later access by the program. Although programs and subroutines identify the block of memory by its address, programming languages let you use names for the data. The program chooses the block of addresses to associate with the name and looks to those addresses whenever the programmer uses that name. Similarly, program subroutines may be named, and the program uses the names to find the block of memory holding the microprocessor instructions that comprise the subroutine.
The various code routines in each BIOS start and end at addresses assigned to the BIOS function in the computer memory map. The address at which each routine starts is called that routine's entry point. The entry point of a BIOS function is completely different from the interrupt that calls that function. When the BIOS in your computer sets itself up—either before or during the actual bootup—it loads the addresses of the entry points into a table in memory that becomes the interrupt vectors. In theory, an entry point can be at any location for any BIOS function—it needs only to be loaded into the slot in the BIOS interrupt vector table to be properly recognized. Unfortunately, some program writers decided to call BIOS routines by their entry points instead of using interrupts, because the direct approach is faster. Consequently, a few applications require that some entry points be at specific physical BIOS addresses. If the entry point of a BIOS differs from what the program expects, the result is likely to be a system crash.
IBM has maintained the same entry points with all its BIOSs, and many compatible BIOSs use exactly the same addresses. A few do not, however. In general, the BIOSs with varying entry points have been written as programming modules that can be combined in various ways to suit the needs of a computer designer. What these modular BIOSs add in flexibility, they lose in compatibility.
Unlike programs that write directly to system hardware, however, programs that require specific BIOS entry points are rare. With the popularity of compatible computers and modular BIOSs, they are sure to become more rare. Modern software, nevertheless, is getting away from a dependency on complete compatibility down to the level of specific entry points. In fact, many programs avoid the BIOS entirely.
The chief beneficiaries of the BIOS are individual programmers who need to create code quickly. In many cases, using BIOS routines can simplify the writing of a program. Certain system operations always are available and can be accessed easily through software. They are reasonably well documented and understood, removing many of the programmer's concerns.
Linking to Hardware
Controlling the hardware of your computer requires that your system be able to pass commands and data to that hardware. For example, if you have a modem, you need to send the modem commands to dial numbers and change speeds. Once you're communicating, you have to send bytes, even megabytes, of data to the modem and receive more bytes in return.
The BIOS routines may use memory or I/O ports to pass the commands and data to hardware devices. When a device uses a block of memory to exchange information, it is termed memory mapped. When it uses I/O ports, it is termed I/O mapped.
Memory mapping works exactly as described in the previous section on parameter passing. The BIOS routine and hardware device share a common range of memory addresses they use for passing bytes back and forth. Programs use BIOS routines instead of physical addresses to reach memory-mapped devices, giving the hardware designer the freedom to move the memory window used by a given device. The designer needs only to change the interrupt handler to match the address he chooses.
I/O mapping uses input/output ports to exchange data. An input/output port of a microprocessor is a special range of addresses that is isolated from main memory and has special access instructions.
In the Intel scheme of things, microprocessors have a range of 65,536 input/output ports (compared to over four billion discrete memory addresses). However, due to an aberration in the design of the first expansion boards for computers, only 1024 are commonly assigned to devices that plug into standard computer expansion slots. To cut costs of the first expansion boards, engineers designed boards to decode only 10 of the 16 address lines.
Although newer buses can take advantage of the full range of input/output ports, expansion boards can quickly consume the available ports, or two boards may attempt to use the same port. Such conflicts between boards is the most common reason why expansion boards fail to operate properly. Sometimes installing an expansion board creates a port conflict that prevents the rest of the system from working at all. Table 7.2 lists some of the common conflicts that arise in I/O port assignments.
If you're running Windows on your computer, you can view the actual I/O port assignments used by your computer. To view these assignments, consult the Device Manager by selecting the System icon in Control Panel. Select your computer on the Device menu and click the Properties button. From the View Resources menu that pops on your screen, select the Input/Output (I/O) radio button. You'll see a screen akin Figure 7.1, listing all the input/output ports in use and the hardware using them.
Through Plug-and-Play and the manual options of the Add Hardware process, Windows generally will make the proper assignments of I/O ports. If you want to reserve one or more I/O ports so that devices you install later cannot steal them, click the Reserve Resources tab and enter the ports you want to reserve.
New expansion buses such as PCI provide access to the full range of I/O ports, thus reducing the chance of conflicts. Plug-and-Play expansion boards are supposed to automatically resolve port conflicts entirely. Eventually, worries about I/O conflicts should disappear. For most computers, however, eventually has not yet arrived.
|[ Team LiB ]|