Linux Step By Steps

Author Mike Andrew with some help by Joel Hatton

The 8 GB / 1024 CYL limit discussed in this document has been broken with LILO-21.5
Get the tarball source here:

If you still need to run an older version of LILO for whatever the reason, read on...


No matter which way you swing it, both the ide hardware and the bios conspire against you so that you CANNOT boot beyond the 8gig, 1024 cylinder limit. Whichever comes first.

In both cases it is because of an addressing scheme called C/H/S. Cylinder, Head, Sector.

All boot loaders use the bios to extract further information (sectors) from the disk. After all, it was the bios which loaded the initial boot sector (mbr) into memory in the first place!

By 'using bios' we mean interrupt 13h. The paramater passed is a 24 bit field constructed as follows

Field Cylinder Head Sector
Bits 10 8 6
Addressable size 1024 256 63*

*Sector 0 does not exist as an addressable entity on a hard disk (it is used internally for track info). Thus 63, not, 64 sectors.

A sector is the smallest addressable entity in a hard disk. It contains 512 bytes.

Doing some math, the MAXIMUM address available using int 13h of the bios is

1024 x 256 x 63 = 16 meg of sectors which = 8,455,716,864 or 8gig of data.

No matter which way you swing this, a boot loader, any boot loader, cannot access data beyond this range because you cannot pass large enough paramaters to the bios to do so.

The data that the boot loader loads certainly can address more than 8gig. The linux kernel does not use bios, and can do whatever it chooses to do with the hard disk. This is why people say 'you must make a small boot partition for linux'. In other words place the boot loading code below the 1024, 8gig limit. (see below for how to)

No boot loader exists, nor can it ever exist, to get over this problem. The initial, tiny tiny tiny 446 byte boot code off the mbr of a hard drive has only enough code to load more, bios addressable, sectors.

THE 500Meg Limit

Compounding this problem is the ide interface itself. Due to amazing stupidity in the original design, this is the interface paramaters that bios can use to access the ide interface.

Field Cylinder Head Sector
Bits 16 4 8
Addressable size 65,536 16 255

This gives a theoretical capacity of 136,902,082,560 (137gig), except for the 'minor' problem that the os cannot ask the bios for more than 1023 cylinders and conversely, the bios cannot ask the hd for more than 16 heads. So, the actual situation looks like this:

Field Cylinder Head Sector
Bios Bits 10 8 6
Ide bits 16 4 8
Actual bits 10 4 6
Actual size 1024 16 63

More simple math yields 1024 x 16 x 63 x 512 = 528.482.304 bytes (528 meg)


To get round this problem, the bios takes the front end of 1024 x 256 x 64 sectors and (in effect) reverses the head and sector values to accomodate the poorly designed ide interface (don't read this too literally). In this way the 512meg barrier was initially broken but the *actual* chs geometry of the disk, and that reported by bios, is different. Large addressing is only used on ide interfaces that cannot do the following;


Logicial block addressing, or LBA was introduced with the EIDE interface. Extended IDE because it extends the address range.

LBA in fact means linear sector addressing. The only thing passed to / from the ide interface to the bios are sectors. It is entirely up to the hard drive and ide to sort out where the 'geometry' fits. The bios however, still presents it's CHS interface to the operating system. Ie 1024x256x63 sectors are converted, by the bios, into a logical sector value and passed as a single number to the ide interface. This is the method used nowadays for almost all hard drives, and has always been the way a SCSI hard drive works. How the ide interface was stuffed up so badly in design in the first place beggars belief.

While this method overcomes the 512meg barrier on extended eide interfaces, the 8 gig limit remains in force.


Linux uses 32 bit linear sector addressing. It does not know about, nor care about, cylinders, heads and sectors. A 32 bit word allows a linear address of two TERAbytes. Enough perhaps for the next 6 years or so. Linear addressing has always been the address method employed on SCSI hard drives.

Again, this does not help you, even if booting on a scsi drive! The bios interface converts CHS to linear scsi address. You are STILL handicapped by the 8gig limit.


In short, there is no such thing. In the 'good old days' drives were physically arranged to have a series of platters on which heads read consecutive 'tracks' (cylinders). Each track was formatted with 64 sectors per track and 512 bytes in each. The only items that changed were the number of tracks, the number of platters (heads), and sometimes the amount of data in each sector.

Today, hard disks have more sectors on their outside tracks than their inside tracks and the amount of data within a physical sector varies. It is rarely 512 bytes. This therefore violates the meaning behind Cylinder, head, and sector because it does not apply to the disk as a whole.

The only reliable guide, a uniform measurement, is the 'logical' definition of 512 bytes per linear sector. Linear meaning sector + 1 is the next logical sector on the disk. Where the 'next' sector is physically is anyone's guess and nobody's buisiness.

At this stage in personal computing (Jan 2000) we are in a transistion between the old 'legacy' method of CHS addressing and the more evolutionary linear sector addressing. For some time yet, the bios's of PC's will continue to support the Interrupt 13 style (CHS) interface. Linear bios addressing is not yet on the horizon but will come.


This is a single hard drive setup in the following manner on a (now) popular 13 gig drive. The gig numbers are exaggerated for emphasis

/dev/hda1 1meg linux /boot partition
/dev/hda2 10gig dos/windows
/dev/hda3 3gig linux
/dev/hda4 128meg linux swap

The /boot partition contains ALL boot sensitive files. Specifically


The /boot partiton is mounted as follows

mount -t ext2fs /dev/hda1 /boot

the /etc/fstab entry is as follows

/dev/hda1 ext2fs  /boot  defaults 1 1 << make sure this is 1 1
/dev/hda2 vfat    /dos   defaults 0 0
/dev/hda3 extfs   /      defaults 1 1

lilo.conf is as follows

boot = /dev/hda <<install on the master boot record of hda
install = /boot/boot.b

delay = 50
timeout = 50
vga     = normal

default = dos << boot to windows if no input (uuuurgh)

# maintain the original distributed kernel (and it's modules) at all times

image = /boot/vmlinuz-2.2.10-modular
    label  = linux
    root   = /dev/hda3

# use this image when compiling 'new' kernels

image = /boot/some_other_image
    label  = new
    root   = /dev/hda3

# use this for dos dual booting

other = /dev/hda2

  label = dos
  table = /dev/hda