SD Card
Contents
Download SD Card Image
Load microSD Card on Windows Host
Because Windows does not support reading/writing of Linux filesystems (ext2, etc.), the partitioning and formatting of the microSD card must be done with disk images. The disk image contains all of the information required to define the partition scheme, disk format and file system contents. This includes the boot partition components as well as the root filesystem partition and it's contents.
Format microSD Card
Before load a microSD card with an SD card image, the card must first be formatted. A tool for formatting the microSD card is produced by the SD Association and can be found at SDCard.org. After downloading and installing the SDFormatter software, connect the microSD card to the host machine and run the SDFormatter.
Disk Imager
The Win32 Disk Imager utility is used to write the disk image to the freshly formatted microSD card. Download the utility from SourceForge and install it on the Windows host.
After opening the Win32 Disk Imager, verify the drive letter matches that of the newly formatted card. By selecting the folder button next to the image file path, you will be able to navigate to and select the extracted system image file. After selecting the system image, select 'Write' to begin writing the image to the microSD card.
Linux SD Card Build Script
$ export SD_CARD_IMG=snickerdoodle_xenial_kinetic.img $ export SD_CARD_DEV=/dev/sdb $ ./sd_create.sh
#!/bin/bash # Check if the card device variable has been set if [ -z "${SD_CARD_DEV}" ]; then echo "[ERROR]: SD_CARD_DEV is unset" exit elif [ -z "${SD_CARD_IMG}" ]; then echo "[ERROR]: SD_CARD_IMG is unset" exit fi # Check if the card device has mounted partitions if [ $(mount | grep -c "${SD_CARD_DEV}[0-9]*") != "0" ]; then echo "SD card has mounted partitions -> unmounting" mount | grep -o "${SD_CARD_DEV}[0-9]*" | xargs umount -n if [ $? -ne 0 ]; then echo "[ERROR]: Failed to unmount existing partitions" exit fi sleep 3 fi # Create a new partition table for the card parted ${SD_CARD_DEV} --script -- mklabel msdos parted ${SD_CARD_DEV} --script -- mkpart primary fat32 1MiB 128MiB parted ${SD_CARD_DEV} --script -- mkpart primary ext4 128MiB 100% sleep 3 bootp=${SD_CARD_DEV}1 rootfsp=${SD_CARD_DEV}2 mkfs.vfat -n BOOT ${bootp} mke2fs -t ext4 -L ROOTFS -b 4096 ${rootfsp} # Can we mount the new partitions is a repeatable way? bootpmnt=$(mktemp -d sdbootXXX) rootfspmnt=$(mktemp -d sdrootfsXXX) mount ${bootp} ${bootpmnt} mount ${rootfsp} ${rootfspmnt} # Mount the image for dumping loopdevice=$(losetup -f --show ${SD_CARD_IMG}) if [ $? -ne 0 ]; then echo "[ERROR]: failed to setup loop device for ${SD_CARD_IMG}" exit fi device=$(kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/\1/g' | head -1) sleep 5 # Set up the mapped boot and rootfs partitions of the image device="/dev/mapper/${device}" imgbootp=${device}p1 imgrootfsp=${device}p2 # Make mount point directories imgbootpmnt=$(mktemp -d sdbootXXX) imgrootfspmnt=$(mktemp -d sdrootfsXXX) mount ${imgbootp} ${imgbootpmnt} mount ${imgrootfsp} ${imgrootfspmnt} # Rsync contents of the boot and rootfs partitions to the SD card rsync -Hav --progress ${imgbootpmnt}/ ${bootpmnt} rsync -Hav --progress ${imgrootfspmnt}/ ${rootfspmnt} sync umount ${imgbootp} umount ${imgrootfsp} rm -r ${imgbootpmnt} rm -r ${imgrootfspmnt} echo "--- Removing loop device" kpartx -dv ${loopdevice} losetup -d ${loopdevice} umount ${bootp} umount ${rootfsp} rm -r ${bootpmnt} rm -r ${rootfspmnt} eject ${SD_CARD_DEV}
Manual SD Card Disk Layout
Partitioning the SD Card (fdisk)
Before partitioning the SD card, any partitions that have been mounted on the system must be unmounted. This can be done using the umount command.
umount /dev/sdb1
Once the SD card has been located, we can partition it for the Linux system (BOOT partition) and root filesystem (ROOTFS partition) using fdisk. fdisk must be run with root permissions (sudo) using the disk parent as the argument (do not use the parition number in the argument).
sudo fdisk /dev/sdb
From within the fdisk interface, we can view the parition table at any time using the "p" command. In this example, an 8GB SD card with a single FAT32 partition is being used and will be re-partitioned for snickerdoodle.
Command (m for help): p Disk /dev/sdb: 7969 MB, 7969177600 bytes 255 heads, 63 sectors/track, 968 cylinders, total 15564800 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Device Boot Start End Blocks Id System /dev/sdb1 8192 15564799 7778304 b W95 FAT32
BOOT Partition
First, a partition must be allocated for the Linux system binaries and files. This includes BOOT.bin (FSBL, bitstream, U-Boot), uEnv.txt, devicetree.dtb, and the Linux kernel uImage. The partition size for these files is recommended to be 128MB in size which translates to an additional 262144, 512 byte sectors.
Command (m for help): d Selected partition 1 Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1): 1 First sector (2048-15564799, default 2048): <RETURN> Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-15564799, default 15564799): +262144
The default partition type for fdisk is Linux (type ID 83). The BOOT partition needs to be formatted as FAT32 (type ID "C"). Do do this, the "t" command is used:
Command (m for help): t Partition number (1-4): 1 Hex code (type L to list codes): c Changed system type of partition 1 to c (W95 FAT32 (LBA))
ROOTFS Partition
Second, a partition for the root filesystem must be created. This partition will be formatted as a Linux type using type ID 83. This is the default partition type.
Command (m for help): n Partition type: p primary (1 primary, 0 extended, 3 free) e extended Select (default p): p Partition number (1-4, default 2): <RETURN> Using default value 2 First sector (264193-15564799, default 264193): <RETURN> Using default value 264193 Last sector, +sectors or +size{K,M,G} (264193-15564799, default 15564799): <RETURN> Using default value 15564799
Before writing the parition table, you should verify the partition layout by printing it with the ’p’ command. In this example, an 8GB SD card has been partitioned with a 128MB FAT32 BOOT partition and the rest allocated for a Linux ROOTFS partition.
Command (m for help): p Disk /dev/sdb: 7969 MB, 7969177600 bytes 255 heads, 63 sectors/track, 968 cylinders, total 15564800 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Device Boot Start End Blocks Id System /dev/sdb1 2048 264192 131072+ c W95 FAT32 (LBA) /dev/sdb2 264193 15564799 7650303+ 83 Linux
Writing Parition Table
Once the partition table has been verified, the ’w’ command can be used to write the table to the disk:
Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
Formatting Partitions
With a partitioned SD card, the partitions need to be formatted with the necessary filesystem type. For the BOOT partition, the filesystem type is VFAT. Formatting the BOOT partition can be done using the mkfs.vfat3. To format a FAT32 filesystem on /dev/sdb1 with a ’BOOT’ disk label, the following command can be used:
mkfs.vfat -n BOOT /dev/sdb1
The format for the ROOTFS partition can be done with mke2fs which will format a Linux partition with an ext2/ext3/ext4 filesystem. To format an ext4 filesystem on /dev/sdb2 with a block size of 1k (1024) and a ’ROOTFS’ disk label, the following command can be used:
If the formatting is successful, the following output with be written to the console (writing superblocks and filesystem accounting information can take some time depending on the size and speed of the SD card):
$ mke2fs -b 4096 -t ext4 -L ROOTFS /dev/sdb2
mke2fs 1.42.9 (4-Feb-2014) Filesystem label=ROOTFS OS type: Linux Block size=4096 (log=0) Fragment size=4096 (log=0) Stride=0 blocks, Stripe width=0 blocks 478208 inodes, 7650300 blocks 382515 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=74973184 934 block groups 8192 blocks per group, 8192 fragments per group 512 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553, 1024001, 1990657, 2809857, 5120001, 5971969 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done
After the partitions have been properly formatted, the SD card must be ejected and re-connected before moving the Linux boot components and root filesystem contents to the disk.
eject /dev/sdb
Loading SD Card Images
Boot Partition Components
- boot.bin (FSBL/U-Boot)
- boot.script.img (system boot script)
- devicetree.dtb (device tree blob)
- uEnv.txt (U-Boot supplementary environment definition)
- uImage (Linux kernel image)