Created
July 22, 2023 07:48
-
-
Save llccd/86a225f57700cd54d4d1676bd29eed5a to your computer and use it in GitHub Desktop.
BCH ECC decoder for Qualcomm NAND controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# BCH ECC decoder for Qualcomm NAND controller | |
# This script assumes no bad block on flash | |
# Ref: | |
# https://elixir.bootlin.com/linux/latest/source/drivers/mtd/nand/raw/qcom_nandc.c | |
# https://github.com/ecsv/qcom-nandc-pagify | |
import bchlib | |
# 128MiB Flash, Page Size:2048+128 | |
page_size = 2048 | |
oob_size = 128 | |
page_count = 128 * 1024 * 1024 // page_size | |
# 8-Bit BCH, 8x bus: 13 bytes ECC | |
bbm_size = 1 | |
ecc_bits = 8 | |
chunk_count = page_size // 512 | |
chunk_size = 532 if ecc_bits == 8 else 528 | |
data_size = 516 | |
data1_size = page_size - (chunk_count - 1) * chunk_size | |
data2_size = data_size - data1_size | |
bch = bchlib.BCH(8219, ecc_bits) | |
f = open('nand-dump.bin', 'rb') | |
fo = open('decoded.bin', 'wb') | |
for page in range(page_count): | |
for chunk in range(chunk_count): | |
data = bytearray(f.read(data1_size)) | |
f.read(bbm_size) | |
data += f.read(data2_size) | |
ecc = bytearray(f.read(bch.ecc_bytes)) | |
bit_flip = bch.decode_inplace(data, ecc) | |
if (bit_flip > 0): | |
print('ecc corrected ' + bit_flip + 'bits on page ' + page + ' chunk ' + chunk) | |
elif (bit_flip < 0): | |
print('uncorrectable ecc at page ' + page + ' chunk ' + chunk) | |
if (chunk == chunk_count - 1): | |
fo.write(data[:-4 * chunk_count]) | |
else: | |
fo.write(data) | |
f.read(chunk_size - data_size - bbm_size - bch.ecc_bytes) | |
f.read(page_size + oob_size - chunk_size * chunk_count) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment