Skip to content

Instantly share code, notes, and snippets.

@joshenders
Last active July 25, 2024 21:54
Show Gist options
  • Save joshenders/4376942 to your computer and use it in GitHub Desktop.
Save joshenders/4376942 to your computer and use it in GitHub Desktop.
How to format a USB drive for storing GameCube games

Why do we change the cluster size when formatting USB drives for storing GameCube games?

For loading GC Games with USBLoaderGX via DiosMios/Nintendont, format your usb drive's primary partition as FAT32 with 32KB clusters (also known as blocks). This increases performance by reducing the NUMBER of transactions required to perform a read/write operation at the expense of the (very negligible) LENGTH of time to complete a transaction; since it's reading more data per transaction.

I'm not certain, since I can't find a GameCube disk specification, but I don't think the 32KB cluster size is an attempt to imitate the on-disk storage format of retail GameCube discs; which may or may not be 32KB. Retail Wii discs however, actually DO use 32KB clusters. As far as I can tell, 32KB is simply the highest density of bytes per cluster that is supported by FAT32 and of course, by extension, Wii homebrew storage libraries.

If you're concerned about storage efficiency and you're using extracted images, you can find the optimal cluster size by calculating the mode of file sizes and using that number rounded up to the nearest multiple.

How to format a USB drive for storing GameCube games

mkdosfs -S 512 -s 64 -F 32 <partition>

Explanation:

Sectors contain bytes. -S 512 means that we're specifying 512 bytes per sector.

-S logical-sector-size
    Specify the number of bytes per logical sector.

Clusters contain sectors. -s 64 means that we're specifying 64 sectors per cluster.

-s sectors-per-cluster
    Specify the number of disk sectors per cluster.

If we represent this mathmatically:

512 bytes (per sector) * 64 sectors (per cluster) = 32KB clusters (32768 Bytes)

Or we can represent this visually:

sector[cluster[bytes], cluster[bytes], cluster[bytes], ... ]

This -F value represents how many bits are used in file allocation table entries. The entries themselves are used to address individual clusters on disk. As the number of bits increases for each individual FAT entry, the higher the value it's able to represent and the higher the quantity of file allocation table entries that it can address.

-F FAT-size
    Specifies  the  type  of file allocation tables used (12, 16 or 32 bit).

To restate this, the more bits you use for file allocation table entries, the larger the numbers they can store. The larger the numbers they can store, the more FAT entries you can have. The more FAT entries you can have, the more clusters they can point to. The more clusters you point to, the more bytes they can contain. The more bytes they can contain, the more data your disks can store using this system.

#...and this is about when I stared playing Super Smash Brothers instead of finishing this article

We specify 32bits for the allocation table entries so that they can store a maximum of 4,294,967,296 entries (aka FAT32). This gives us a approximate maximum disk size of 8TB... but 4 high order bits are reserved ... only 28 are used...

To further illustrate, a 32-bit value has 32 binary places(2^32). When all of the bits are set to 1, as in the binary representation of the number 4,294,967,296:

1111 1111 1111 1111 1111 1111 1111 1111

(spaces added for clarity)

On 32bit CPU architectures, this is the value of a unsigned integer.

unsigned int;

The datatype used in the FAT implementation is a signed integer which can store a maximum of 2,147,483,647 positive values represented in two's compliment form.

@Lewiscowles1986
Copy link

given a 1GB MMC this does complain that

sudo mkdosfs -S 512 -s 64 -F 32 /dev/mmcblk0
mkfs.fat 3.0.28 (2015-05-16)
WARNING: Not enough clusters for a 32 bit FAT!

@bmino
Copy link

bmino commented May 2, 2020

Thank you! This was exactly what I was fumbling through help files looking for

@joshenders
Copy link
Author

I don’t remember why I went into this much detail but glad you found it useful.

@xk2600
Copy link

xk2600 commented Apr 23, 2021

I can't speak to linux, but I can speak to on FreeBSD, the commands I use to create disks readable on WII for both GC and WII images are as follows:

pavewii.sh
#/bin/sh
if [ $# -ne 1 ]; then print "usage: $0 [geom]"; exit -1 ; fi
DISK=$1
export DISK
if `/sbin/geom -p da0 2> /dev/null 1> /dev/null` ; then 
  # do nothing
else
  print "argument does not appear to be a geom: $DISK"
fi
echo WARNING: Destroying disk $DISK. CTRL-C to cancel! Any other key continues!
read BURNITDOWN

printf "\nClearing partition table on $DISK...\n"
/sbin/gpart destroy da0
printf "\nWiping the first 1G of disk in 1M chunks with random data...\n"
/bin/dd if=/dev/random of=/dev/da0 obs=1M count=1G
printf "\nCreating MBR partition table on $DISK...\n"
/sbin/gpart create -s mbr da0
/sbin/gpart add -t fat32lba /dev/da0
printf "\nWriting FAT32 filesystem (512 Byte sector * 64 sectors per cluster = 32768 Byte cluster size)...
/sbin/newfs_msdos -A -F32 -S 512 -c 64 /dev/da0s1
/bin/sync
printf "Wait for it! Syncing writes...."
sleep 30
printf "Wait for it! Syncing writes...."
/bin/sync
printf "DONE!\n\n"
printf "To mount: /bin/mkdir /mnt/wii; /sbin/mount_msdosfs /dev/da0s1 /mnt/wii"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment