Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

NOOBs fails to resize partitions created with rpi-imager on very large (>64, <=400GB) SDXC cards. #589

Open
terrysimons opened this issue Jun 1, 2020 · 11 comments

Comments

@terrysimons
Copy link

terrysimons commented Jun 1, 2020

I found a bug in rpi-imager that affects very large SD cards.

In my particular setup, the smallest card that I have which works with rpi-imager v1.2 and NOOBS 3.4 is a 64GB PATRIOT U(1) Class 10 card.

I have 3 cards larger than 64GB, which ALL fail when using rpi-imager to erase & load NOOBS during the partition resizing phase after booting into the NOOBS installer.

I have narrowed this down to the 4MiB empty space that rpi-imager puts at the front of the SD card. For some reason, on very large SD cards, this causes a failure.

I have reproduced this with gparted and manual NOOBS copy to the SD card. I can confirm that 4MiB of empty space at the beginning of the SD card fails, however, if I format these very large cards with 1MiB of empty space (which is the minimum that gparted allows) then NOOBS can resize them just fine.

I'm not exactly sure why this is happening, since the error message NOOBS give doesn't exactly state a reason other than:

"Error resizing existing FAT partition
Error: Unable to satisfy all constraints on the partition."

However, I can confirm that the following cards all fail with the rpi-imager method, but they work fine if I format with gparted and only use 1MiB of empty space at the front of the card:

SanDisk Ultra 400GB U(1) A1

These card, however, still fail UNLESS I also shrink the partition to 375623 MiB, which is the size of the 400GB card (and why I chose such an arbitrary value):

PNY PRO Elite 512GB U(3) A2
SanDisk Extreme 1TB U(3) A2

I have more details about the steps I went through to figure this out over in the forums at:

https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=275772&p=1670957

It seems like large cards should not have the 4MiB of empty space at the start of the disk.

I can also confirm that on the 64GB card which works with 4MiB of empty space, ALSO works with 1MiB of empty space at the beginning of the disk.

Perhaps cards >= 64GB in size should be formatted to have 1MiB of empty space and no more than a 375623 MiB large fat32 partition?

I'm running some additional tests to determine where the maximum partition size for 512GB and 1TB cards is, and I'll report back.

@terrysimons
Copy link
Author

terrysimons commented Jun 1, 2020

It looks like 1MiB of unpartitioned space, and a 387422MiB FAT32 partition is the limit.

1MiB unformatted space + 387422MiB FAT32 partition succeeds, but 1MiB unformatted space + 387423MiB FAT32 partition fails on BOTH my 512GB and 1TB SD cards.

@terrysimons
Copy link
Author

terrysimons commented Jun 1, 2020

I was using the default "Align to MiB" option in gparted, so I wonder if looking at the cylinder boundaries would make more sense. 387422MiB isn't base-2 aligned, so I'm not sure why that would be an obvious failure location.

@terrysimons
Copy link
Author

It does appear that a smaller partition with 4MiB of unpartitioned space will also work on these cards.

Initially I wasn't having any luck but I believe it was due to the FAT32 partition being too large, though I'm a bit perplexed why 4 MiB of unformatted space on the 400GB card also failed, since that card in particular works with 1MiB of unformatted space at the beginning of the card.

The following combinations all worked for me for each of the 3 cards that were having difficulty with NOOBS and rpi-imager:

4MiB of unpartitioned space.
8000MiB of FAT32 space.

I think a reasonable change to rpi-imager would be to create a smaller FAT32 partition up to 64GiB or less for the initial partition and then NOOBS shouldn't have any problem formatting even very large cards. If there's interest in narrowing this down more, I'm happy to do so. I'm still perplexed as to why the 400GB card fails with 4MiB of unpartioned space, while it succeeds with 1MiB of partitioned space all else being equal. I suppose I can try shrinking the fat32 partition by 3MiB and see if that suceeds.

@terrysimons
Copy link
Author

And just to confirm, the 400GB SanDisk Ultra U(1) A1 card does fail if I use a 4MiB unpartitioned space at the beginning, even if I shrink the FAT32 partition by 3MiB on the back side... but it works with a 1MiB unpartitioned space with the rest of the disk FAT32 so that's still strange.

However, as I mentioned, the large cards all work with 4MiB unpartitioned + 8000MiB FAT32.

@procount
Copy link
Contributor

procount commented Jun 1, 2020

Let me start by saying that I don't know why this fails, but I I can provide my insight and ideas why it might be happening (mostly suppositions 😉 )

I'm not exactly sure why this is happening, since the error message NOOBS give doesn't exactly state a reason other than:

"Error resizing existing FAT partition
Error: Unable to satisfy all constraints on the partition."

NOOBS defers the actual partitioning to standard tools such as parted (which underlies gparted) and sfdisk. I believe this error message is from parted.

These days, most storage devices use sequential block numbering like LBA to access the data. But the formatting tools still have to cope with the old physical hard disk layouts that use Cylinder, Head and Sector (CHS) numbers. When a drive is formatted, the tools try to satisfy many of the constraints that this technology used, plus other arcane requirements that aim to achieve backwards compatibility.

When NOOBS was developed, SD card sizes above 64GB were unheard of, and even 32GB and 64GB cards were prohibitively expensive for most people. So I do wonder if the formatting tools managed to keep up with this technology, although it should all work, because the designers go to great length to ensure compatibility.

IIRC, the 4MB gap at the beginning of the disk is to allow for a RISCOS binary blob that need to be fixed at a certain disk location in order for RISCOS to run. RISCOS does not understand partitions and uses a strange format (UDF/ADS or something) so this blob creates a sort of hybrid disk layout that RISCOS can understand. So I think reducing this gap to 1MB may prevent RISCOS from loading.

