RPi2 image bad partition alignment?

I have a Raspberry Pi 2 running the FreeBSD-11.0-RELEASE-arm-armv6-RPI2 image on a 16GB microSD card.

I've just noticed that the partitions in this image may not be aligned for optimal performance on flash storage:

# gpart show
=>      63  30703553  mmcsd0  MBR  (15G)
        63    102375       1  !12  [active]  (50M)
    102438  30601178       2  freebsd  (15G)

=>       0  30601178  mmcsd0s2  BSD  (15G)
         0        90            - free -  (45K)
        90  30601088         1  freebsd-ufs  (15G)

The MS-DOS firmware slice starts at sector 63, which I expect is done to conform to legacy CHS partitioning standards, but this partition is mostly only read from, so not a problem.

The FreeBSD slice then starts at sector 102438, and the UFS root partition inside that starts a further 90 sectors on, for a total offset of 102528 (50.0625 MiB), which obviously doesn't align with the typical SD card flash erase block size of 4MiB.

Could this be hurting I/O performance and causing unnecessary additional writes and wear on the SD card?
It probably does hurt performance if the SD card happens to use a large internal block size. That's a good reason to use manual partitioning and GPT partitions if possible. The FreeBSD installer still doesn't get this right even if SSDs/SD cards have been around quite a time now and you'd really want to default to at least 1MB alignment on any disk.

Edit: It's possible that the alignments you got on that disk are a result of CHS alignment requirements that GEOM still follows on MBR disks regardless of the platform.
  • Thanks
Reactions: jem
Thanks kpa. I've also been puzzled by GEOMs insistence on adhering to outdated CHS alignment when using the MBR scheme, even though Logical Block Addressing superseded it a long time ago.

Unfortunately, manual partitioning isn't an option with this premade image. I will try to create a new image with the correct partition offsets on a different system and ufsdump/restore the contents from the original image.

Ubuntu gets it right with their RPi2 image:

Model: SD SL08G (sd/mmc)
Disk /dev/mmcblk0: 15523840s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start    End        Size       Type     File system  Flags
 1      8192s    270335s    262144s    primary  fat16        boot, lba
 2      270336s  15523806s  15253471s  primary  ext4

Partition 1 is aligned to 4MiB and partition 2 is aligned to 33 x 4MiB.
I believe the CHS alignment requirement is still part of the PC platform specification, that's why it's still around. There are machines still in real use that don't support LBA but yet are able to run the latest FreeBSD and other OSes as well.
I successfully created a new image with more flash-suitable partition alignments, wrote it to an SD card, and it boots fine. If anyone is interested, my procedure was as follows:

# mdconfig -f FreeBSD-11.0-RELEASE-arm-armv6-RPI2.img

# dd if=/dev/zero of=new.img bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes transferred in 8.138808 secs (131928633 bytes/sec)

# mdconfig -f new.img

# gpart create -s mbr md1
md1 created

# gpart add -t '!12' -b 4M -s 60M md1
md1s1 added

# gpart set -a active -i 1 md1
active set on md1s1

# gpart add -t freebsd md1
md1s2 added

# gpart create -s bsd md1s2                                                                                                            
md1s2 created

# gpart add -t freebsd-ufs md1s2
md1s2a added

# gpart show
=>     63  2097089  md1  MBR  (1.0G)
       63     8129       - free -  (4.0M)
     8192   122880    1  !12  [active]  (60M)
   131072  1966080    2  freebsd  (960M)

=>      0  1966080  md1s2  BSD  (960M)
        0  1966080      1  freebsd-ufs  (960M)

# newfs_msdos -L MSDOSBOOT /dev/md1s1
newfs_msdos: trim 30 sectors to adjust to a multiple of 63
/dev/md1s1: 122696 sectors in 15337 FAT16 clusters (4096 bytes/cluster)
BytesPerSec=512 SecPerClust=8 ResSectors=1 FATs=2 RootDirEnts=512 Media=0xf0 FATsecs=60 SecPerTrack=63 Heads=64 HiddenSecs=0 HugeSectors=122850

# newfs -L rootfs /dev/md1s2a
/dev/md1s2a: 960.0MB (1966080 sectors) block size 32768, fragment size 4096
        using 4 cylinder groups of 240.03MB, 7681 blks, 30848 inodes.
super-block backups (for fsck_ffs -b #) at:
 192, 491776, 983360, 1474944

# mkdir old new

# mount_msdosfs /dev/md0s1 old/
# mount_msdosfs /dev/md1s1 new/
# cp old/* new/
# umount old/
# umount new/

# mount /dev/md0s2a old/
# mount /dev/md1s2a new/
# rsync -aHAXS old/ new/
# umount old/
# umount new/

# mdconfig -du 0
# mdconfig -du 1