If a system is about from year 1994 or older, its BIOS might not be able to handle disks with Clusters/Heads/Sectors geometry larger than 1024/16/63, which works out to a limit of 504 MiB (528.4 MB). The reason for this was an inconvenient interaction of two sets of limits:
- the classic unextended BIOS INT 13h function accepted a maximum disk geometry of 1024/255/63
- the IDE (PATA) hardware would accept a maximum geometry of 65536/16/63
- so far, trivial implementations just picked the smallest limit in each value, resulting in a limit of 1024/16/63.
In July 1994, a new BIOS feature "Enhanced Disk Drive Services" (EDD for short) was developed to work around this limit. It shifted bits between the Clusters and Heads parts of the geometry between BIOS representation and the IDE hardware interface (called "geometry translation"), as a workaround for this limit.
Some BIOS versions also had bugs at disk geometry 4096/16/16 or its "translated" form 1024/64/63.
At disk geometry of 16383/16/63 (or 1024/255/63 in translated form), the maximum limit of classic C/H/S disk addressing was reached: the data input formats of the BIOS functions handling this kind of disk addressing simply did not have enough bits to handle disks bigger than this. This limit was reached at disk size of 7.87 GiB (8.45 GB), or exactly 16 450 560 disk blocks.
The IDE (PATA) specification included a feature that could work around this, but it was initially specified as optional feature, and not all BIOSes implemented it. It was called Logical Block Addressing, or LBA for short. As disk sizes grew, most disks released after 1996 or so did support LBA.
But then another BIOS bug was discovered: some BIOSes had a faulty LBA implementation that failed if more than 26 bits was required to represent the disk block number. This affected some BIOS versions released in August 1999 or older, and it caused a limit at disk size of exactly 32 GiB (33.8 GB).
The LBA specification that was released in 1994 had allocated only 28 bits for the disk block number, and this caused a yet another disk size limit at exactly 128 GiB disk size. The ATA-6 specification released in year 2003 specified 48-bit versions of the LBA disk access functions, which is what we're currently using with modern SATA disks. It should work until disk sizes grow to 128 PiB.
It was often possible to work around these limitations by deliberately specifying an incorrect disk geometry in BIOS, telling it that the disk was smaller than the offending limit, and making /boot
a partition that fit completely within the fake geometry.
Sometimes (after the LBA support was introduced) it was enough that the /boot
partition was within the appropriate size limit.
The bootloader would use BIOS routines to load the Linux kernel (and optionally an initrd file) from this partition, and once the kernel was started, its drivers would take over disk access, bypassing BIOS altogether and making its limitations irrelevant as long as the OS was running. At this point, the real disk geometry would usually be auto-detected by the kernel.
So, what does this mean?
- if your system has a BIOS release date in year 2004 or older, you may need to create a
/boot
partition that fits entirely within the first 128 GiB of the disk, or else the BIOS might fail to boot the OS. (This is usually a problem for dual-boot and other multi-OS setups only.)
- if your system has a BIOS release date of before year 2000, you might want to create a separate
/boot
partition within the first 32 GiB of the disk, just to be safe from LBA implementation bugs.
- if the system is from 1996 or older and does not mention "LBA" anywhere in BIOS settings, you might have to specify a fake disk geometry and make sure your
/boot
partition is both within the fake geometry and within the first 7.87 GiB of the disk.
- anything older than that: "It belongs to a museum." :-) But if you must, see above for the relevant limits.
If a system's BIOS release date is only just after the date of a particular specification update, it might or might not have the updated specification: after each specification update was released, it took some time for the new implementations to become ubiquitous.
ls (
and press TAB. If it displays devices like(ahci0)
or(ata0)
, then you have a baremetal-capable GRUB. If you see(hd0)
, it's using BIOS support. https://www.gnu.org/software/grub/manual/grub/grub.html#Device-syntax – telcoM May 07 '21 at 21:30/boot/grub/i386-pc
needs to be within the BIOS support limitations anyway. The alternative is to usegrub-mkimage
to build a custom GRUB image that embeds the appropriate module to the main GRUB image and install it, then do it again every time the distribution releases a GRUB update. I've yet to see an installer that would do this automatically. – telcoM May 07 '21 at 21:35core.img
(generally) and it allows GRUB to access any file directly (without third parties). – May 08 '21 at 03:34grub-mkimage
program. It is funny that an almost complete OS has to be built (GRUB) to load the actual OS. – May 08 '21 at 03:38disk_module
based on command line options, defaulting tobiosdisk
oni386-pc
architecture. – telcoM May 08 '21 at 08:32