1
0
Fork 0
forked from len0rd/rockbox

disk: If primary GPT header is missing, try secondary one

Basically the GPT is supposed to live at sector 1, but a backup copy is
stored on the final sector.

This gives us a little bit of extra flexibility on systems that might
require sector 1 for other things, but in any case it's a more robust
arrangement.

Change-Id: I8925ffc743629cf2eba51861042492e35b41664b
This commit is contained in:
Solomon Peachy 2025-04-30 19:17:10 -04:00
parent 6a8f1a7e84
commit 64de7aa8d2

View file

@ -165,10 +165,10 @@ bool disk_init(IF_MD_NONVOID(int drive))
if (!sector)
return false;
#if (CONFIG_STORAGE & STORAGE_ATA)
/* Query logical sector size */
struct storage_info *info = (struct storage_info*) sector;
storage_get_info(IF_MD_DRV(drive), info);
#if (CONFIG_STORAGE & STORAGE_ATA)
disk_writer_lock();
#ifdef MAX_VARIABLE_LOG_SECTOR
disk_log_sector_size[IF_MD_DRV(drive)] = info->sector_size;
@ -226,8 +226,6 @@ bool disk_init(IF_MD_NONVOID(int drive))
}
}
// XXX backup GPT header at final LBA of drive...
while (is_gpt) {
/* Re-start partition parsing using GPT */
uint64_t part_lba;
@ -235,13 +233,21 @@ bool disk_init(IF_MD_NONVOID(int drive))
uint32_t part_entry_size;
unsigned char* ptr = sector;
// XXX this doesn't take into account virtual sector size... ugh.
storage_read_sectors(IF_MD(drive,) 1, 1, sector);
part_lba = BYTES2INT64(ptr, 0);
if (part_lba != 0x5452415020494645ULL) {
/* Try backup GPT header at final LBA of drive */
// XXX this doesn't take into account virtual sector size... ugh.
storage_read_sectors(IF_MD(drive,) info->num_sectors-1, 1, sector);
part_lba = BYTES2INT64(ptr, 0);
if (part_lba != 0x5452415020494645ULL) {
DEBUGF("GPT: Invalid signature\n");
break;
}
}
part_entry_size = BYTES2INT32(ptr, 8);
if (part_entry_size != 0x00010000) {
DEBUGF("GPT: Invalid version\n");