From: Andrei Borzenkov Subject: [PATCH] biosdisk: debug output for disk parameters Add debug output to track BIOS behavior with 4Kn disks. --- grub-core/disk/i386/pc/biosdisk.c | 45 +++++++++++++++++++++++++++++++++++---- include/grub/i386/pc/biosdisk.h | 1 + 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index f0aadd1..ef69f13 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -84,6 +84,8 @@ grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) grub_bios_interrupt (0x13, ®s); return (regs.eax >> 8) & 0xff; + // return regs.flags & GRUB_CPU_INT_FLAGS_CARRY ? (regs.eax >> 8) & 0xff : 0; + } /* @@ -335,6 +337,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) grub_uint64_t total_sectors = 0; int drive; struct grub_biosdisk_data *data; + int ret; drive = grub_biosdisk_get_drive (name); if (drive < 0) @@ -369,11 +372,17 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) struct grub_biosdisk_drp *drp = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_dprintf ("biosdisk", "%s: int13 version=%u\n", disk->name, version); /* Clear out the DRP. */ grub_memset (drp, 0, sizeof (*drp)); drp->size = sizeof (*drp); - if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp)) + if (! (ret = grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))) { + grub_dprintf ("biosdisk", "%s: DRP size=%u flags=%x c=%u h=%u s=%u t=%" + PRIuGRUB_UINT64_T " bpi=%u\n", + disk->name, drp->size, drp->flags, drp->cylinders, drp->heads, + drp->sectors, drp->total_sectors, drp->bytes_per_sector); + data->flags = GRUB_BIOSDISK_FLAG_LBA; if (drp->total_sectors) @@ -394,16 +403,22 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) disk->log_sector_size++); } } + else + grub_dprintf ("biosdisk", "%s: int13 get ext failed %x\n", disk->name, ret); } + else + grub_dprintf ("biosdisk", "%s: int13 check ext failed\n", disk->name); } if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM)) { - if (grub_biosdisk_get_diskinfo_standard (drive, + if ((ret = grub_biosdisk_get_diskinfo_standard (drive, &data->cylinders, &data->heads, - &data->sectors) != 0) + &data->sectors)) != 0) { + grub_dprintf ("biosdisk", "%s: get_diskinfo failed %x\n", disk->name, ret); + if (total_sectors && (data->flags & GRUB_BIOSDISK_FLAG_LBA)) { data->sectors = 63; @@ -419,6 +434,9 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) return grub_error (GRUB_ERR_BAD_DEVICE, "%s cannot get C/H/S values", disk->name); } } + else + grub_dprintf ("biosdisk", "%s: C/H/S=%lu/%lu/%lu\n", disk->name, + data->cylinders, data->heads, data->sectors); if (data->sectors == 0) data->sectors = 63; @@ -461,6 +479,7 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, unsigned segment) { struct grub_biosdisk_data *data = disk->data; + int ret; /* VirtualBox fails with sectors above 2T on CDs. Since even BD-ROMS are never that big anyway, return error. */ @@ -501,19 +520,37 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, disk->name); } else - if (grub_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap)) + if ((ret = grub_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap))) { + grub_dprintf ("biosdisk", "%s: ext sec=%" PRIuGRUB_UINT64_T " size=%" + PRIuGRUB_SIZE " ret=%u\n", + disk->name, sector, size, ret); + /* Fall back to the CHS mode. */ data->flags &= ~GRUB_BIOSDISK_FLAG_LBA; disk->total_sectors = data->cylinders * data->heads * data->sectors; return grub_biosdisk_rw (cmd, disk, sector, size, segment); } + else if (!(data->flags & GRUB_BIOSDISK_FLAG_DPRINT)) + { + grub_dprintf ("biosdisk", "%s: ext sec=%" PRIuGRUB_UINT64_T " size=%" + PRIuGRUB_SIZE "\n", + disk->name, sector, size); + data->flags |= GRUB_BIOSDISK_FLAG_DPRINT; + } } else { unsigned coff, hoff, soff; unsigned head; + if (!(data->flags & GRUB_BIOSDISK_FLAG_DPRINT)) + { + grub_dprintf ("biosdisk", "%s: legacy sec=%" PRIuGRUB_UINT64_T " size=%" + PRIuGRUB_SIZE "\n", + disk->name, sector, size); + data->flags |= GRUB_BIOSDISK_FLAG_DPRINT; + } /* It is impossible to reach over 8064 MiB (a bit less than LBA24) with the traditional CHS access. */ if (sector > diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h index 3d80716..fa0862f 100644 --- a/include/grub/i386/pc/biosdisk.h +++ b/include/grub/i386/pc/biosdisk.h @@ -24,6 +24,7 @@ #define GRUB_BIOSDISK_FLAG_LBA 1 #define GRUB_BIOSDISK_FLAG_CDROM 2 +#define GRUB_BIOSDISK_FLAG_DPRINT 4 #define GRUB_BIOSDISK_CDTYPE_NO_EMUL 0 #define GRUB_BIOSDISK_CDTYPE_1_2_M 1 -- tg: (0d663b5..) t/biosdisk (depends on: master)