Using SD Card in Linux Print


This application note explains how to use SD Card with the Freescale Vybrid in Linux. All software tests documented below were performed on the Emcraft VF6-SOM System-On-Module (SOM), plugged into the TWR-VF6-SOM-BSB development baseboard.

The Vybrid SD Card device driver is linux/drivers/mmc/host/sdhci-esdhc-imx.c in the kernel tree. To enable the SD Card support in the kernel, you must enable the CONFIG_MMC_SDHCI_ESDHC_IMX build time option in the kernel configuration. To do so, start the kernel configuration GUI (make kmenuconfig from the project directory) and proceed to enable the following item: Device Drivers -> MMC/SD/SDIO card support. Then enter the MMC/SD/SDIO card support menu and enable the following options:

Then, return to the top level menu, enter the System Type -> Freescale MXC Implementation -> Vybrid UART configuration menu, and disable the Enable UART1 option (this is required, because UART1 and MMC functions are multiplexed on the same pins):

The most typical use of SD Card in embedded applications is a removable storage device (disk) that can be easily taken from the embedded target to a PC or notebook. In such contexts, SD Card installed to the embedded target is typically already formatted with an MS-DOS file system. The Linux kernel must be specially configured to allow mounting the MS-DOS file system. To perform the configuration, start the kernel configuration interface, proceed to File systems -> DOS/FAT/NT Filesystems and enable the following kernel options:

The two additional kernel configuration options that, depending on your application needs, may be needed to mount an MS-DOS file system on SD Card are illustrated below:

and:

In the target file system, there must be appropriate device nodes to access the SD Card using standard Linux tools and utilities. Add the following lines to your <project>.initramfs file to create the device nodes for the SD Card:

nod /dev/mmcblk0 0600 0 0 b 179 0
nod /dev/mmcblk0p1 0666 0 0 b 179 1
nod /dev/mmcblk0p2 0666 0 0 b 179 2
nod /dev/mmcblk0p3 0666 0 0 b 179 3
nod /dev/mmcblk0p4 0666 0 0 b 179 4

On the target, you will require the mount utility in order to mount an MS-DOS file system on the SD Card. In Linux, mount is available as part of the multi-call busybox utility. Typically, mount will already be enabled in your busybox configuration, but in case it is not, run the busybox configuration GUI (make bmenuconfig from the project directory), proceed to Linux System Utilities and enable the following item:

To allow measuring read/write throughput rates, enable the dd applet in busybox:

You will also need to add symlinks for mount and dd to the target file system. This is done by adding the following line to the <project>.initramfs file (if the line is not already there):

slink /bin/mount busybox 777 0 0
slink /bin/dd busybox 777 0 0

Having updated your project configuration as described above, build the bootable Linux image (<project>.uImage) by running make from the project directory.

Install the newly built uImage file to the Flash on the target as described in Installing Linux Images to Flash or load it to RAM via Ethernet as described in Loading Linux Images via Ethernet and TFTP.

Insert a pre-formatted card with an MS-DOS file system to the SD Card slot on the TWR-VF6-SOM-BSB baseboard. When you boot the uImage on the Vybrid, there should be messages similar to the ones shown below. In the below example, Linux has detected an SD Card with a single partition on it:

...
init started: BusyBox v1.17.0 (2015-05-29 16:57:14 MSD)
mmc0: new SD card at address c4ae
mmcblk0: mmc0:c4ae SU02G 1.84 GiB
mmcblk0:
p1
~ #

At this point you are ready to mount the MS-DOS file system on the SD Card. This is done as follows:

~ # mount /dev/mmcblk0p1 /mnt

Check that the file system has indeed been mounted (refer to the last line in the below output):

~ # mount
rootfs on / type rootfs (rw)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
none on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
/dev/mmcblk0p1 on /mnt type vfat
(rw,relatime,fmask=0022,dmask=0022,codepage=cp437,
iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

Now you can write something to the SD Card. In the below example, we store the current date and time to a log file, although in real-life applications you will probably want to do something more meaningful:

~ # date > /mnt/log.file

Verify the written content by reading the log file back:

~ # cat /mnt/log.file
Mon Jun 8 12:27:02 UTC 2015
~ #

Write throughput to an 8GB Kingston SDHC card class 10 is measured to be the following:

~ # dd if=/dev/zero of=/mnt/10m bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10.0MB) copied, 0.161602 seconds, 61.9MB/s
~ #

Read throughput using the same SDHC card is as follows:

~ # umount /mnt
~ # mount /dev/ mmcblk0 /mnt
~ # dd if=/mnt/10m of=/dev/null bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10.0MB) copied, 1.051801 seconds, 9.5MB/s
~ #

Ok, you have validated that we can write data to the SD Card. Now you remove the card the from the embedded target. Unmount the file system and then extract the card from the SD Card slot:

~ # umount /mnt
~ #

mmc0: card aaaa removed

At this point, you can take the card to your PC or notebook and process data stored in the MS-DOS filesystem. As a final step in this application note, validate hot insertion of SD Card on the target. Insert the card back into the SD Card slot on the baseboard with Linux up and running on the Vybrid. Messages similar to the ones shown below should appear on the Linux console:

mmc0: new SD card at address aaaa
mmcblk0: mmc0:aaaa SU02G 1.84 GiB
mmcblk0:
p1

Mount the MS-DOS file system and verify the content of the previously created log file:

~ # mount /dev/mmcblk0p1 /mnt
~ # ls -lt /mnt
-rwxr-xr-x 1 root root 29 Jun 8 12:27 log.file
~ # cat /mnt/log.file
Mon Jun 8 12:27:02 UTC 2015
~ #