From ad6cc2f099bd8877a335b47bc150e14067adabfe Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Mon, 17 Nov 2025 10:46:37 -0500 Subject: [PATCH] ipod6g: Prevent booting into OF if it does not support LBA48 and drive needs it Early 6th gen ipods (80GB and 160GB "fat") are limited to LBA28 which results in a hard upper limit of 128GiB on the storage size. The later 120GB model also shares this limitation. These are identified by HwVr of 0x00130000 and 0x00130100, respectively. The final revision of the iPod Classic series (160GB "thin") does not have this limitation, and can be identified by a HwVr of 0x00130200 or 0x00130300. This is strictly an issue with Apple's stock firmware, and not the hardware, and Rockbox will happily utilize the full capabiltiies of any installed storage device. Unfortunately, if you boot into the stock Apple firmware, said firmware will destructively trash the partition table and filesystem. Consequently, the Rockbox bootloader will now check if the installed drive requires LBA48, making sure the flashed firmware also supports LBA48. If not, we will disallow booting into the OF (including disk mode) altogether. This check can be overridden by holding down LEFT, at which point you get to keep all the pieces. Note: While Apple never released firmware without these limitaitons on the older models, there is a way to update to update these to the newer firmware. This requires altering the stored HwVr, so it is safe to use the HwVr as a proxy for the installe firmware capabilities. Change-Id: Icdd5754f2a3d38c6de67fc7565fabc7aa20f19b3 --- bootloader/ipod-s5l87xx.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/bootloader/ipod-s5l87xx.c b/bootloader/ipod-s5l87xx.c index 08baf0dd3a..827831fcca 100644 --- a/bootloader/ipod-s5l87xx.c +++ b/bootloader/ipod-s5l87xx.c @@ -64,6 +64,7 @@ #define ERR_RB 0 #define ERR_OF 1 #define ERR_STORAGE 2 +#define ERR_LBA28 3 /* Safety measure - maximum allowed firmware image size. The largest known current (October 2009) firmware is about 6.2MB so @@ -166,6 +167,10 @@ void fatal_error(int err) printf("Hold MENU+SELECT to reboot"); printf("and enter Rockbox firmware"); break; + case ERR_LBA28: + printf("Hold MENU+SELECT to reboot"); + printf("and LEFT if you are REALLY sure"); + break; } #if (CONFIG_STORAGE & STORAGE_ATA) @@ -883,11 +888,35 @@ void main(void) /* We wait until HDD spins up to check for hold button */ if (button_hold()) { - printf("Executing OF..."); + bool lba48 = false; + struct SysCfg syscfg; + const ssize_t result = syscfg_read(&syscfg); + if (result != -1) { + const size_t syscfg_num_entries = MIN(syscfg.header.num_entries, SYSCFG_MAX_ENTRIES); + for (size_t i = 0; i < syscfg_num_entries; i++) { + const struct SysCfgEntry* entry = &syscfg.entries[i]; + const uint32_t* data32 = (uint32_t *)entry->data; + if (entry->tag == SYSCFG_TAG_HWVR) { + lba48 = (data32[1] >= 0x130200); + break; + } + } + + int btn = button_read_device(); + + struct storage_info sinfo; + storage_get_info(0, &sinfo); + if (sinfo.num_sectors < (1 << 28) || lba48 || btn & BUTTON_LEFT) { + printf("Executing OF..."); #if (CONFIG_STORAGE & STORAGE_ATA) - ata_sleepnow(); + ata_sleepnow(); #endif - rc = kernel_launch_onb(); + rc = kernel_launch_onb(); + } else { + printf("OF does not support LBA48"); + fatal_error(ERR_LBA28); + } + } } }