Understanding eMMC User Capacity
eMMC Apparently Misreporting Capacity
Many users have pointed out that the eMMC flash ROM of HTC Vision and other models reports itself via it's CID register as a Samsung "SEM04G" (SDIN5C2-4G) which has a User Data capacity of 3,957,325,824 bytes (7,729,152 x 512-byte sectors). However, according to the kernel, the device capacity is only 2.10GiB (2,254,858,240 bytes or 4,404,020 x 512-byte sectors):
INFO [ 5.501770] mmcblk0: mmc0:0001 SEM04G 2.10 GiB
That leaves 1,702,467,584 bytes (3,325,132 x 512-byte sectors) apparently unavailable or missing. The "2.10 GiB" figure is calculated as an approximation of the exact value and there can be a small unreported remainder.
A picture says a thousand words
In this diagram some partitions are shown as allocated to make understanding the entire capacity issue easier.
The answer is in the eMMC specification but is not spelled out clearly. The total user capacity of the embedded MultiMediaCard (eMMC) is the sum of the size of the enhanced user data area and the remaining user data area. The eMMC EXT_CSD registers accurately reflect the user capacity.
The SanDisk SDIN5C2-4G uses Multi-Level Cell (MLC) X4 technology that SanDisk acquired when they bought Israeli company M-Systems in November 2006. The X4 (multiply by four) technology allows detection of sixteen separate voltages, representing 8 binary bits, in the floating-gate (FG) MOSFET transistors used in NAND flash devices. X4 allows increased storage for the same number of FG-MOSFETs but with increased errors due to the difficulty of accurately detecting the smaller voltage differences in a cell.
The enhanced mode of X4 eMMC simply reduces the cells to X2 (8 separate voltage levels) representing 4 binary bits.
Having less voltage levels to detect with larger differences means enhanced reliability at the expense of halving the storage capacity.
The eMMC can be programmed once in its lifetime with enhanced capabilities. This is done at the same time as the eMMC is partitioned by the manufacturer of the device that contains the eMMC. The eMMC has two Boot partitions, a Replay Protected Memory Block (RPMB), four General Purpose partitions (which can be zero length) and a User Data area.
Because not all data storage applications require this enhanced reliability eMMC provides for assigning a range of logical sectors in the user data area as enhanced. The starting location of this enhanced user data area can also be specified. The effect is that the enhanced X2 storage areas require twice as much space as regular X4 un-enhanced areas. When enhanced reliability is selected the RPMB and Boot partitions are automatically also enhanced. The four General Purpose partitions can be individually set as enhanced using the WR_REL_SET register in EXT_CSD.
The SEM04G is partitioned by HTC in the Vision as:
Boot1, Boot2, each 1 MiB
RPMB 128 kiB
GP1-GP4, each 0 MiB
User Data (in two disconnected chunks) 528 MiB
Enhanced User Data (offset 512 MiB into User Data) 1.5859375 GiB
Crunching the Numbers
This is a systematic reduction of the numbers using the values reported by a SEM04G eMMC via its EXT_CSD registers. The device_size_mismatch of 6.25MiB between the calculation and the maximum user capacity that SanDisk publish could be due to how they define the maximum capacity - sectors reserved for bad blocks, reliable write and so on might not be reflected in the EXT_CSD values.
# UPPERCASE are eMMC specification-defined registers in EXT_CSD # 0x00434000 SEC_COUNT = 4407296 #ENH_SIZE_MULT_2 = 0x00 #ENH_SIZE_MULT_1 = 0x00 #ENH_SIZE_MULT_0 = 0x00 ENH_SIZE_MULT = 0 # 0x04 HC_WP_GRP_SIZE = 4 # 0x04 HC_ERASE_GPR_SIZE = 4 # 0x0000EC MAX_ENH_SIZE_MULT = 236 # 0x00100000 ENH_START_ADDR = 1048576 # 512kB multiplier used by eMMC specification size_multiplier = 524288 # bytes in a single addressable block sector_size = 512 total_capacity = SEC_COUNT * sector_size # 2256535552 (2.1015625 GiB) enhanced_size = ENH_SIZE_MULT * HC_WP_GRP_SIZE x HC_ERASE_GPR_SIZE * size_multiplier # 1702887424 (1.5859375 GiB) enh_sector_count = enhanced_size / sector_size # 3325952 unenhanced_sector_count = SEC_COUNT - enh_sector_count # 1081344 unenhanced_size = unenhanced_sector_count * sector_size # 553648128 user_data_prefix = sector_size * ENH_START_ADDRESS # 536870912 (0.5 GiB) user_data_suffix = unenhanced_size - user_data_prefix # 16777216 # 128kB multiplier used by eMMC specification boot_size_multipler = 131072 #0x08 BOOT_SIZE_MULTI = 8 boot_part_size = BOOT_SIZE_MULTI * boot_size_multiplier # 1048576 # device has two boot partitions boot_part_qty = 2 boot_parts_size = boot_part_qty * boot_part_size # 2097152 # 0x01 RPMB_SIZE_MULT = 1 rpmb_size = RPMB_SIZE_MULT * boot_size_multiplier # 131072 enhanced_boot_size = boot_parts_size + rpmb_size # 2228224 # 0x04 : bit 2 = EN_REL_WR (The device supports the enhanced definition of reliable write) # : bit 0 = HS_CTRL_REL (All the WR_DATA_REL parameters in the WR_REL_SET register are read only bits) WR_REL_PARAM = b00000100 # 0x17 WR_REL_SET = b00010111 WR_DATA_REL_4 = 1 WR_DATA_REL_3 = 0 WR_DATA_REL_2 = 1 WR_DATA_REL_1 = 1 WR_DATA_REL_USER = 1 total_user_size = unenhanced_size + (2 * enhanced_size) # 3959422976 # 3.6875 GiB total_size = total_user_size + (2 * enhanced_boot_size) # 3963879424 # 3.691650391 GiB # SanDisk specification for the SEM04G part # 3.685546875 GiB sandisk_user_max_sector_count = 7729152 sandisk_user_max_size = 3957325824 device_size_mismatch = total_size - sandisk_user_max_size # 6553600 # 6.25 MiB capacity_mismatch = total_capacity - unenhanced_size - enhanced_size # 0