The BIOSDisk disk driver
Last update: 2003-01-11
Copyright © 2003 Salvatore Isaja
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included by reference.
BIOSDisk is a simple but effective FreeDOS-32 driver for disk devices. As its name suggests, it uses the ROM BIOS to access disk devices. This could sound strange for a 32-bit protected mode operating system: BIOSDisk has been developed to have disk support while waiting for 32-bit disk drivers. If supported by the ROM BIOS (most BIOSes do), BIOSDisk can use the IBM/MS Extension to access media greater than 8.4 GB, with Large Block Addressing (LBA).
This document is intended for those people who want to use its features and/or study the source code, in the hope it will be useful.
Contents
- What's new What's new in this version of the driver source and documentation
- About the driver General informations on the FD32 BIOSDisk driver
- BIOSDisk issues An overview of the issues behind the BIOSDisk driver functionality
- Customizing the driver Changing the driver at compile time using predefined conditional defines
- List of source files The list of source files of the driver with a brief description of them
What's new
The driver code has been changed in order to use the last proposed driver interface, based on a request function. Source files have been rearranged in order to minimize cross-references between different files. The once called Partition Manager is now part of BIOSDisk and it's no longer a stand-alone FreeDOS-32 component.
About the driver
The FreeDOS-32 BIOSDisk driver, as well as the rest of the FreeDOS-32 code, is released under the terms of the GNU General Public License.
Current features
- LBA access for media greater than 8.4 GB
- Support for removable media
Planned features
- Floppy speed-up reading/writing a whole track per revolution
- Multi-block disk cache for hard disks
- Move to a real 32-bit ATA/ATAPI driver! :-)
Download
You can get the latest development source code for BIOSDisk by checking
out the drivers module from our CVS repository. See the Downloads page for details
about this procedure. Please note that BIOSDisk depends on files located in the
fd32 CVS module too.
BIOSDisk's files are located in the biosdisk directory. Please
read the README.txt file before using the code. It contains release
notes and instructions on how to build the driver. The COPYING text
file contains the GNU General Public License: be sure you respect its terms if
you intend to use the code.
Disclaimer
BIOSDisk and the other support code is still under development and test, so it is not guaranted to be bug free by this time. Please consider that the code might have bugs that could corrupt your data seriously. Testing on a floppy or an unused hard disk is strongly recommended. You may also choice to build a read-only version of the driver.
Just to be more formal: as stated in the GNU General Public License, the program is provided "AS IS" WITHOUT ANY WARRANTY. Test it AT YOUR OWN RISK. I'M NOT RESPONSIBLE FOR ANY DAMAGE.
BIOSDisk issues
Some notes on BIOS disk services, CHS and LBA coordinates and partition tables follow. These are intended to show what implementation issues are behind the BIOSDisk disk driver. This discussion has been kept simple, without explaining all details. If you need more informations, you may want to check the Operating System Resource Center, where you can find a lot of interesting documents about these topics.
Why the ROM BIOS?
Because it offers all ready-to-use disk services we need. This is the fastest way to provide disk access to the FD32 kernel, although it is intended only as a temporary solution: for "real things", 32-bit ATA/ATAPI drivers will be developed, but, since we already have disk access for testing and developing, this is not priority.
The price to pay is that, being FreeDOS-32 a 32-bit protected mode kernel, mode switches are required each time a BIOS service is required, because BIOS code is real mode. Again, this is good for testing and developing, but against the goals of this project. Luca has developed code for mode switch in OSLib, so we have a functional BIOSDisk.
Basically, we need services to read and write sectors, and to detect disk units. The ROM BIOS provides them. Moreover, many BIOSes provide two different kinds of services: standard disk services and IBM/MS extended services. The latter have been introduced to deal with bigger media.
Standard disk services and CHS coordinates
Disk manufacturers used to define a "disk geometry" for accessing the disk. It was specified by three numbers: the cylinder number, the head number and the sector number in the disk track, often abbreviated as CHS triplet. Historically, old disks really had such a geometry, whereas in new disks this geometry is purely conventional (for example, there isn't a fixed number of sectors per cylinder, and there are not hundredths of disks per device...).
Standard BIOS disk services (INT 13h services 0?h) still use CHS coordinates to address a sector on a disk, storing a CHS triplet in a 24 bit number. This is subdivided in a 10-bit cylinder, 8-bit head and 6-bit sector. This limits the number of cylinders to 1024 (0 to 1023), the number of heads to 256 (0 to 255) and the number of sectors to 64 (0 to 63). Actually they are even less: for a DOS storic bug the number of heads is limited to 255 (0 to 254), while the number of sector is one-based, so there are max 63 sectors (1 to 63). Thus, CHS coordinates can address up to 1024*255*63 = 16,450,560 sectors, i.e. 8.4 GB (decimal gigabytes!) if usual 512 bytes sectors are used.
Extended disk services and LBA coordinates
To solve the limits of CHS, a new addressing scheme has been introduced: the Large Block Addressing (LBA). In LBA a disk is seen as a big mono-dimensional array of sectors, numbered starting from zero. The absolute sector number is the LBA address.
IBM/MS extended BIOS disk services (INT 13h services 4?h) use 64-bit numbers to store the LBA addresses, giving control over 1019 sectors (note that this is only true at API level, for real devices the limit is much smaller). BIOS disk extensions are only meaningful for hard disk devices, while floppy disk devices continue to use CHS addressing. If the CHS range allows it, it's possible to translate LBA coordinates in CHS coordinates and viceversa, if the (conventional) geometry of the disk is known, i.e. the max number of cylinders, heads and sectors per track.
IBM/MS disk extensions are implemented in recent BIOSes. Thus, the BIOSDisk disk detection code has to check if extensions are available before using them. If they are, hard disk devices are accessed through LBA services, otherwise old CHS services are used.
Partition tables
Hard disk devices are usually partitioned to host different file systems. Each partition is seen by the system as if it were a drive, thus a device has to be registered to the FreeDOS-32 kernel for each disk partition.
Hard disk partitions are described in a partition table stored in the first sector of the disk, which is called the Master Boot Record (MBR). There are no official standards about partition tables usage, but there are some rules followed by many FDISK programs. The partition table contains four entries, so up to four "primary" partitions can be created. When this limit became too strict, extended partitions have been introduced: up to one of these primary partitions can be defined as "extended", i.e. a partition containing in its first sector another partition table. This partition table can contain up to one data partition and up to one extended partition, to form a linked list of partition tables. It is very common, but not required, to have only one primary partition.
Each entry of the partition table stores:
- the starting and ending sectors of the partition as 24-bit CHS triplet
- the starting sector of the partition as 32-bit LBA number and the LBA partition size in sectors
- the "active" flag, which tells what partition to use to boot up the system
- a partition type code, which tells what file system is hosted in the partition
CHS and LBA limits are clearly redundant, and can be used to check the partition entry validity. For larger sector numbers, when CHS goes over-range, CHS limits are usually set to FFFFFFh and only LBA limits are used. FreeDOS-32 will always work with LBA informations (the same as Linux does, on the contrary of Windows that uses both, and DOS that uses CHS only).
Unfortunately, older versions of FDISK are reported to compute incorrect LBA start or size values. For this reason, LBA values are computed from their CHS counterpart when possible, i.e. when LBA values are within the range of the CHS system. Other LBA values have to be trusted, but in this case they have probably been computed by a new FDISK.
Last but not least, the starting point of partitions nested in an extended partition are relative to the starting point of the parent extended partition. This helps to make the code more dirty, but after all this is usual when old technologies are patched keeping backward compatibility.
Naming conventions
BIOSDisk uses the Linux naming convention for disk devices
and disk partitions devices. Floppy device names start with "fd",
followed by a zero-based number, so the first floppy device is "fd0",
the second "fd1" and
so on. Hard disk device names start with "hd", followed
by a letter, so the first hard disk is "hda", the second "hdb" and
so on. Actually, the 'a' and 'b' letters identify the
master and slave units attached to the primary IDE controller, while the 'c'
and 'd' letters identify the master and slave units attached
to the secondary IDE controller. BIOSDisk can use this convention only if IBM/MS
BIOS extensions are available, since they allow to detect the IDE channel and
the master/slave role, otherwise letters are incremented as the disks are enumerated.
Partition device names start
with the hard disk device name, followed by a number. Partitions 1 to 4 are primary
partitions (data partitions in the primary partition table) and partitions greater
than 4 are secondary partitions belonging to an extended partitions chain. So,
for example, for the disk device "hda",
BIOSDisk creates devices like "hda1", "hda5", "hda6" and "hda7".
Outside BIOSDisk they are seen as stand-alone disk devices, while BIOSDisk transparently
adds a constant offset to sector numbers when accessing them.
Customizing the driver
You can customize BIOSDisk at compile time
using a set of conditional preprocessor constants defined in the biosdisk.h private
header file.
Write support - BIOSDISK_WRITE
You can decide if you want to build a read
only disk driver or a disk driver with write support. This may be useful for
safely testing the driver. Define the BIOSDISK_WRITE constant to include disk
write functions in the compilation.
FD32 devices registration - BIOSDISK_FD32DEV
If you don't need to register
devices to the FreeDOS-32 Device Manager (for example,
you want to use BIOSDisk code only for displaying disk units), do not define
the BIOSDISK_FD32DEV constant.
Verbose detection - BIOSDISK_SHOWMSG
Define the BIOSDISK_SHOWMSG constant to display messages
during the disk detection process.
List of source files
Follows the list of the files of the BIOSDisk source code, with a short description for each function. For more informations look at the source files: a more detailed description precedes each function, including parameters and return value.
biosdisk.h - driver's constants, structures and prototypes
This header file is included by all other files. It includes the needed FreeDOS-32
header files, defines customization constants, flag mnemonics, the tDisk status
structure for a disk device and function prototypes.
common.c - operations common to standard and extended BIOS
Implements the wrappers
biosdisk_read and biosdisk_write, which call the read
and write functions of the extended BIOS, if available, or the standard BIOS
ones otherwise. This file also includes the functions biosdisk_devopen and biosdisk_devclose to manage the usage counter (important for caching, although not yet implemented),
and the biosdisk_mediachange function to check the disk's change-line status.
detect.c - Detection and initialization of disk devices
This is the most complex
file of BIOSDisk. The public function biosdisk_detect calls the detect_floppies and detect_harddisks, which query the BIOS for disk devices, detect their capabilities
(such as size, geometry and availability of LBA extensions), also using some
internal support function, and to register devices to the FreeDOS-32 kernel (see
the Device Manager documentation). The hard disk detection function also calls
the biosdisk_scanpart function (file partscan.c) to detect disk partitions. Structures
defined in this file reflect the format of data structures expected by the BIOS
disk detection services.
extdisk.c - IBM/MS extended BIOS disk function
The biosdisk_extread and biosdisk_extwrite functions are wrappers for the internal function ext_disk_op, which transfers
sectors between the disk device and a low memory buffer. The two wrappers also
take care of allocating the low memory buffer and of copying data from/to it
to/from a user buffer. The tAddressPacket internal structure is typical of
extended BIOS disk services requests.
hand.s - FD32 Interrupt Handlers & similar stuff
This assembly file is included in the BIOSDisk compilation only for the FreeDOS-32 target. It implements interrupt handlers to be installed in protected mode for reflecting those interrupts to the virtual-8086 mode. This file is by Luca Abeni.
init.c - initialization code for the FreeDOS-32 kernel
This file is included in the
BIOSDisk compilation only for the FreeDOS-32 target. The driver entry point (see
the Drivers Specification),
biosdisk_init, initializes the virtual-8086 mode
switching required for BIOS calls from protected mode, installs some required
IRQ handlers and calls the biosdisk_detect (file detect.c) function to detect
and register disk devices to the FreeDOS-32 kernel. This file is by Luca Abeni.
partscan.c - hard disk partitions scanner
The biosdisk_scanpart function scans
a hard disk device for primary and extended partitions, registering a device
to the FreeDOS-32 kernel for each of them.
reflect.c - FreeDOS-32 interrupt reflection functionality
This file is included in
the BIOSDisk compilation only for the FreeDOS-32 target. The fd32_int_reflect function reflects all the handled interruputs which occur in protected mode back
to the virtual-8086 mode. This file is by Luca Abeni.
request.c - driver request function for BIOSDisk
Implements the BIOSDisk driver
request function, biosdisk_request, as described in the FreeDOS-32
drivers interface. This function is called by the FreeDOS-32 kernel to ask
the BIOSDisk disk driver to perform its services.
stddisk.c - standard BIOS disk functions
If IBM/MS extensions are not available,
this file provides the biosdisk_stdread and biosdisk_stdwrite wrappers for the
internal std_disk_op function, which transfers sectrors between the disk device
and a low memory buffer. The two wrappers also take care of allocating the low
memory buffer and of copying data from/to it to/from a user buffer. Note that
at BIOS call level disk coordinates are expressed in CHS.