St. Louis Unix Users Group
Linux Sig
Disks - 101
John W. Himpel
November 21, 1996
Controllers
Minor Device # |
Device Name |
Description |
0 |
/dev/fd0 |
Controller 1, drive 1 autodetect |
1 |
/dev/fd1 |
Controller 1, drive 2 autodetect |
2 |
/dev/fd2 |
Controller 1, drive 3 autodetect |
3 |
/dev/fd3 |
Controller 1, drive 4 autodetect |
128 |
/dev/fd4 |
Controller 2, drive 1 autodetect |
129 |
/dev/fd5 |
Controller 2, drive 2 autodetect |
130 |
/dev/fd6 |
Controller 2, drive 3 autodetect |
131 |
/dev/fd7 |
Controller 2, drive 4 autodetect |
5.25" Devices
Minor Device # |
Device Name |
Description |
0 |
/dev/fd? |
autodetect format |
4 |
/dev/fd?d360 |
360K in a 360K drive |
20 |
/dev/fd?h360 |
360K in a 1200K drive |
48 |
/dev/fd?h410 |
410K in a 1200K drive |
64 |
/dev/fd?h420 |
420K in a 1200K drive |
24 |
/dev/fd?h720 |
720K in a 1200K drive |
80 |
/dev/fd?h880 |
880K in a 1200K drive |
8 |
/dev/fd?h1200 |
1200K in a 1200K drive |
40 |
/dev/fd?h1440 |
1440K in a 1200K drive |
56 |
/dev/fd?h1476 |
1476K in a 1200K drive |
72 |
/dev/fd?h1494 |
1494K in a 1200K drive |
92 |
/dev/fd?h1600 |
1600K in a 1200K drive |
3.5" Devices
Minor Device # |
Device Name |
Description |
12 |
/dev/fd?u360 |
360K Double Density |
16 |
/dev/fd?u720 |
720K Double Density |
120 |
/dev/fd?u800 |
800K Double Density |
52 |
/dev/fd?u820 |
820K Double Density |
68 |
/dev/fd?u830 |
830K Double Density |
84 |
/dev/fd?u1040 |
1040K Double Density |
88 |
/dev/fd?u1120 |
1120K Double Density |
28 |
/dev/fd?u1440 |
1440K High Density |
124 |
/dev/fd?u1600 |
1600K High Density |
44 |
/dev/fd?u1680 |
1680K High Density |
60 |
/dev/fd?u1722 |
1722K High Density |
76 |
/dev/fd?u1743 |
1743K High Density |
96 |
/dev/fd?u1760 |
1760K High Density |
116 |
/dev/fd?u1840 |
1840K High Density |
100 |
/dev/fd?u1920 |
1920K High Density |
32 |
/dev/fd?u2880 |
2880K High Density |
104 |
/dev/fd?u3200 |
3200K High Density |
108 |
/dev/fd?u3520 |
3520K High Density |
112 |
/dev/fd?u3840 |
3840K High Density |
36 |
/dev/fd?CompaQ |
Compaq 2880K drive; probably obsolete |
EIDE |
SCSI |
Internal Cabling |
Internal and/or External Cabling |
FIFO I/O queuing |
Tag command queuing & elevator seeking- Reorders I/O to reduce seek time and head movements |
Compatibility between manufactures is spotty |
Compatibility is not an issue |
Cabling requirements are more forgiving |
Cabling requirements are demanding |
Terminator scheme is straight-forward |
Terminator scheme is slightly more complicated |
8.4 GB/drive limit |
8.4 GB/drive limit |
Internal hard drives, CD-ROM drives, tape drives |
Internal and external hard drives, CD-R, CD-ROM, DAT, and tape drives; scanners; other peripherals |
Maximum Connections: Four |
Maximum Connections: 7 |
VL-Bus or PCI |
VL-Bus or PCI |
Generally cheaper |
Generally more expensive |
May require jumper modifications for Primary/Secondary device settings |
May require jumper modifications for SCSI-ID and termination settings |
DVD Format |
Capacity (120-mm disc) |
Capacity (80-mm disc) |
DVD-ROM: one side, one layer |
4.7 GB |
1.4 GB |
DVD-ROM: one side, two layers |
8.5 GB |
2.6 GB |
DVD-ROM: two sides, one layer |
9.4 GB |
2.9 GB |
DVD-ROM: two sides, two layers |
17 GB |
5.3 GB |
DVD-R: one side, one layer |
3.9 GB |
1.2 GB |
DVD-R: two sides, one layer |
7.8 GB |
2.4 GB |
DVD-RAM: one side, one layer |
2.6 GB |
0.7 GB |
DVD-RAM: two sides, one layer |
5.2 GB |
1.5 GB |
DVD-ROM - Similar in concept to CD-ROM.
DVD-R - Similar in concept to WORM.
DVD-RAM - Rewritable phase change.
struct partition {
char active; /* 0x80: bootable, 0: not bootable */
char begin[3]; /* CHS for first sector */
char type;
char end[3]; /* CHS for last sector */
int start; /* 32 bit sector number */
/* (counting from 0) */
int length; /* 32 bit number of sectors */
};
(where CHS stands for Cylinder/Head/Sector). Note the use of 28 bits to store the CHS information used to described the disk geometry. The IDE controller used 28 bits to define the CHS information regarding the disks which it controls. However, each uses a different scheme for subdividing the 28 bits into CHS information.
Parameter |
BIOS Limit |
IDE Controller Limit |
Effective Limit |
Cylinder |
0-1023 |
0-65,535 |
0-1023 |
Head |
0-255 |
0-15 |
0-15 |
Sectors/Track |
1-63 |
1-256 |
1-63 |
Capacity |
7.875 GB |
130.56 GB |
504 MB |
The BIOS, via INT13, uses the least common denominator approach to determine the disk geometry. So what's the problem? For IDE disks <504 MB, there is no problem. But for IDE disks >=504 MB (typically more than 1023 cylinders), and the operating system of choice uses the INT13 BIOS interface, cylinders past 1023 are inaccessible. What operating systems use the BIOS? MS-DOS, Windows 95, Windows NT. Linux does not use the BIOS to access the disk. So therefore, this does not present a problem for Linux.
Well, except for two things:
(1) When you boot you system, Linux isn't running yet and cannot save you from the BIOS limitations. This has some consequences for LILO and similar boot loaders.
(2) It is necessary for all operating systems that use one disk to agree on where the partitions are. In other words, if you use both Linux and say DOS on one disk, then both must interpret the partition table in the same way. This has some consequences for the Linux kernel and for fdisk.
When the system is booted, the BIOS reads sector 0 (known as the MBR- the Master Boot Record) from the first disk (or from floppy), and jumps to the code found there - usually some bootstrap loader. These small bootstrap programs found there typically do not have their own disk drivers and use the BIOS services. This means that a Linux kernel can only be booted when it is entirely located within the first 1024 cylinders of a disk that the BIOS can access - probably this means the first or second disk.
Another point is the boot loader and the BIOS must agree as to the disk geometry. It may help to give LILO the 'linear' option. More details below.
If you have several operating systems on you disks, then each uses one or more disk partitions. A disagreement on where these partitions are may have catastrophic consequences.
The MBR contains a partition table describing where the (primary) partitions are. There are 4 table entries, for 4 primary partitions. The format of the partition table is given above. By inspection, it become obvious that some information is redundant; the location of a partition is given both by the 24-bit begin and end fields, and by the 32-bit start and length fields.
Linux only uses the start and length fields, and can therefore handle partitions of nor more than 2^32 sectors, that is, partitions of at most 2 TB. That is two hundred times larger than the disks available today, so maybe it will be enough for the next ten years or so.
Unfortunately, the BIOS INT13 call used CHS coded in three bytes, with 10 bits for the cylinder number, 8 bits for the head number, and 6 bits for the track sector number. Possible cylinder numbers are 0-1023, possible head numbers are 0-255, and possible track sector numbers are 1-63 (yes, sectors on a track are counted from 1, not 0). With these 24 bits, one can address 845571684 bytes (7.875 GB), two hundred times larger than the disks available in 1983.
Even more unfortunately, the standard IDE interface allows 256 sectors/track, 65536 cylinders and 16 heads. This in itself allows access to 2^37=137438953472 bytes (128 GB), but combined with the BIOS restriction to 63 sectors and 1024 cylinders only 528482394 bytes (504 MB) remain addressable.
This is not enough for present-day disks and people resort to all kinds of trickery, both in hardware and in software.
Nobody is interested in what the 'real' geometry of a disk is. Indeed, the number of sectors per track often is variable - there are more sectors per track close to the outer rim of the disk - so there is no 'real' number of sectors per track. For the user it is best to regard a disk as just a linear array of sectors numbered 0, 1, ...., and leave it to the controller to find out where a given sector lives on the disk.
This linear numbering is known as LBA. The linear address belonging to (c,h,s) for a disk with a geometry (C,H,S) is c*H*S + h*S + (s-1). All SCSI controllers speak LBA, while some IDE controllers do also.
If the BIOS converts the 24-bit (c,h,s) to LBA and feed that to a controller that understands LBA, then again 7.875 GB is addressable. Not enough for all disks, but still an improvement. Note that here CHS, as used by the BIOS, no longer has any relation to 'reality'.
Something similar works when the controller doesn't speak LBA but the BIOS knows about translation. (In the setup this is often indicated as 'Large'. Now the BIOS will present a geometry (C',H',S') to the operating system, and use (C,H,S) while talking to the disk controller. Usually S=S', C'=C/N and H' = H*N, where N is the smallest power of two that will ensure C" <= 1024 (so that least capacity is wasted by the rounding down in C' = C/N). Again, this allows access of up to 7.875 GB.
If a BIOS does now know about 'Large' or 'LBA', then there are software solutions around. Disk Manager like OnTrack or EZ-Drive replace the BIOS disk handling routines by their own. Often this is accomplished by having the disk manager code live in the MBR and subsequent sectors (OnTrack call this code DDO: Dynamic Drive Overlay), so that it is booted before any other operating system. That is why one may have problems when booting from a floppy when a Disk Manager has been installed.
The effect is more less the same as with a translating BIOS - but especially when running several operating systems on the same disk, disk managers can cause a lot of trouble.
Linux does support OnTrack Disk Manager since version 1.3.14, and EZ-Drive since version 1.3.29.
If the Linux kernel detects the presence of some disk manager on an IDE disk, it will try to remap the disk in the same way this disk manager would have done, so that Linux sees the same disk partitioning as for example DOS with OnTrack or EZ-Drive. However, No remapping is done when a geometry was specified on the command line - so a 'hd=cyls,heads,secs' command line option might well kill compatibility with a disk manager.
The remapping is done by trying 4, 8, 16, 32, 64, 128, 255 heads (keeping H*C) constant) until either C <= 1024 or H=255.
The details are as follows - subsection headers are the strings appearing in the corresponding boot messages. Here and everywhere else in this text, partition types are given in hexadecimal.
EZD
EZ-Drive is detected by the fact that the first primary partition has type 55. The geometry is remapped as described above, and the partition table from sector 0 is discarded - instead the partition table is read from sector 1. Disk block numbers are not changed, but writes to sector 0 are redirected to sector 1. This behavior can be changed by recompiling the kernel with
#define FAKE_FDISK_FOR_EZDRIVE 0 in ide.c
DM6:DDO
OnTrack DiskManager (on the first disk) is detected by the fact that the first primary partition has type 54. The geometry is remapped as described above and the entire disk is shifted by 63 sectors (so that the old sector 63 becomes sector 0). Afterwards a new MBR (with the partition table) is read from the new sector 0. Of course this shift is to make room for the DDO - that is why there is no shift on other disks.
DM6:AUX
OnTrack DiskManager (on other disks) is detected by the fact that the first primary partition has type 51 or 53. The geometry is remapped as described above.
DM6:MBR
An older version of OnTrack DiskManaager is detected not by partition type, but by signature. (Test whether the offset found in bytes 2 and 3 of the MBR is not more than 430, and the short found at this offset equals 0x55AA, and is followed by an odd byte.) Again the geometry is remapped as above.
PTBL
Finally, there is a test that tries to deduce a translation from the start and end values of the primary partitions: If some partition has start and end cylinder less than 256, and start and send sector number 1 and 63, respectively, and end heads 31, 63, or 127, then, since it is customary to end partitions on a cylinder boundary and since moreover the IDE interface uses at most 16 heads, it is conjectured that a BIOS translation is active, and the geometry is remapped to use 32, 64 or 128 heads, respectively. (Maybe there is a flaw here, and genhd.c should not have tested the high order two bits of the cylinder number?) However, no remapping is done when the current idea of the geometry already has 63 sectors per track and at least as many heads (since this probably means that a remapping was done already).
What does all of this mean? For Linux users only one thing: that they must make sure that LILO and fdisk (cfdisk) use the right geometry where 'right' is defined for fdisk as the geometry used by the other operating systems on the same disk, and for LILO as the geometry that will enable successful integration with the BIOS at boot time. (Usually these two requirements coincide.)
Then how does fdisk and an OS determine the geometry of a large IDE drive? In descending order 1) command line arguments 2) CMOS values and 3) IDE Controller values. The OS then must determine via algorithm not a physical geometry, but rather a logical geometry. As a point of fact, the actual physical geometry is unimportant, rather fdisk and an OS simply must agree on a logical geometry which maps the entire physical drive. The actual values of C', H', and S' may or may not match the physical drive, but they must be agreed upon by both fdisk and all the OSs which will use the partition tables.
For SCSI drives, the SCSI commands already use logical block numbers, so a 'geometry' is entirely irrelevant for actual I/O. However, the format of the partition table is still the same, so fdisk has to invent some geometry because fdisk does not distinguish between IDE and SCSI. What is the real geometry of a SCSI disk? The easiest answer is that there is no such thing. And if there were, you wouldn't wan to know, and certainly NEVER, EVER tell fdisk or LILO or the kernel about it. It is strictly a business between the SCSI controller and the disk. Let me repeat that: only silly people tell fdisk/LILO/kernel about the TRUE SCSI geometry.
One final note, by convention partitions end on a cylinder boundary. This again is for the convience of DOS partitions. Some fdisk implementations enforce this restrictions, some implementations give warnings if this restriction is ignored, and some implementation ignore this restriction. My advice would be to pay homage to DOS and be safe.
Some interesting entries in the /etc/lilo.conf file are:
BOOT = The location where the bootstrap loader and configuration information should be written. If not specified the current / partition is used as default.
COMPACT = Tries to merge read requests for adjacent sectors into a single read request. This drastically reduces load time and keeps the map smaller. Using COMPACT is especially recommended when bootingh from a floppy disk. COMPACT may cause conflicts with the use of the LINEAR option.
DEFAULT = The image to be used as the boot image if the operator does not choose another.
delay = Specified the numbefr of tenths of a second LILO should wait before booting the first image.
DISK = Defines any non-standard disk paramaters (I/O Address, Geometry).
INSTALL = Install the specified file as the new boot sector. If INSTALL is omitted, then /boot/boot.b is used as the default.
LINEAR = Generate linear sector addresses instead of sector/head/cylinder addresses. Make sure your BIOS setting agrees with the use of this option.
MAP= Specified the location of the map file. If MAP is omitted, a file /boot/map is used.
MESSAGE= A file containing a message to be displayed before outputting the LILO prompt. This file is limited to 65K in length.
PASSWORD = Requires the operator to enter a password before the boot process will continue.
A sample lilo.conf file follows:
#
# general section
#
boot = /dev/sdb1
install =/boot/boot.b
message = /boot/message
prompt
# wait 20 seconds (200 10ths) for user to select the entry
timeout = 200
#
# default entry
#
image = /vmlinuz
label = linux
root = /dev/sdb1
read-only
#
# additional entries
#
image = /vmlinuz.960505
label = OldLinux
root = /dev/sdb1
read-only
e. One suggestion
/ 30M
usr 300M
var 100M
root 100M
tmp 100M
home 200M
swap 32M
First Disk Second Disk Third Disk
1 2 3
6 5 4
7 8 9
Acknowledgements:
Much of the information for this presentation was taken verbatim from the following sources: