BIOS

From OSDev Wiki
Jump to navigation Jump to search

BIOS (Basic Input/Output System) was created to offer generalized low-level services to early PC system programmers. The basic aims were: to hide (as much as possible) variations in PC models and hardware from the OS and applications, and to make OS and application development easier (because the BIOS services handled most of the hardware level interface).

These BIOS services are still used (especially during bootup), and are often named "BIOS functions". In Real Mode, they can be easily accessed through software interrupts, using assembly language.

BIOS functions

To access a BIOS function, you generally set the AH CPU register (or AX, or EAX for some functions) to a particular value, and then do an INT opcode. The value in AH (or AX, or EAX), combined with the particular interrupt number selected requests a specific BIOS function. (Other CPU registers hold any "arguments" to the function, and often the return values from the function, also.)

It is simplest to create a listing of BIOS functions by specifying the interrupt number, and the value of AH (or AX, or EAX) that selects the function. It is also easiest to refer to particular BIOS functions this way in discussions. For example, INT 0x13, AH=0 is a BIOS function that resets hard disks or floppy disks.

Note: the INT and AH values are always listed in hexadecimal notation. Accidentally using a decimal value in an INT opcode is a very common source of errors when using BIOS functions.

To an extent, the BIOS functions are organized by interrupt number:

  • INT 0x10 = video display functions (including VESA/VBE)
  • INT 0x13 = mass storage (disk, floppy, CDROM) access
  • INT 0x14 = serial port functions
  • INT 0x15 = memory size, miscellaneous system functions
  • INT 0x16 = keyboard functions
  • INT 0x17 = parallel port functions
  • INT 0x1A = RTC, PCI, ...

The exhaustive list of BIOS functions is available from RBIL.

Unfortunately, the PC industry has never been good about maintaining standards. So each PC manufacturer and each BIOS manufacturer randomly made up new BIOS functions. It is also possible to "hook" any of these interrupts, and insert extra functions that mimic BIOS functions. Early PC hardware and software manufacturers did this often. So there ended up being literally thousands of BIOS functions (or mimics). The RBIL list is enormous, and is mostly filled with functions that only work when combined with some completely obsolete computer, BIOS, or piece of hardware or software.

Common functions

Unfortunately, the RBIL does not clearly indicate which BIOS functions are "generic" (in some sense). That is, the ones that are always available, and that everyone uses. Partially this is because the "standard" BIOS functions grew over time, so if you go back far enough in time you can usually find a computer that does not support almost any specific BIOS function. But there is definitely a set that is commonly used in most current OSes.

INT 0x10

Function Description
AH = 0x0 Set video mode
AH = 0x1 Set up the cursor
AH = 0x2 Set cursor position
AH = 0x3 Get cursor position
AH = 0xE Display character
AH = 0xF Get current video page and mode
AH = 0x12 Detect EGA/VGA
AH = 0x13 Display string
AX = 0x1110 Set 8x8 font
AX = 0x1130 Get 8x8 font
AX = 0x1200 Alternate print screen
AX = 0x1201 Turn off cursor emulation
AX = 0x4F00 VESA get video information
AX = 0x4F01 VESA get mode information call
AX = 0x4F02 Select VESA video modes
AX = 0x4F0A VESA 2.0 protected mode interface

INT 0x13

Function Description
AH = 0x0 Reset floppy/hard disk
AH = 0x2 Read floppy/hard disk in CHS mode
AH = 0x3 Write floppy/hard disk in CHS mode
AH = 0x15 Detect second disk
AH = 0x41 Test presence of the BIOS Enhanced Disk Drive Services (EDD)
AH = 0x42 Read to disk in LBA mode
AH = 0x43 Write from disk in LBA mode

(see ATA using BIOS for more detail on these BIOS function calls)

INT 0x14

Function Description
AH = 0x0 Initialize serial port
AH = 0x1 Write byte to serial port
AH = 0x2 Read byte from serial port
AH = 0x3 Get serial port status

INT 0x15

Function Description
AH = 0x86 Delay for a microsecond interval
AH = 0x87 Copy data to extended memory
AH = 0xC0 Detect MCA bus
AX = 0x2400 Disable A20 gate
AX = 0x2401 Enable A20 gate
AX = 0x2402 Get A20 gate status
AX = 0x0530 Detect APM BIOS
AX = 0x5300 APM detect
AX = 0x5303 APM connect using 32 bit
AX = 0x5304 APM disconnect
EAX = 0xE820 Get complete memory map
AX = 0xE801 Get contiguous memory size
AX = 0xE881 Get contiguous memory size
AH = 0x88 Get contiguous memory size
AH = 0x89 Switch to protected mode

