3.2.4.13. MMC/SD
3.2.4.13.1. Introduction
The multimedia card high-speed/SDIO (MMC/SDIO) host controller provides an interface between a local host (LH) such as a microprocessor unit (MPU) or digital signal processor (DSP) and either MMC, SD® memory cards, or SDIO cards and handles MMC/SDIO transactions with minimal LH intervention.
Main features of the MMC/SDIO host controllers:
Full compliance with MMC/SD command/response sets as defined in the Specification.
Support:
4-bit transfer mode specifications for SD and SDIO cards
8-bit transfer mode specifications for eMMC
Built-in 1024-byte buffer for read or write
32-bit-wide access bus to maximize bus throughput
Single interrupt line for multiple interrupt source events
Two slave DMA channels (1 for TX, 1 for RX)
Designed for low power and programmable clock generation
Maximum operating frequency of 48MHz
MMC/SD card hot insertion and removal
The following image shows the MMC/SD Driver Architecture:

3.2.4.13.2. References
3.2.4.13.3. Acronyms & Definitions
Acronym |
Definition |
---|---|
MMC |
Multimedia Card |
HS-MMC |
High Speed MMC |
SD |
Secure Digital |
SDHC |
SD High Capacity |
SDIO |
SD Input/Output |
3.2.4.13.4. Features
The SD driver supports the following features:
The driver is built in-kernel (part of vmlinux)
SD cards including SD High Speed and SDHC cards
Uses block bounce buffer to aggregate scattered blocks
3.2.4.13.5. SD: Supported High Speed Modes
3.2.4.13.6. Driver Configuration
The default kernel configuration enables support for MMC/SD(built-in to kernel).
The selection of MMC/SD/SDIO driver can be modified using the linux kernel configuration tool. Launch it by the following command:
$ make menuconfig ARCH=arm
Building into Kernel
- Ensure that the following config options are set to ‘y’:
CONFIG_MMC
CONFIG_MMC_BLOCK
CONFIG_MMC_SDHCI
CONFIG_MMC_SDHCI_OMAP (for DRA7XX and AM57XX devices)
CONFIG_MMC_OMAP (for AM335X and AM437X devices)
Building as Loadable Kernel Module
Depending on your configuration, any of the above options can be set to ‘m’ to build them as a module. Use the following command to install all modules tp your filesystem.
$ sudo -E make modules_install ARCH=arm INSTALL_MOD_PATH=path/to/filesystem
Boot the kernel upto kernel prompt and use modprobe to insert the driver module and all its dependencies.
$ modprobe sdhci-omap # for DRA7XX and AM57XX devices
$ modprobe omap_hsmmc # for AM335X and AM437X devices
If udev is running and the SD card is already inserted, the required modules will be loaded and any valid filesystem will be automatically mounted if they exist on the card.
Enabling eMMC Card Background operations support
eMMC cards need to occasionally spend some time cleaning up garbage and perform cache/buffer related operations. These are strictly on the card side and do not involve the host. They occur at one of the three levels based on the importance/severity of the operation:
Normal
Important
Critical
If an operation is delayed for too long, it becomes critical, taking priority over the regular read/write from host. This can cause host operations to be delayed or take more time than expected. To avoid such issues the MMC HW and core driver provide a framework which can check for pending background operations and give the card some time to service them before they become critical. This feature is already part of the framework and to start using it the User needs to enable: EXT_CSD : BKOPS_EN [163] BIT 0.
This can be done using the “mmc-utils” tool from user space or using the “mmc” command in U-boot.
Command to enable bkops from userspace using mmc-utils, assuming eMMC instance to be mmcblk0
root@<machine>:mmc bkops enable /dev/mmcblk0
You can find the instance of eMMC by reading the ios timing spec form debugfs:
root@<machine>:~# cat /sys/kernel/debug/mmc0/ios
----
timing spec: 9 (mmc HS200)
---
or by looking for boot partitions, eMMC has two boot partitions mmcblk<x>boot0 and mmcblk<x>boot1
root@<machine>:/# ls /dev/mmcblk*boot*
/dev/mmcblk0boot0 /dev/mmcblk0boot1
3.2.4.13.7. Create software partitions in eMMC UDA
In eMMC, the User Data Area (UDA) HW partition is the primary storage
space generally used to flash the rootfs. To prepare the UDA, use
the fdisk command. For ex: fdisk /dev/mmcblkN
in
which N is 0 or 1. To find which integer is eMMC use the command
lsblk, like so:
root@<machine>:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
mmcblk0 179:0 0 14.8G 0 disk
mmcblk0boot0 179:32 0 31.5M 1 disk
mmcblk0boot1 179:64 0 31.5M 1 disk
mmcblk1 179:96 0 14.8G 0 disk
|-mmcblk1p1 179:97 0 128M 0 part /run/media/boot-mmcblk1p1
`-mmcblk1p2 179:98 0 1.9G 0 part /
Where the eMMC will have hardware partitions mmcblkNboot0
and mmcblkNboot1
. The mmcblkN
is the eMMC device.
Now we use fdisk /dev/mmcblk0
to create one software partition
in UDA. For documentation on using fdisk, please go to:
fdisk how-to.
3.2.4.13.8. Formatting eMMC partitions from Linux
After creating a partition/s, the partition can be formated with
the mkfs command. For ex: mkfs -t ext4 /dev/mmcblkN
where mmcblkN is the MMC device with the software partition to format.
The general syntax for formatting disk partitions in Linux is:
mkfs [options] [-t type fs-options] device [size]
For example, to format a partition in eMMC UDA to ext4 file system:
root@<machine>:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
mmcblk0 179:0 0 14.8G 0 disk
`-mmcblk0p1 179:1 0 14.8G 0 part /run/media/mmcblk0p1
mmcblk0boot0 179:32 0 31.5M 1 disk
mmcblk0boot1 179:64 0 31.5M 1 disk
mmcblk1 179:96 0 14.8G 0 disk
|-mmcblk1p1 179:97 0 128M 0 part /run/media/boot-mmcblk1p1
`-mmcblk1p2 179:98 0 8.8G 0 part /
root@<machine>:~# umount /run/media/mmcblk0p1
[ 43.648532] EXT4-fs (mmcblk0p1): unmounting filesystem f8ecc7b8-ab1a-4240-ab4b-470d242c0539.
root@<machine>:~# mkfs -t ext4 /dev/mmcblk0p1
mke2fs 1.47.0 (5-Feb-2023)
Discarding device blocks: done
Creating filesystem with 3884800 4k blocks and 972944 inodes
Filesystem UUID: 842929dd-4e57-47b6-afa1-c03abc3100b1
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done