While putting together an implementation of Android Fastboot on i.MX, I finally had to face the question of SD card sizes.
How big is a 4G SD card?
This should be an easy question, and the answer should br either 4 billion (4000 million for you Brits) or 4<<30 bytes, right?
Apparently not.
I just compared three 4GB SD cards from three manufacturers using fdisk -u -l
. Only one of them was over 4 billion bytes, and none of them made it to 4<<30.
ATP
Disk /dev/mmcblk0: 4126 MB, 4126146560 bytes
4 heads, 16 sectors/track, 125920 cylinders, total 8058880 sectors
Lexar
Disk /dev/mmcblk0: 4008 MB, 4008706048 bytes
4 heads, 16 sectors/track, 122336 cylinders, total 7829504 sectors
Unigen
Disk /dev/mmcblk0: 3951 MB, 3951034368 bytes
122 heads, 62 sectors/track, 1020 cylinders, total 7716864 sectors
Also note that the disk geometry is quite different for the Unigen card, which brings up another important question.
How many cylinders and heads does an SD card have?
It seems like a ridiculous question, akin to Christian theologians pondering how many angels can fit on the head of a pin, but it really is important.
The number of sectors per track is used by filesystem software as a unit of allocation (to accomodate ancient code), and a larger value of "sectors per track" will have a coarser granularity.
You may be able to ignore this when laying out your filesystem, but you'll end up with error messages about partitions that don't start or end on cylinder boundaries.
So where does this information come from? In other words, who gets to decide this mapping?
We can get another clue by re-writing the partition table on the Unigen card:
~$ sudo dd if=/dev/zero bs=1M count=1 of=/dev/mmcblk0
1+0 records in
1+0 records out
~$ sudo fdisk -u -l /dev/mmcblk0
Disk /dev/mmcblk0: 3951 MB, 3951034368 bytes
4 heads, 16 sectors/track, 120576 cylinders, total 7716864 sectors
So it seems that we can change the geometry by re-writing the partition table, which seems pretty odd. You would expect the geometry to be an input to partition-table parsing, but apparently not in the case of SD cards.
Apparently, there are multiple levels to this:
- The kernel defaults to 4 heads and 16 sectors per track and calculates a cylinder count based on the capacity of the disk.
- Util-linux uses this as a default, but will also provide defaults or try to optimize them for better performance.
- Busybox will also override the kernel's defaults based on either user-specified geometry or by looking at an existing partition table.
At this point in this post, I still have outstanding questions:
- How did my Unigen card originally decide that it had 62 sectors per track?
- Is there code in the kernel which will benefit from larger numbers?
- How do we define this layout for eMMC devices?
When we have answers to some of these, we'll update this post. In the meantime, we'll push on with the Fastboot implementation.