NOOBS was designed to allow standard Window Users to easily create an initial NOOBS SD card using standard Window tools such as format and zip, since other tools to directly write a disk image or format an SDcard as ext4, were not appropriate at the time.

Since the RPi must boot from a FAT partition, the initial advice was to simply format the whole SD card as FAT32, then copy the NOOBS files. NOOBS itself would deal with the re-formatting of the SD card to ext4 as required. For small SD cards, this was not a problem. However, for today's large SD cards there are several issues:

  1. Cards >32GB are normally formatted as exFAT by the standard tools, so 3rd party tools now have to be used to enforce the FAT32 format. (I assume they do this by using larger cluster sizes of 8 sectors/cluster or more - see https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#Size_limits)
  2. Formatting cards >32GB as FAT32 can take a while (depending on method) and most of this is wasted time since NOOBS' first task is to shrink the partition as small as possible again.
  3. One idea is that when shrinking FAT32 partitions, the tools may not be able to change the cluster size - it maintains the cluster size used at creation. This will define a minimum partition size. If NOOBS requests a smaller partition size than this, parted may fail. (purely speculation). Whereas it may be better to reformat the drive as FAT32 with smaller cluster sizes or even use FAT12/16. (NOOBS tries to do this if the boot partition is small).
  4. Possibly the alignment of large sectored clusters with the 4MiB offset is causing other constraints to fail.

Now that the disk imaging tools have been improved (Etcher and Raspberry Pi Imager), the solution I used in PINN was to create a disk image as an alternative. Since this already contains a FAT32 partition of just the right size, it avoids the problem of creating a FAT32 partition >32GB, hence avoiding the use of other tools, and avoids the issue of resizing a massive partition down to something very small.

Another alternative is to ensure that the first partition on the disk is created to be <64GB (or just big enough for NOOBS+ any other OS installation files) before formatting it as FAT32, rather than it filling the whole of the SD card.

The use of a 1MiB gap instead of 4MiB seems interesting, although I think it will preclude installing RISCOS. There is a new version of RISCOS Direct for the RPi being developed. If this can avoid the need for the "binary blob" then it may be a way forward, but I haven't looked at it in detail.

@lurch
Copy link
Collaborator

lurch commented Jun 1, 2020

NOOBS defers the actual partitioning to standard tools such as parted (which underlies gparted) and sfdisk. I believe this error message is from parted.

Correct. Even in the days before massive SD cards, parted would sometimes give weird errors on particular-sized SD cards - see e.g. https://github.com/raspberrypi/noobs/search?q=constraints&type=Issues
Unfortunately newer versions of parted (which might deal better with partitioning huge SD cards?) don't have the resizing options that NOOBS relies on #284 (comment)

@maxnet
Copy link
Collaborator

maxnet commented Jun 1, 2020

What OS are you running rpi-imager under, and have you tried a different one?

rpi-imager outsources formatting FAT32 to the operating system under Mac OS X and Linux and to a third-party program (fat32format.exe) under Windows (because Windows format.exe only wants to format larger cards as exfat).
You are focusing on the start position of the partition, but there may well be differences in the FAT32 file system structures itself as well. Which may make the issue harder to reproduce.

@lurch lurch changed the title NOOBs fails to resize partitions created with rpi-imager on very large (>64, <=400GB) XDHC cards. NOOBs fails to resize partitions created with rpi-imager on very large (>64, <=400GB) SDXC cards. Jun 1, 2020
@terrysimons
Copy link
Author

I'm running rpi-imager on Ubuntu 20.04, and no I haven't tried a different one.

As I mentioned in my last update, if I create an 8GiB partition, the 4MiB unpartitioned space at the beginning is just fine - it's when the partitions are "too big" for some definition of "too big" that things start to fail.

For maximum compatibility, why not do that instead of formatting the entire disk? The FAT32 partition looks like it gets resized and moved to the front of the disk anyway, so it seems like a perfectly reasonable solution to bound your FAT32 partition to some smaller size when disks are very large.

@terrysimons
Copy link
Author

@maxnet If you read the forum post where I outlined my initial investigation, I dumped the VFAT structures with minfo and they weren't different, really.

@lurch
Copy link
Collaborator

lurch commented Jun 2, 2020

As I mentioned in my last update, if I create an 8GiB partition, the 4MiB unpartitioned space at the beginning is just fine...
For maximum compatibility, why not do that instead of formatting the entire disk?

AFAIK the formatting option in RPi Imager is intended to restore an SD card to being used as a removable drive (e.g. if somebody wants to wipe Raspberry Pi OS and use the SD card with their Windows laptop), and isn't specifically targeting NOOBS installations? 🤷

@maxnet
Copy link
Collaborator

maxnet commented Jun 2, 2020

For maximum compatibility, why not do that instead of formatting the entire disk?

Because it is a lot of work to do that for every operating system.

We may be able to specify partition offsets under Linux.
But on say Mac OS X we currently just call "diskutil eraseDisk FAT32 SDCARD MBRFormat" to do both the partitioning and formatting.
What offset the partition ends up at is up to the OS in this case.

The FAT32 partition looks like it gets resized and moved to the front of the disk anyway

NOOBS only moves the front of the FAT partition if it does not start at a multiple of 1 MiB.
So should not be moving the front if it is already at 4 MiB.

==

AFAIK the formatting option in RPi Imager is intended to restore an SD card to being used as a
removable drive (e.g. if somebody wants to wipe Raspberry Pi OS and use the SD card with their
Windows laptop), and isn't specifically targeting NOOBS installations?

The option that if you feed it a .zip file with multiple files in it, it will do both a FAT32 format and extract was added for the Pi 4 EEPROM recovery stuff.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants