Package: grub
Version: 0.5.93.1
I have a buggy BIOS that supports the extended drive information call, but
not LBA read. Grub can't read anything from the disk if NO_INT13_FALLBACK
is defined. I see no reason not to enable the fallback all the time; the
appended patch for bios.c does that, and cleans up the logic a bit.
The motherboard is an Asus P3B-F; I am not sure of the precise BIOS
revision.
Incidentally, shouldn't grub use the cylinder/head/sector values from the
extended drive info call if available?
zw
--- grub-0.5.93.1/stage2/bios.c Thu Aug 12 02:38:44 1999
+++ grub-0.5.93.1z/stage2/bios.c Sat Dec 25 08:55:26 1999
@@ -37,7 +37,14 @@
unsigned long *cylinders,
unsigned long *heads,
unsigned long *sectors);
-
+struct disk_address_packet
+{
+ unsigned char length;
+ unsigned char reserved;
+ unsigned short blocks;
+ unsigned long buffer;
+ unsigned long long block;
+};
/* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
@@ -48,19 +55,12 @@
biosdisk (int read, int drive, struct geometry *geometry,
int sector, int nsec, int segment)
{
- int err;
+ struct disk_address_packet dap;
+ int cylinder_offset, head_offset, sector_offset;
+ int head;
if (geometry->flags & BIOSDISK_FLAG_LBA_EXTENSION)
{
- struct disk_address_packet
- {
- unsigned char length;
- unsigned char reserved;
- unsigned short blocks;
- unsigned long buffer;
- unsigned long long block;
- } dap;
-
if (sector >= geometry->total_sectors)
return BIOSDISK_ERROR_GEOMETRY;
@@ -70,46 +70,33 @@
dap.block = sector;
dap.blocks = nsec;
dap.reserved = 0;
- /* This is undocumented part. The address is formated in
- SEGMENT:ADDRESS. */
+ /* The buffer address is expected in SEGMENT:OFFSET notation.
+ We know the OFFSET is zero. */
dap.buffer = segment << 16;
- err = biosdisk_int13_extensions (read + 0x42, drive, &dap);
+ if (biosdisk_int13_extensions (read + 0x42, drive, &dap) == 0)
+ return 0;
-#define NO_INT13_FALLBACK 1
-#ifndef NO_INT13_FALLBACK
- if (err)
- {
- geometry->flags &= ~BIOSDISK_FLAG_LBA_EXTENSION;
- geometry->total_sectors = (geometry->cylinders
- * geometry->heads
- * geometry->sectors);
- return biosdisk (read, drive, geometry, sector, nsec, segment);
- }
-#endif /* ! NO_INT13_FALLBACK */
-
+ /* That didn't work. Fall back to the old BIOS call. */
+ geometry->flags &= ~BIOSDISK_FLAG_LBA_EXTENSION;
+ geometry->total_sectors = (geometry->cylinders
+ * geometry->heads
+ * geometry->sectors);
}
- else
- {
- int cylinder_offset, head_offset, sector_offset;
- int head;
- /* SECTOR_OFFSET is counted from one, while HEAD_OFFSET and
- CYLINDER_OFFSET are counted from zero. */
- sector_offset = sector % geometry->sectors + 1;
- head = sector / geometry->sectors;
- head_offset = head % geometry->heads;
- cylinder_offset = head / geometry->heads;
+ /* SECTOR_OFFSET is counted from one, while HEAD_OFFSET and
+ CYLINDER_OFFSET are counted from zero. */
+ sector_offset = sector % geometry->sectors + 1;
+ head = sector / geometry->sectors;
+ head_offset = head % geometry->heads;
+ cylinder_offset = head / geometry->heads;
- if (cylinder_offset >= geometry->cylinders)
- return BIOSDISK_ERROR_GEOMETRY;
-
- err = biosdisk_standard (read + 0x02, drive,
- cylinder_offset, head_offset, sector_offset,
- nsec, segment);
- }
+ if (cylinder_offset >= geometry->cylinders)
+ return BIOSDISK_ERROR_GEOMETRY;
- return err;
+ return biosdisk_standard (read + 0x02, drive,
+ cylinder_offset, head_offset, sector_offset,
+ nsec, segment);
}
/* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return