Skip to content

Instantly share code, notes, and snippets.

@kylemanna
Last active December 9, 2022 08:41
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save kylemanna/5692543 to your computer and use it in GitHub Desktop.
Save kylemanna/5692543 to your computer and use it in GitHub Desktop.
Parse eMMC Extended CSD and print useful things.
#!/usr/bin/env python
"""
Author: Kyle Manna <kyle@kylemanna.com>
Blog: https://blog.kylemanna.com
cat /d/mmc0/mmc0:0001/ext_csd
0000000000000001030100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000087a0000000000000000061502030700100608010101080800100000728000000808080808080000000000010200070002000500000000000001000200000000000000000000000000000100050000000000030001ca00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"""
import binascii
import re
import sys
def str2bytearray(s):
if len(s) % 2:
s = '0' + s
reorder = True
if reorder:
r = []
i = 1
while i <= len(s):
r.append(s[len(s) - i - 1])
r.append(s[len(s) - i])
i += 2
s = ''.join(r)
out = bytearray(binascii.unhexlify(s))
return out
if __name__ == '__main__':
ecsd_str = '0000000000000001030100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000087a0000000000000000061502030700100608010101080800100000728000000808080808080000000000010200070002000500000000000001000200000000000000000000000000000100050000000000030001ca00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
#ecsd_str = '320100'
ecsd = str2bytearray(ecsd_str)
line_len = 16
i = 0
while i < len(ecsd):
sys.stdout.write("{0:04x}:\t".format(i))
for j in range(line_len):
if (i < len(ecsd)):
sys.stdout.write("{0:=02x}".format(ecsd[i]))
i = i + 1
else:
break
if (j == (line_len - 1)): pass
elif (i % 4): sys.stdout.write(" ")
else: sys.stdout.write(" ")
sys.stdout.write("\n")
print("SECURE_REMOVAL_TYPE[16] = 0x{:x}".format(ecsd[16]))
print("SLC_DEVICE_HEALTH_STATUS[87] = 0x{:x}".format(ecsd[87]))
print("SLC_DEVICE_HEALTH_STATUS[87] = 0x{:x}".format(ecsd[87]))
print("MLC_DEVICE_HEALTH_STATUS[94] = 0x{:x}".format(ecsd[94]))
print("SEC_BAD_BLK_MGMNT[134] = 0x{:x}".format(ecsd[134]))
print("RPMB_SIZE_MULT[168] = 0x{:x}".format(ecsd[168]))
print("FW_CONFIG[169] = 0x{:x}".format(ecsd[169]))
print("ERASE_GROUP_DEF[175] = 0x{:x}".format(ecsd[175]))
print("EXT_CSD_REV[192] = 0x{:x}".format(ecsd[192]))
print("CSD_STRUCTURE[194] = 0x{:x}".format(ecsd[194]))
print("CARD_TYPE[196] = 0x{:x}".format(ecsd[196]))
print("ERASE_TIMEOUT_MULT[223] = 0x{:x}".format(ecsd[223]))
print("HC_ERASE_GRP_SIZE[224] = 0x{:x}".format(ecsd[224]))
print("BOOT_SIZE_MULT[226] = 0x{:x}".format(ecsd[226]))
print("BOOT_INFO[228] = 0x{:x}".format(ecsd[228]))
print("SEC_TRIM_MULT[229] = 0x{:x}".format(ecsd[229]))
print("SEC_ERASE_MULT[230] = 0x{:x}".format(ecsd[230]))
print("SEC_FEATURE_SUPPORT[231] = 0x{:x}".format(ecsd[231]))
print("PRE_EOL_INFO[267] = 0x{:x}".format(ecsd[267]))
print("DEVICE_LIFE_TIME_EST_TYP_A[268] = 0x{:x}".format(ecsd[268]))
print("DEVICE_LIFE_TIME_EST_TYP_A[269] = 0x{:x}".format(ecsd[269]))
@lgommans
Copy link

Note that this can also be found in the output of mmc extcsd read /dev/block/mmcblk0 (replace with a device of your choice). The command is part of the mmc-utils package available e.g. in Debian. I think that is more reliable as it receives updates with your OS. And btw the last value in this script (269) should be labeled ...TYP_B. The life time estimation values are both in tens of percents, so 0x03 would be 30% worn.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment