Real Mode OS Warning
Using BIOS functions (and "avoiding" the need to write drivers) can seem easier for beginners that don't know any better, however it makes everything much much harder in the long run. This makes it an alluring trap for the unwary.
The purpose of this page is to forewarn beginners so that they don't become unsuspecting victims of the trap. This page is not intended to prevent people who are familiar with all the pitfalls from intentionally deciding to walk into the trap.
BIOS Is Deprecated
Currently the entire industry (all "80x86 PC" manufacturers all OSs for "80x86 PC") are shifting to UEFI. At the end of this transition (at some point in the future) BIOS will cease to exist. Relying on the existence of BIOS functions is not a long term option. Temporarily relying on the existence of BIOS functions (for the short term) makes it much much harder to port the OS to UEFI later, and also makes it much much harder to port the OS to other platforms (ARM, SPARC, etc) because everything that the BIOS was used for has to be replaced.
BIOS Does Not Support All Devices
BIOS doesn't provide support for sound, network cards (with the exception of one network card if and only if you booted with PXE), modern printers, scanners, (voice, data or fax) modems, GPUs (for hardware accelerated graphics and/or GPGPU), multiple monitors (one monitor only), various sensors (movement, light, location/GPS, etc) or some user input devices (mouse, joystick, steering wheel, head tracking in 3D helmets, motion sensing/Kinect, touch screens, tablets used with stylus, microphones, bar-code scanners, etc).
For any/all of these things, you will need to write your own drivers.
BIOS Does Not Support Any Device Well
Firmware (including BIOS and UEFI) are mostly only intended to provide minimal functionality needed to get an OS started; and for this reason (for devices that they do support) they don't support the devices well. Note that most of the problems apply to both BIOS and UEFI, and most of the problems apply even if you're writing a "single tasking real mode" OS.
Time And Timers
The "time of day" support only has 1 second precision (and not sub-second precision); and the alarm function is limited to the next 24 hours and also only has 1 second precision. The "elapsed time" support is based on the worst/slowest configuration of the PIT, giving it poor (~55 ms) precision without any support for "call my callback after duration". The BIOS function to obtain elapsed time is based on "ticks since midnight" and has various issues involving roll-over (e.g. trying to determine the amount of time between "just before midnight" and "just after midnight" is a little messy and will bite you if you don't take it into account; and you can't measure anything longer than 1 day without intermittent polling because you don't know how many midnights have passed between "start time" and "end time").
The BIOS serial port code uses polling to send and receive bytes (and there is no "FIFO buffers"). This means that it's almost impossible to use the BIOS functions for serial ports to receive data without losing data, and almost impossible to use the BIOS functions for serial ports to send data without huge performance problems.
The BIOS functions for video (including VBE/VESA BIOS Extensions) don't allow anything other than switching video modes and writing to display memory (no fast bit-blits, no hardware mouse pointer, no vertical sync, etc). For video mode switching the number of modes is typically very limited, and often you can't even set the monitor's preferred/native resolution (leading to a blurry/bad image due to scaling done by the monitor). For writing to display memory the performance is intolerable (hundreds of cycles of extra bloat for every single pixel written).
The BIOS keyboard support has a tiny buffer and uses polling, so if you don't poll often enough (and the user types fast enough) you lose key-presses. There is also no support for asking if a specific key is currently being held down or not, no support for the keyboard's LEDs, no support for different keyboard layouts, no way to do a reverse lookup (determine the name of the key from the scan code), no support for "non-ASCII" (needed for internationalisation), and no support for "hot-plug" (device removal/insertion, and old KVMs that use a mechanical switch).
BIOS support for these devices is synchronous; which causes severe performance problems. For example, if you want to decompress a file from one device and write the data to another device, you can't have a pipeline of buffers and read from one device while the CPU decompresses while writing decompressed data to the other device - you have to read from the first device (while the second device and CPU do nothing) then decompress (while both devices do nothing) then write to the other device (while the first device and CPU do nothing). You also can't pre-fetch data in the background or implement an effective "write-back" disk cache (where writes are done the background).
For removable media (floppy, CD, tape) there is no notification when media is inserted or removed. This can lead to data corruption - e.g. user removes one floppy disk and inserts another; but OS still thinks the first floppy disk is present and writes to it, accidentally corrupting the second floppy disk. While it is possible to try to avoid this (e.g. always check if first sector is different before doing any read or write) it causes more performance problems.
For hot-plug devices (all SATA disks, all USB devices, etc) there is no support for hot-plug. E.g. if the user unplugs a USB flash device (or SATA hard drive or...) there's no notification (read/writes to the device simply cause an error) and if the user plugs in a USB flash device (or SATA hard drive or...) there's no way for the OS to use it (the BIOS continues to pretend the device doesn't exist).
There is no concept of IO priorities and no way to cancel an "in progress" transfer. This means that if you need to tansfer data as soon as possible then that transfer has to wait until any less important "in progress" transfer completes.
There is no support for "trim" (for SSD and USB flash), no support for "secure erase", no support for "eject" (for CD drives), no support for monitoring the health of the device ("Self-Monitoring, Analysis and Reporting Technology"), no support for hard drives with 4 KiB sectors (determining if the drive has 4 KiB sectors or not), and no support for "write barriers" or determining if the data has actually been written to the media and not just buffered by the drive (needed to ensure power failures can't cause file system corruption).
BIOS is only designed to handle single-CPU. You can use multiple CPUs, but you can't safely allow 2 or more CPUs to call BIOS functions at the same time and need a "BIOS lock" to ensure that doesn't happen. There's also a risk that calling BIOS from any CPU other than the BSP ("boot CPU") may cause problems (either due to BIOS bugs or for other reasons).
BIOS Prevents You From Doing Anything Right
The BIOS expects a variety of hardware devices (PIC, PIT, RTC, PS/2 controller, disk controllers, etc) to be in a certain default state. Some of this hardware is deprecated and replaced (and emulated) by more modern devices (PIC replaced with IO APIC, PIT replaced with HPET, etc). An OS can't use modern hardware without tampering with the default state of devices that the BIOS expects, and therefore can't use modern hardware without breaking BIOS.
This makes it extremely difficult for an OS to do anything right (including drivers for devices that the BIOS doesn't support) while still using the BIOS.
BIOS Prevents You From Learning Anything Useful
Eventually (to write an OS that's actually useful, or to learn how to write an OS that's actually useful) an OS developer needs to learn various things; like how devices work, how interrupt controllers can be used, how IO can be done asynchronously, etc. Knowing about these things (even if your OS doesn't do them) is what makes you a good/better OS developer. You learn none of these things by relying on the BIOS.
BIOS Leads You To Extremely Poor Design
For beginners that use BIOS, it's natural (due to lack of experience/knowledge) for them to design their operating system's device driver interfaces to be similar to the interfaces provided by the BIOS, and then it's natural to design the interfaces/APIs for upper layers (e.g. file systems, etc) to suit the driver interfaces, and then it's natural to design the user-space interfaces/APIs to suit both the driver interfaces and the upper layers.
This means that there's an extreme risk of the (very bad and broken) design of the BIOS to permeate the entire OS; such that even if the OS developer manages to overcome all of the other problems caused by using BIOS (e.g. and replace all use of BIOS with their own native drivers, etc) they are still left with a crippled OS that is permanently scarred.