Package: grub Version: 0.97-23 Severity: important Tags: patch If a file happens to use the last sectors on a device which is using LBA mode access, grub will ask the bios to read past the end of the disk which on some bioses causing a long delay (which looks like the system is hung). I have seen 2 minutes on some of my systems and a couple of hours on another type of system.
The issue occours because in LBA mode grub only knows the total_sectors of the device, and hence always reads 63 sectors at a time for its vtrack buffering. Since the device might not have 63 sectors per track (almost all hard disks do of course, but a compact flash card that is 256MB almost certainly doesn't). My flash card is 16 heads, 32 sectors/track, 978 cylinders or similar). Occationally a kernel or ramdisk file happens to be in the last sectors of the filesystem which is hence the end of the disk. When grub tries to read the last sectors, it asks the bios to read 63 sectors starting at the last vtrack start of the disk, where there may only be 16 or 28 or something sectors left, and the bios doesn't appreciate going past the end of the disk. Eventually it returns an error and grub retries the read one sector at a time which works fine. The fix is to check that read_start + read_len <= total_sectors, and if it isn't, then adjust the read_len down to the difference between read_start and total_sectors. With this change there is no hang and everything works fine since the bios is never asked to read past the end of the device. I imagine this was never caught in the past since almost all devices that use LBA are large harddisks which always use 63 sectors per track and 255 heads in order to give the lowest possible cylinder count. This problem almost certainly exists in every grub 0.x version, including sarge. If a user happens to have a disk where sectors per track is not 63 when in LBA mode, and they happen to have a kernel or initrd file end up at the end of the device, then they will not be able to boot that kernel. Here is the patch: diff -ruN grub-0.97.ori/stage2/disk_io.c grub-0.97/stage2/disk_io.c --- grub-0.97.ori/stage2/disk_io.c 2007-03-16 11:25:46.000000000 -0400 +++ grub-0.97/stage2/disk_io.c 2004-05-23 12:35:24.000000000 -0400 @@ -205,6 +205,14 @@ bufaddr = (char *) BUFFERADDR + byte_offset; } + /* + * Make sure not to ask the bios to read past end of disk + * since some bioses take a long time to fail + */ + if ((read_start + read_len) > buf_geom.total_sectors) + { + read_len = (buf_geom.total_sectors) - read_start; + } bios_err = biosdisk (BIOSDISK_READ, drive, &buf_geom, read_start, read_len, BUFFERSEG); if (bios_err) -- System Information: Debian Release: 4.0 APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.18-3-k7 Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Versions of packages grub depends on: ii libc6 2.3.6.ds1-13 GNU C Library: Shared libraries ii libncurses5 5.5-5 Shared libraries for terminal hand grub recommends no packages. -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]