Merge pull request #31 from marineam/verbose-debug
Add verbose debug logging to biosdisk and gpt
This commit is contained in:
commit
1c205c2c4d
2 changed files with 134 additions and 10 deletions
|
@ -278,10 +278,14 @@ grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data,
|
|||
char name[10];
|
||||
|
||||
if (cd_drive && drive == cd_drive)
|
||||
return hook ("cd", hook_data);
|
||||
{
|
||||
grub_dprintf ("biosdisk", "iterating cd\n");
|
||||
return hook ("cd", hook_data);
|
||||
}
|
||||
|
||||
grub_snprintf (name, sizeof (name),
|
||||
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
|
||||
grub_dprintf ("biosdisk", "iterating %s\n", name);
|
||||
return hook (name, hook_data);
|
||||
}
|
||||
|
||||
|
@ -301,7 +305,7 @@ grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
|
|||
if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
|
||||
GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
|
||||
{
|
||||
grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
|
||||
grub_dprintf ("biosdisk", "Read error when probing drive 0x%2x\n", drive);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -336,6 +340,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
int drive;
|
||||
struct grub_biosdisk_data *data;
|
||||
|
||||
grub_dprintf ("biosdisk", "opening %s\n", name);
|
||||
|
||||
drive = grub_biosdisk_get_drive (name);
|
||||
if (drive < 0)
|
||||
return grub_errno;
|
||||
|
@ -393,6 +399,11 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
(1 << disk->log_sector_size) < drp->bytes_per_sector;
|
||||
disk->log_sector_size++);
|
||||
}
|
||||
|
||||
grub_dprintf ("biosdisk",
|
||||
"LBA total = 0x%llx block size = 0x%lx\n",
|
||||
(unsigned long long) total_sectors,
|
||||
1L << disk->log_sector_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,6 +439,9 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
if (! total_sectors)
|
||||
total_sectors = ((grub_uint64_t) data->cylinders)
|
||||
* data->heads * data->sectors;
|
||||
|
||||
grub_dprintf ("biosdisk", "C/H/S %lu/%lu/%lu\n",
|
||||
data->cylinders, data->heads, data->sectors);
|
||||
}
|
||||
|
||||
disk->total_sectors = total_sectors;
|
||||
|
@ -440,12 +454,15 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
|
||||
disk->data = data;
|
||||
|
||||
grub_dprintf ("biosdisk", "opening %s succeeded\n", name);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_biosdisk_close (grub_disk_t disk)
|
||||
{
|
||||
grub_dprintf ("biosdisk", "closing %s\n", disk->name);
|
||||
grub_free (disk->data);
|
||||
}
|
||||
|
||||
|
@ -577,6 +594,9 @@ static grub_err_t
|
|||
grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_size_t size, char *buf)
|
||||
{
|
||||
grub_dprintf ("biosdisk", "reading 0x%lx sectors at 0x%llx from %s\n",
|
||||
(unsigned long) size, (unsigned long long) sector, disk->name);
|
||||
|
||||
while (size)
|
||||
{
|
||||
grub_size_t len;
|
||||
|
@ -607,6 +627,9 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
{
|
||||
struct grub_biosdisk_data *data = disk->data;
|
||||
|
||||
grub_dprintf ("biosdisk", "writing 0x%lx sectors at 0x%llx to %s\n",
|
||||
(unsigned long) size, (unsigned long long) sector, disk->name);
|
||||
|
||||
if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
|
||||
return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM"));
|
||||
|
||||
|
|
|
@ -207,6 +207,18 @@ grub_gpt_pmbr_check (struct grub_msdos_partition_mbr *mbr)
|
|||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid protective MBR");
|
||||
}
|
||||
|
||||
static grub_uint64_t
|
||||
grub_gpt_entries_sectors (struct grub_gpt_header *gpt,
|
||||
unsigned int log_sector_size)
|
||||
{
|
||||
grub_uint64_t sector_bytes, entries_bytes;
|
||||
|
||||
sector_bytes = 1ULL << log_sector_size;
|
||||
entries_bytes = (grub_uint64_t) grub_le_to_cpu32 (gpt->maxpart) *
|
||||
(grub_uint64_t) grub_le_to_cpu32 (gpt->partentry_size);
|
||||
return grub_divmod64(entries_bytes + sector_bytes - 1, sector_bytes, NULL);
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_gpt_header_check (struct grub_gpt_header *gpt,
|
||||
unsigned int log_sector_size)
|
||||
|
@ -236,6 +248,64 @@ grub_gpt_header_check (struct grub_gpt_header *gpt,
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_gpt_check_primary (grub_gpt_t gpt)
|
||||
{
|
||||
grub_uint64_t backup, primary, entries, entries_len, start, end;
|
||||
|
||||
primary = grub_le_to_cpu64 (gpt->primary.header_lba);
|
||||
backup = grub_le_to_cpu64 (gpt->primary.alternate_lba);
|
||||
entries = grub_le_to_cpu64 (gpt->primary.partitions);
|
||||
entries_len = grub_gpt_entries_sectors(&gpt->primary, gpt->log_sector_size);
|
||||
start = grub_le_to_cpu64 (gpt->primary.start);
|
||||
end = grub_le_to_cpu64 (gpt->primary.end);
|
||||
|
||||
grub_dprintf ("gpt", "Primary GPT layout:\n"
|
||||
"primary header = 0x%llx backup header = 0x%llx\n"
|
||||
"entries location = 0x%llx length = 0x%llx\n"
|
||||
"first usable = 0x%llx last usable = 0x%llx\n",
|
||||
(unsigned long long) primary,
|
||||
(unsigned long long) backup,
|
||||
(unsigned long long) entries,
|
||||
(unsigned long long) entries_len,
|
||||
(unsigned long long) start,
|
||||
(unsigned long long) end);
|
||||
|
||||
if (grub_gpt_header_check (&gpt->primary, gpt->log_sector_size))
|
||||
return grub_errno;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_gpt_check_backup (grub_gpt_t gpt)
|
||||
{
|
||||
grub_uint64_t backup, primary, entries, entries_len, start, end;
|
||||
|
||||
backup = grub_le_to_cpu64 (gpt->backup.header_lba);
|
||||
primary = grub_le_to_cpu64 (gpt->backup.alternate_lba);
|
||||
entries = grub_le_to_cpu64 (gpt->backup.partitions);
|
||||
entries_len = grub_gpt_entries_sectors(&gpt->backup, gpt->log_sector_size);
|
||||
start = grub_le_to_cpu64 (gpt->backup.start);
|
||||
end = grub_le_to_cpu64 (gpt->backup.end);
|
||||
|
||||
grub_dprintf ("gpt", "Backup GPT layout:\n"
|
||||
"primary header = 0x%llx backup header = 0x%llx\n"
|
||||
"entries location = 0x%llx length = 0x%llx\n"
|
||||
"first usable = 0x%llx last usable = 0x%llx\n",
|
||||
(unsigned long long) primary,
|
||||
(unsigned long long) backup,
|
||||
(unsigned long long) entries,
|
||||
(unsigned long long) entries_len,
|
||||
(unsigned long long) start,
|
||||
(unsigned long long) end);
|
||||
|
||||
if (grub_gpt_header_check (&gpt->backup, gpt->log_sector_size))
|
||||
return grub_errno;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_gpt_read_primary (grub_disk_t disk, grub_gpt_t gpt)
|
||||
{
|
||||
|
@ -246,11 +316,13 @@ grub_gpt_read_primary (grub_disk_t disk, grub_gpt_t gpt)
|
|||
* but eventually this code should match the existing behavior. */
|
||||
gpt->log_sector_size = disk->log_sector_size;
|
||||
|
||||
grub_dprintf ("gpt", "reading primary GPT from sector 0x1\n");
|
||||
|
||||
addr = grub_gpt_sector_to_addr (gpt, 1);
|
||||
if (grub_disk_read (disk, addr, 0, sizeof (gpt->primary), &gpt->primary))
|
||||
return grub_errno;
|
||||
|
||||
if (grub_gpt_header_check (&gpt->primary, gpt->log_sector_size))
|
||||
if (grub_gpt_check_primary (gpt))
|
||||
return grub_errno;
|
||||
|
||||
gpt->status |= GRUB_GPT_PRIMARY_HEADER_VALID;
|
||||
|
@ -272,11 +344,14 @@ grub_gpt_read_backup (grub_disk_t disk, grub_gpt_t gpt)
|
|||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"Unable to locate backup GPT");
|
||||
|
||||
grub_dprintf ("gpt", "reading backup GPT from sector 0x%llx\n",
|
||||
(unsigned long long) sector);
|
||||
|
||||
addr = grub_gpt_sector_to_addr (gpt, sector);
|
||||
if (grub_disk_read (disk, addr, 0, sizeof (gpt->backup), &gpt->backup))
|
||||
return grub_errno;
|
||||
|
||||
if (grub_gpt_header_check (&gpt->backup, gpt->log_sector_size))
|
||||
if (grub_gpt_check_backup (gpt))
|
||||
return grub_errno;
|
||||
|
||||
gpt->status |= GRUB_GPT_BACKUP_HEADER_VALID;
|
||||
|
@ -289,6 +364,7 @@ grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt,
|
|||
{
|
||||
struct grub_gpt_partentry *entries = NULL;
|
||||
grub_uint32_t count, size, crc;
|
||||
grub_uint64_t sector;
|
||||
grub_disk_addr_t addr;
|
||||
grub_size_t entries_size;
|
||||
|
||||
|
@ -310,7 +386,12 @@ grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt,
|
|||
if (!entries)
|
||||
goto fail;
|
||||
|
||||
addr = grub_gpt_sector_to_addr (gpt, grub_le_to_cpu64 (header->partitions));
|
||||
sector = grub_le_to_cpu64 (header->partitions);
|
||||
grub_dprintf ("gpt", "reading GPT %lu entries from sector 0x%llx\n",
|
||||
(unsigned long) count,
|
||||
(unsigned long long) sector);
|
||||
|
||||
addr = grub_gpt_sector_to_addr (gpt, sector);
|
||||
if (grub_disk_read (disk, addr, 0, entries_size, entries))
|
||||
goto fail;
|
||||
|
||||
|
@ -336,6 +417,8 @@ grub_gpt_read (grub_disk_t disk)
|
|||
{
|
||||
grub_gpt_t gpt;
|
||||
|
||||
grub_dprintf ("gpt", "reading GPT from %s\n", disk->name);
|
||||
|
||||
gpt = grub_zalloc (sizeof (*gpt));
|
||||
if (!gpt)
|
||||
goto fail;
|
||||
|
@ -369,12 +452,18 @@ grub_gpt_read (grub_disk_t disk)
|
|||
/* Similarly, favor the value or error from the primary table. */
|
||||
if (gpt->status & GRUB_GPT_BACKUP_HEADER_VALID &&
|
||||
!grub_gpt_read_entries (disk, gpt, &gpt->backup))
|
||||
gpt->status |= GRUB_GPT_BACKUP_ENTRIES_VALID;
|
||||
{
|
||||
grub_dprintf ("gpt", "read valid backup GPT from %s\n", disk->name);
|
||||
gpt->status |= GRUB_GPT_BACKUP_ENTRIES_VALID;
|
||||
}
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
if (gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID &&
|
||||
!grub_gpt_read_entries (disk, gpt, &gpt->primary))
|
||||
gpt->status |= GRUB_GPT_PRIMARY_ENTRIES_VALID;
|
||||
{
|
||||
grub_dprintf ("gpt", "read valid primary GPT from %s\n", disk->name);
|
||||
gpt->status |= GRUB_GPT_PRIMARY_ENTRIES_VALID;
|
||||
}
|
||||
|
||||
if (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID ||
|
||||
gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID)
|
||||
|
@ -394,21 +483,25 @@ grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt)
|
|||
{
|
||||
grub_uint64_t backup_header, backup_entries;
|
||||
|
||||
grub_dprintf ("gpt", "repairing GPT for %s\n", disk->name);
|
||||
|
||||
if (disk->log_sector_size != gpt->log_sector_size)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"GPT sector size must match disk sector size");
|
||||
|
||||
if (!(gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID ||
|
||||
gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID))
|
||||
gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID))
|
||||
return grub_error (GRUB_ERR_BUG, "No valid GPT entries");
|
||||
|
||||
if (gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID)
|
||||
{
|
||||
grub_dprintf ("gpt", "primary GPT header is valid\n");
|
||||
backup_header = grub_le_to_cpu64 (gpt->primary.alternate_lba);
|
||||
grub_memcpy (&gpt->backup, &gpt->primary, sizeof (gpt->backup));
|
||||
}
|
||||
else if (gpt->status & GRUB_GPT_BACKUP_HEADER_VALID)
|
||||
{
|
||||
grub_dprintf ("gpt", "backup GPT header is valid\n");
|
||||
backup_header = grub_le_to_cpu64 (gpt->backup.header_lba);
|
||||
grub_memcpy (&gpt->primary, &gpt->backup, sizeof (gpt->primary));
|
||||
}
|
||||
|
@ -418,9 +511,13 @@ grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt)
|
|||
/* Relocate backup to end if disk whenever possible. */
|
||||
if (grub_gpt_disk_size_valid(disk))
|
||||
backup_header = disk->total_sectors - 1;
|
||||
grub_dprintf ("gpt", "backup GPT header will be located at 0x%llx\n",
|
||||
(unsigned long long) backup_header);
|
||||
|
||||
backup_entries = backup_header -
|
||||
grub_gpt_size_to_sectors (gpt, gpt->entries_size);
|
||||
grub_dprintf ("gpt", "backup GPT entries will be located at 0x%llx\n",
|
||||
(unsigned long long) backup_entries);
|
||||
|
||||
/* Update/fixup header and partition table locations. */
|
||||
gpt->primary.header_lba = grub_cpu_to_le64_compile_time (1);
|
||||
|
@ -435,13 +532,15 @@ grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt)
|
|||
return grub_errno;
|
||||
|
||||
/* Sanity check. */
|
||||
if (grub_gpt_header_check (&gpt->primary, gpt->log_sector_size))
|
||||
if (grub_gpt_check_primary (gpt))
|
||||
return grub_error (GRUB_ERR_BUG, "Generated invalid GPT primary header");
|
||||
|
||||
if (grub_gpt_header_check (&gpt->backup, gpt->log_sector_size))
|
||||
if (grub_gpt_check_backup (gpt))
|
||||
return grub_error (GRUB_ERR_BUG, "Generated invalid GPT backup header");
|
||||
|
||||
gpt->status |= GRUB_GPT_BOTH_VALID;
|
||||
grub_dprintf ("gpt", "repairing GPT for %s successful\n", disk->name);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
@ -497,9 +596,11 @@ grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt)
|
|||
if (!(gpt->status & GRUB_GPT_BOTH_VALID))
|
||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "Invalid GPT data");
|
||||
|
||||
grub_dprintf ("gpt", "writing primary GPT to %s\n", disk->name);
|
||||
if (grub_gpt_write_table (disk, gpt, &gpt->primary))
|
||||
return grub_errno;
|
||||
|
||||
grub_dprintf ("gpt", "writing backup GPT to %s\n", disk->name);
|
||||
if (grub_gpt_write_table (disk, gpt, &gpt->backup))
|
||||
return grub_errno;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue