Wednesday, 23 May 2012

Formatting FAT32 Volumes Larger Than 32GB & SD Card Alignment

For a long time, flash memory for mobile phones and portable audio players seems to have been stuck at around 32GB.  Many devices report their maximum supported card size as 32GB, but this didn't stop me buying a Sandisk 64GB Micro SD for my Galaxy S2 and playing around with it.

Samsung claim the Galaxy S2 supports a maximum of 32GB via it's Micro SD card slot, but as the owner of AndroidNZ found out, this wasn't strictly true.  He had tried the card in the device, and once I saw that it was working, I decided to take a punt and buy one for myself.

64GB Micro SD card working flawlessly in my Galaxy S2, which claims to only support up to 32GB.

Initially you may run into some difficulty.  When I inserted the card into the phone, the phone said that the card is damaged or unreadable.  It appeared that my card shipped unformatted, which meant it had no filesystem.  The first challenge was to format the card in a filesystem the Galaxy S2 could read.  I tried the Linux filesystems first such as EXT2, EXT3 and EXT4, as the default filesystem FAT32 has a 4GB maximum filesize limitation, and I intended to use my phone as a portable HDD too (very useful for transporting or downloading Linux ISOs if you are caught out with a dead computer).

I found that with the Galaxy S2, EXT2, EXT3 and EXT4 were not supported, which was quite annoying and odd since that the internal memory of the Galaxy S2 uses EXT4.  So why can't it mount EXT4 SD cards?  I had also tried mounting external NTFS HDDs before with no luck, so I knew not to bother wasting my time with that.  I also tried exFAT but still no joy.  Hopefully since the Galaxy S3 supports exFAT the code will be retroported to the S2 (everything crossed).

The card even works on my 2008 Nokia N96!

So unfortunately that left me with FAT32.  For whatever reason, my S2 refused to format the card (but since I formatted the card, my phone will do it no problem now) which meant I had to do it on my computer, and immediately I ran into an old problem.  You see Microsoft impose a 32GB limit on partiton sizes for FAT32 in recent operating systems (XP onward I believe), despite the filesystem supporting partitions up to 2TB on paper.  My only guess is that Microsoft wanted to push NTFS as the dominant filesystem since it's a lot more robust.  I had tried formatting by right clicking the drive in "Computer", through launching diskmgmt.msc via the command prompt, and then even resorting to the CLI format utility, diskpart.  None of which would allow me to create a FAT32 partition of 64GB.

Fortunately, third party partitioning software will allow you to create FAT32 partitions in excess of 32GB, so it was time to find an alternative.

For simple partitioning, I found Easeus Partition Master which has a free version with all the functionality we need (for my final formatting, I eventually decided to use some tools supplied in Linux, but I'll come to that later as it concerns aligning the SD card too).  If you are a little more experienced with computers, or have used Linux in the past and are familiar with the filesystem structure, you could also use a GParted Live CD which boots into a basic version of Debian with the GParted program which is simple to use.

Additionally you could possibly use a Windows 98/ME boot disc or Windows setup disk to get into DOS and run fdisk.  Unfortunately even though I was able to find the boot disk files online, they wouldn't run within 64-bit Windows - they might possibly work within DOSbox though.

Partitioning With Easeus Partition Master
For the purpose of this tutorial I will be using an old 32GB Micro SD card as I have already formatted my 64GB and loaded it up with music and stuff.  The process is identical, but the reported volume sizes will be different.

Upon launching Easeus, you will be shown a screen like the one below.

Note the disk sizes, so that you don't accidentally delete partitions on your HDD!

Easeus is really easy to use, but here's a quick run down for those who might not have partitoned a disk before.

1) Upon opening Easeus, check to see if your SD card has any existing partitions.  The one in the screenshot is blank.  If you have existing partitions, select it by clicking on it, then right click and choose Delete Partition, then click Apply in the top left hand corner.

2) Right click the Unallocated space of the SD card you wish to format and click Create Partition.  Change the default settings to match the screenshot, so we are creating a Primary partition in FAT32.  You can adjust the space used if for some reason you want to create multiple partitions, but in general you just want to select the maximum amount.  The drive letter is not important, so leave that as the default.  Once you are done, press Ok to go back to the main screen.

The first part of creating a FAT32 partition
That's all there is to it, but if you would like to experiment with different cluster sizes which can improve write speeds, perform the final step below.

3) To change the cluster size, right click the partition and select Format Partition and choose a cluster size from the drop down menu.  Press Ok to go back to the main screen and press apply to write the changes.  In general, the larger the disk size, the larger the cluster size you would use.  Using larger clusters can help improve transfer speeds, but at the cost of disk space efficiency.  What this means is that files occupy space on the disk to the nearest cluster size.  So a 12KB file on a disk with a cluster size of 16KB, will use 16KB on that disk, or if the cluster size was 64KB, then that same 12KB file will occupy 64KB.

Aligning the SD Card
If you are comfortable with Linux and command line tools, then we can improve the speed of the SD card by aligning it.  The theory behind this is that SD cards erase/write 128KB blocks which means even if only 10KB in that block changes, the whole thing needs to be re-writtent.  Most formatting tools don't seem to be aware or care about how SD cards work and just format the FAT32 filesystem in the usual way, however better performance can be achieved if the File Allocation Tables end at the border of a block, with the data starting at a new block, rather than some of the FAT using part of a block and the data starting in that same part block.  This makes it easier for the SD card to write full blocks more often than it would if the partition was unaligned.

I found that with my SD card unaligned, I would get write speeds averaging around 6.5MB/s, but once aligned it would manage a consistant 9MB/s, and higher with large files.

Unfortunately I do not know of any SD card alignment tools for Windows when it comes to FAT32, so we will be using a Linux Live CD for this, but if your device supports exFAT, then I've found the official SD card formatter to give really good speeds.

We first need a Linux environment, you maybe already run some linux distro, but if not we can download a Live CD which runs the OS from optical media without installing anything.  I use Opensuse

Here is a link to the original thread.  The guide I will post will pretty much be a simplified version of this based on my own experience as I found the guide a little bit cryptic at first.

Partitioning The Card
1) First, insert the SD card so that Linux detects it and allow it to mount.  If it doesn't mount automatically, you can open the file browser and browse to the card as this will cause it to be mounted.  You may need to have a filesystem on the card beforehand, so you can just format it to NTFS or something in Windows as a temporary measure.

2) Open a terminal window from the progam menu and type:
df -h
df is the disk free command, which shows you the available space on your mounted drives, and the -h switch for "human" readable information, such as MB and GB rather than just bytes.
There are a few pieces of information we need here.  Locate your SD card by its capacity in the list, and make note of the Filesystem and Mounted on columns.

As you can see, my SD card is listed under filesystem as /dev/mmcblk0p1 and under mounted on as /media/15F4-1F1D

I should explain briefly about how Linux's filesystem works.  /dev/mmcblk0p1 is actually referring to a partition on the disk, and the disk itself is known as /dev/mmcblk0 - as you may have guessed, Linux simply suffixes p1, p2, p3 etc to the device name to denote partitions on a device.  /media/15F4-1F1D is the mount point and is the Linux equivalent to a drive letter, eg C:

3) Next we need to unmount the drive.  In the terminal window type (replacing the mount point with whatever your drive is mounted as when you typed df -h):
umount /media/15F4-1F1D

If you don't want to type the whole thing, you can start it off and press Tab to complete it automatically.  If the unmount was successful, you are returned to the prompt.  You can check it was unmounted by typing in df -h again and confirming that it is not in the list.

4) Now we need to change the drive geometry in order to make the 128k easy.  Flash memory works differently from harddrives and do not have physical, sectors tracks or heads, but it still uses that information to organise data.  The aim is to find a combination of sectors, tracks and heads that is evenly divisible by 128KB (131,072 bytes).  The suggested geometry of 224 heads and 56 sectors does that (224 heads x 56 sectors x 512 bytes per sector / 131,072 bytes = 49) whereas the default value (255 heads x 63 sectors x 512 bytes per sector /131,072 bytes = 62.75) does not.
In the terminal window, type the following:
su (then press enter, this enables super user mode, or admin)
fdisk -H 224 -S 56 /dev/mmcblk0

fdisk is the partitioning program, -H sets the number of heads and -S sets the number of sectors.

To confirm this worked, press p to get a list of the partitions and device properties

4) While still in fdisk, we will create the FAT32 partition.  To do this, type the following at the prompt:
d (then press enter to delete any existing partitions - if you only have 1 it is deleted automatically, otherwise you are prompted to enter the number of the partition)
n (then press enter to create a new partition, then select primary partition and then enter through the other options).
x (to enter expert mode)
b (to change the beginning of the data, then select partition 1 and set the start to 1)
r (to return from expert mode)
t (to set the partition type, enter c when prompted for FAT32)
x (to enter expert mode again)
b (to set the beginning of the data to 256 for partition 1)
r (to return from expert mode)
w (to write the changes to disk

You may press q at any time to quit without saving changes.

5) Finally we need to create the aligned FAT32 partition.  We first need to find out how big the FAT tables are going to be, so we can manipulate the size of the tables to finish at the end of an erase block (the 128KB blocks we keep talking about).
At the terminal window, type:
mkfs.vfat -F 32 -s 32 -v /dev/mmcblk0p1
Then press enter to format.  Once done, you will see something like below, giving a read out of the disk.  The line we need is the FAT size which tells us how big a single FAT is (there are two on this disk).

6) We then need to calculate the size of the FAT in bytes, to see if it will end on a whole erase block or not.  What we do is:
FAT size x No. of FATs x 512 bytes per sector / 131,072 = No of erase blocks
In this instance we would have:
14,976 x 2 x 512 =  15,335,424 / 131,072 = 117
Now if at this point the number of erase blocks is uneven, we need to pad that out to fill the erase block.  Simply round up your last result to the nearest whole number and reverse the calculation.

No of erase blocks x 131,072
Which gives us:
118 x 131,072 = 15,466,496

Now we subtrack the original FAT size in bytes, from the erase block aligned FAT size in bytes, then divide by 512 to give us the number of sectors difference to be used as reserve sectors.  This is essentially expanding the amount of space allocated to the FAT in order for it to finish on a complete erase block, so the data starts on a new block.

15,335,424  - 15,466,496 / 512 = 256 reserve sectors

7) Now we know how many reserve sectors are needed to ensure alignment to the erase blocks, we can continue to format with the correct information.
At the terminal window, type
mkfs.vfat -F 32 -s 32 -R 256 -v /dev/mmcblk0p1

The switches used are:
-F 32 (for FAT32)
-s 32 (cluster size expressed as sectors, so 32 x 512 bytes = 16KB clusters)
-R 256 (number of reserved sectors)
-v (device to be formatted)

Once that has completed, you can mount the drive to transfer items to it, or simply remove it and go back to Windows, or use it in your device.