(see Detecting Memory (x86) for more detail on the memory size related calls)

INT 0x16

Function Description
AH = 0x0 Read keyboard scancode and character (blocking)
AH = 0x1 Read keyboard scancode and character (non-blocking)
AH = 0x2 Get modifier keys status
AH = 0x3 Set keyboard repeat rate

INT 0x1A

Function Description
AX = 0xB120 Find PCI device
AX = 0xB103 Find PCI class code
AX = 0xB106 PCI bus operations
AX = 0xB108 PCI read configuration byte
AX = 0xB109 PCI read configuration word
AX = 0xB108 PCI read configuration dword

Others

  • INT 0x11 -- Hardware detection
  • INT 0x12 -- Get low memory size
  • INT 0x17 -- Parallel port ("printer") related functions
  • INT 0x18 -- Return to BIOS (this usually makes the BIOS attempt to boot from the next device)

Assembly notes

Each BIOS function (as described in RBIL) has a specific set of "result" registers. Beyond those listed registers, the BIOS functions are supposed to perfectly preserve all the other register values. Early versions of Bochs (below 2.3) had a small problem with this. The lower halves of all the 32bit extended registers (ie. EBX, ECX) were preserved properly, but the upper words of some of the registers got trashed.

The BIOS functions themselves should never crash. On any error they will:

  • almost always set the carry flag (test with JC),
  • sometimes return "AH = 0x86 (unsupported function)",
  • sometimes return "AH = 0x80 (invalid command)"
  • or (for seriously buggy BIOSes) return with nothing changed.

Try to always test these error returns, because in many circumstances the BIOS functions might appear to be returning valid (but very wrong) data -- rather than an error code.

BIOS in Protected Mode

Unfortunately, in Protected mode, almost all BIOS functions become unavailable, and trying to call them nonetheless will result in exceptions or unreliable responses (because of the different way segment values are handled). Some newer services however (such as SMBios, PCI, PnP, or VBE) offer an interface that is compatible with 32bit Protected Mode.

If you must use Real Mode BIOS functions after the CPU has been switched into Protected Mode, then see Virtual 8086 Mode, or perhaps exit Protected Mode, and momentarily return to Real Mode. Both methods have serious problems, and therefore any calls to the BIOS should be done before any physical device is programmed by your code:

  • BIOS calls may use interrupts, which means that you need to forward IRQs or map the PIC back to its original configuration.
  • BIOS calls may access devices that you have already configured - notably the PIT and PIC
  • BIOS calls can enter protected mode on their own to access MMIO registers, which is beyond the limits of virtual 8086 mode.
  • In real mode, you have no way of managing interrupts and your drivers may get stuck for interrupts being lost.
  • In real mode, you have no control over time, performance and security guarantees.

The only device that's mostly exempt from these problems is the Video BIOS, which is not generally bundled with your motherboard and therefore can't rely on BIOS services either. Most current OSes - commercial and hobbyist alike - use a v8086 monitor or emulator to support graphics devices without a native driver so many BIOSes have been tested against such a set-up.

BIOS in Long Mode

Just like in Protected Mode, BIOS functions are unavailable in Long Mode too. Unfortunately there's no Virtual 8086 Mode to come to the rescue. It is necessary to momentarily switch to Real Mode, or to emulate a CPU and interpret opcodes by software. All necessary information for the latter approach can be found in Intel and AMD documentation.

Additional Information from the BIOS

Most of the useful information you get from the BIOS will come from calling BIOS functions. However, there is a small amount of additional information that can be acquired.

Some of the BIOS detection/state result is stored in the BIOS Data Area.

Additional information is kept in the CMOS chip.

Compatibility on Modern Machines

BIOS has been replaced by UEFI on modern x86 machines starting from the 2010s, whose UEFI firmwares keep supporting the "legacy" BIOS functions through an emulation layer, the Compatibility Support Module (CSM).

See Also

Articles

Threads

External Links

Retrieved from "https://wiki.osdev.org/index.php?title=BIOS&oldid=29694"