ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

eMMC存储区域与EXT_CSD[179]分区配置实战指南

eMMC存储区域与EXT_CSD[179]分区配置实战指南 1. eMMC 到底是什么从引脚到协议栈的整体认知eMMC 这个词做嵌入式、做手机、做电视盒子、做车机的朋友基本天天挂在嘴边。它的全称是 embedded MultiMediaCard中文一般叫“嵌入式多媒体卡”。说白了它就是一颗把 NAND Flash 颗粒和一颗 Flash 控制器封装在一起的存储芯片对外只暴露一个标准的多媒体卡接口。你不需要自己去管 NAND 的坏块管理、磨损均衡、ECC 纠错这些麻烦事控制器全帮你做了。这一点对硬件工程师和驱动工程师来说都是巨大的解放——硬件上少走一堆线软件上少写一堆底层逻辑。我最早接触 eMMC 是在做一款工业平板的时候当时用的是某国产主控加一颗 8GB 的 eMMC。那时候还不太懂以为它就是个“焊在板子上的 SD 卡”。后来踩了坑才发现eMMC 和 SD 卡虽然协议同源但 eMMC 有自己独立的寄存器体系、分区结构和启动机制尤其是 EXT_CSD 这一块不懂它基本没法做量产和调试。所以这篇文章我打算把 eMMC 从存储区域结构、EXT_CSD[179]、各分区、主要引脚、命令格式与类型一直到 u-boot 里怎么管理它完整地捋一遍。内容偏实战适合做驱动移植、u-boot 裁剪、量产工具开发以及需要排查 eMMC 读写异常的朋友。先给一个整体印象eMMC 的存储空间不是一整块随便你写的区域它被划分成了好几个功能区——Boot Area、RPMB、General Purpose Partitions、User Data Area还有底层的 Enhanced Area。每个区域有自己的用途和访问规则。而控制这些区域怎么划分、怎么访问的就是 EXT_CSD 寄存器组。你可以把 EXT_CSD 理解成 eMMC 的“配置中心”里面 512 个字节每一位都有含义。其中第 179 字节从 0 开始数是PARTITION_CONFIG这个字节决定了系统从哪个分区启动、当前能访问哪个分区是 u-boot 和内核切换分区时的核心操作对象。理解了这些你再看 u-boot 里的mmc命令、mmc dev、mmc part、mmc read/write就不会觉得是一堆黑盒操作了。下面我按模块拆开讲尽量把每个“为什么”都说清楚。2. eMMC 存储区域结构不是一块盘而是好几个功能区2.1 从物理到逻辑NAND 颗粒与控制器如何协作eMMC 内部其实是一颗或多颗 NAND Flash 裸片加上一颗控制器。NAND 的特点是读写以页为单位常见 2KB、4KB、8KB、16KB擦除以块为单位常见 128KB、256KB、512KB 甚至更大。NAND 还有坏块出厂时就有一定比例的坏块使用过程中还会新增坏块。如果让主控直接管 NAND那软件层面要处理坏块表、ECC、磨损均衡、垃圾回收工作量巨大。eMMC 的控制器把这些全包了。它对外提供的是 512 字节一个扇区的线性地址空间你读写某个扇区控制器内部自己完成地址映射、ECC 校验、坏块替换、磨损均衡。所以从软件角度看eMMC 就像一块普通的块设备和硬盘、SSD 在接口层面很像。但要注意eMMC 的写入放大、寿命、性能都和内部 NAND 类型SLC、MLC、TLC以及控制器策略强相关。这也是为什么同样标称 8GB 的 eMMC不同品牌、不同批次实际写入速度和寿命差异很大。2.2 五大存储区域Boot、RPMB、GPP、User、EnhancedeMMC 标准里把存储空间划分成几个区域每个区域有独立的地址空间和访问属性。下面这张表是我根据 JEDEC 标准和实际调试经验整理的方便你快速对照。区域名称典型大小主要用途访问特点Boot Area Partition 1/2通常 128KB~4MB存放 bootloader如 u-boot SPL上电可由硬件自动读取也可手动切换RPMB通常 128KB~4MB存放安全密钥、防回滚计数器需要认证密钥才能读写普通读写命令无效General Purpose Partition 1~4可配置0~数 GB存放特定数据如双系统、恢复镜像需通过 EXT_CSD 配置后才可见User Data Area剩余全部空间主数据区放系统、应用、用户数据默认访问区域可再划分 Enhanced AreaEnhanced AreaUser 区的一部分提升擦写寿命和写入性能需配置通常用于频繁写入的关键数据Boot Area 是 eMMC 最“硬核”的部分。主控上电后如果硬件设计成从 eMMC 启动那么它会根据 eMMC 内部的一个配置位自动从 Boot Partition 1 或 2 读取数据到内部 SRAM 执行。这个机制让 SoC 不需要外挂 SPI Flash 也能启动。很多方案里u-boot SPL 就放在 Boot Area而完整的 u-boot 和内核放在 User Area。RPMB 是 Replay Protected Memory Block 的缩写它的核心是“防重放”。每次写入都要带一个计数器写入前会校验计数器是否比上次大防止攻击者把旧数据重新写回去。手机里的指纹模板、支付密钥经常放这里。普通mmc write命令是写不进 RPMB 的必须走专门的认证流程这一点在调试时特别容易踩坑。General Purpose PartitionGPP最多有 4 个默认大小是 0也就是不存在。你需要通过 EXT_CSD 的GP_SIZE_MULT系列寄存器来设置每个 GPP 的大小设置完再重新初始化它们才会出现。GPP 的一个典型用途是做 A/B 双系统或者把恢复镜像单独放一个分区避免被主系统误擦。User Data Area 就是我们平时说的“用户区”系统、数据都放这里。它还可以进一步划分出一块 Enhanced Area。Enhanced Area 的物理特性被控制器优化过通常用 SLC 模式或者更好的管理策略擦写寿命和写入速度都比普通区域好但代价是占用更多物理空间。所以 Enhanced Area 一般只划一小块用来放频繁写日志、数据库文件这类数据。2.3 分区大小配置GP_SIZE_MULT 的计算方法GPP 和 Enhanced Area 的大小不是随便填的它由 EXT_CSD 里的GP_SIZE_MULT_1到GP_SIZE_MULT_4以及ENH_SIZE_MULT等寄存器决定。每个寄存器是 3 个字节组合成一个 24 位值。实际大小的计算公式是分区大小 GP_SIZE_MULT × 512KB × WR_REL_PARAM 中的放大系数更准确地说JEDEC 标准定义的单位是 512KB 乘以EXT_CSD[157]里的HC_WP_GRP_SIZE或者EXT_CSD[159]的REL_WR_SEC_C相关参数。实际调试时我一般直接看主控手册或者用mmc extcsd read把整个 EXT_CSD dump 出来对照标准文档算。举个例子如果GP_SIZE_MULT_1的值是 0x000020也就是 32那么大小就是 32 × 512KB 16MB。这个计算在配置双系统分区时非常关键算错了要么分区起不来要么浪费空间。3. EXT_CSD[179] 深度解析一个字节控制启动与分区切换3.1 EXT_CSD 寄存器组全景EXT_CSD 全称 Extended Card Specific Data是 eMMC 比 SD 卡多出来的一组寄存器总共 512 字节。它可以通过CMD8读取也可以通过CMD6的特定模式写入。里面包含了容量、分区配置、总线宽度、速度模式、寿命估算、缓存大小等大量信息。你可以把它当成 eMMC 的“身份证 配置面板”。在 Linux 下如果你有mmc-utils工具可以直接mmc extcsd read /dev/mmcblk0这会打印出所有 512 字节的解析结果包括PARTITION_CONFIG、BOOT_BUS_CONDITIONS、BUS_WIDTH、HS_TIMING等。在 u-boot 下可以用mmc info看基本信息但 EXT_CSD 的完整 dump 需要自己写命令或者用mmc extcsd相关扩展。3.2 PARTITION_CONFIG 的位定义EXT_CSD[179]就是PARTITION_CONFIG它的 8 个 bit 分成三段位段名称含义bit 7Reserved保留bit 6PARTITION_ACCESS当前可访问的分区bit 5:3BOOT_PARTITION_ENABLE上电从哪个 Boot 分区启动bit 2:0BOOT_ACK启动时是否发送 ACK以及 ACK 模式PARTITION_ACCESS的取值决定当前 User Area 之外你能访问哪个区域0可以访问 User Data Area1访问 Boot Partition 12访问 Boot Partition 23访问 RPMB4~7访问 GPP 1~4BOOT_PARTITION_ENABLE的取值0禁止从 eMMC 启动1从 Boot Partition 1 启动2从 Boot Partition 2 启动7从 User Data Area 启动BOOT_ACK一般设成 1表示启动时 eMMC 会回一个 ACK 给主控确认启动数据已经被读取。有些主控要求必须 ACK否则启动失败。3.3 实操用 mmc-utils 切换分区并读写 Boot Area假设你要把一个新的 u-boot SPL 写到 Boot Partition 1可以这样做# 查看当前 PARTITION_CONFIG mmc extcsd read /dev/mmcblk0 | grep PARTITION_CONFIG # 切换到 Boot Partition 1 mmc bootpart enable 1 1 /dev/mmcblk0 # 此时 /dev/mmcblk0boot0 就是 Boot Partition 1 # 写入 SPL dd ifu-boot-spl.bin of/dev/mmcblk0boot0 bs512 seek0 convfsync # 切回 User Area mmc bootpart enable 0 1 /dev/mmcblk0这里有个细节mmc bootpart enable 1 1的第一个参数是启动分区号第二个参数是是否发送 ACK。执行后PARTITION_CONFIG的BOOT_PARTITION_ENABLE和BOOT_ACK会被更新同时PARTITION_ACCESS也会被设成对应分区所以你能看到/dev/mmcblk0boot0设备节点。写完后再切回 0否则系统可能一直访问 Boot 区导致 User 区数据看不到。注意不同主控的 eMMC 控制器对PARTITION_ACCESS的切换支持不一样。有些主控在切换后需要重新初始化 eMMC 才能生效有些则立即生效。我在某国产主控上就遇到过切换后必须mmc rescan才能识别新分区的情况。3.4 常见坑写 Boot 区后启动失败我踩过最典型的一个坑是把 SPL 写到 Boot Partition 1 后忘记设置BOOT_PARTITION_ENABLE结果主控还是从 User Area 启动自然起不来。还有一种情况是BOOT_ACK设错主控等不到 ACK 就超时复位。排查这类问题第一步就是读PARTITION_CONFIG确认 bit 5:3 和 bit 2:0 是否符合预期。第二步是确认 Boot 区数据确实写进去了可以用mmc read读回来对比。4. eMMC 各分区详解与实战配置4.1 Boot Area启动的“第一站”Boot Area 通常有两个分区Boot 1 和 Boot 2。它们的大小在 eMMC 出厂时就固定了常见有 128KB、512KB、1MB、2MB、4MB。具体多大可以读EXT_CSD[226]的BOOT_SIZE_MULT计算公式是BOOT_SIZE_MULT × 128KB。比如读出来是 0x10也就是 16那么每个 Boot 分区就是 16 × 128KB 2MB。Boot 区的一个特点是它支持“上电自动读取”。主控上电后如果硬件启动模式选择 eMMC那么它会自动从BOOT_PARTITION_ENABLE指定的分区读取数据。读取多少通常是主控内部 SRAM 的大小比如 64KB、128KB。所以 SPL 必须放在 Boot 区的最前面而且大小不能超过主控 SRAM 容量。另一个特点是 Boot 区可以设置写保护。通过EXT_CSD[173]的BOOT_WP寄存器可以设置上电后 Boot 区是只读还是可写。量产时一般会设成只读防止误擦。调试阶段则设成可写方便反复烧录。4.2 RPMB安全存储的“保险箱”RPMB 的访问流程和普通分区完全不同。你不能直接用mmc write写必须走一套认证协议主控生成一个随机数发给 eMMC。eMMC 用内部密钥对随机数做 HMAC-SHA256返回给主控。主控验证通过后才能发起带签名的写请求。每次写请求都带一个写计数器eMMC 只接受比当前计数器大的请求。这套机制保证了即使攻击者能物理接触 eMMC也无法篡改或重放 RPMB 数据。在 Android 里RPMB 常用于存储防回滚版本号、指纹模板、DRM 密钥。调试 RPMB 需要专门的工具Linux 下有mmc rpmb相关命令但需要内核支持。u-boot 里一般不做 RPMB 读写因为太复杂通常留给内核或 TEE 处理。4.3 General Purpose Partition灵活的双系统方案GPP 最多 4 个默认大小 0。要启用 GPP需要写GP_SIZE_MULT寄存器然后重新初始化 eMMC。配置 GPP 的步骤大致如下# 假设要设置 GPP1 为 64MB # 64MB / 512KB 128 0x80 # GP_SIZE_MULT_1 是 3 字节所以写 0x000080 mmc extcsd write /dev/mmcblk0 143 0x00 mmc extcsd write /dev/mmcblk0 144 0x00 mmc extcsd write /dev/mmcblk0 145 0x80 # 重新初始化 mmc rescan具体寄存器偏移要看标准文档GP_SIZE_MULT_1在 EXT_CSD 的 143~145 字节GP_SIZE_MULT_2在 146~148依此类推。写完后GPP1 会出现在/dev/mmcblk0gp1这样的设备节点。GPP 的一个典型用途是做 A/B 分区升级A 系统放 User 区B 系统放 GPP1升级时写另一个分区重启切换。这样即使升级失败也能回滚。4.4 Enhanced Area提升寿命的关键配置Enhanced Area 是从 User Data Area 里划出来的一块物理上被控制器优化过。它的配置涉及ENH_SIZE_MULT和ENH_START_ADDR。ENH_SIZE_MULT决定大小ENH_START_ADDR决定起始地址。配置后这块区域的擦写寿命和写入速度会明显优于普通区域。我实测过一颗 8GB 的 eMMC普通区域随机写 4KB 的 IOPS 大概在 200 左右划出 512MB Enhanced Area 后同样测试能到 800 以上。当然代价是 Enhanced Area 占用的物理空间可能是普通区域的 2~3 倍所以总容量会缩水。划多少合适我的经验是如果只是放日志256MB 足够如果是数据库1GB 起步。配置前一定要确认 eMMC 支持 Enhanced 模式读EXT_CSD[158]的ENH_START_ADDR和EXT_CSD[159]的ENH_SIZE_MULT是否可写。5. eMMC 主要引脚与硬件设计要点5.1 引脚定义CLK、CMD、DAT0~7、RST、VCC、VCCQeMMC 的引脚不算多但每一根都很关键。标准 eMMC 封装常见有 BGA-153、BGA-169 等引脚包括引脚功能说明CLK时钟由主控提供频率决定传输速度CMD命令双向用于发送命令和接收响应DAT0~DAT7数据双向支持 1/4/8 位模式RST_n复位低有效用于硬件复位 eMMCVCC主电源通常 3.3V给 NAND 和控制器供电VCCQIO 电源通常 1.8V 或 3.3V给 IO 接口供电VSS地多个地引脚降低噪声DAT0~DAT7 不是所有 eMMC 都引出 8 位。有些小容量 eMMC 只引出 DAT0~DAT3也就是 4 位模式。8 位模式下理论带宽翻倍。比如 52MHz 时钟、8 位模式理论速度是 52 × 8 416Mbps约 52MB/s。如果跑 HS400 模式时钟 200MHz双沿采样8 位理论能到 400MB/s。5.2 硬件设计走线、电源、去耦eMMC 的硬件设计有几个坑我踩过第一CLK 走线要尽量短且包地处理。CLK 是高速信号如果走线太长或者没有参考地容易产生振铃导致命令出错。我见过一个板子CLK 走了 5cm结果 eMMC 只能跑 26MHz降到 52MHz 就各种 CRC 错误。第二DAT 线要等长。8 位模式下DAT0~DAT7 的走线长度差要控制在 5mil 以内否则数据采样窗口会偏移。特别是 HS400 模式对时序要求极高等长和阻抗控制必须做好。第三VCC 和 VCCQ 的去耦电容要靠近引脚。一般 VCC 放 10uF 0.1uFVCCQ 放 1uF 0.1uF。VCCQ 的电源质量直接影响 IO 信号完整性如果 VCCQ 纹波大高速模式下误码率会飙升。第四RST_n 不要悬空。有些设计为了省事把 RST_n 直接接 VCCQ这样 eMMC 无法硬件复位。调试时如果遇到 eMMC 死锁只能断电重启非常麻烦。建议 RST_n 接到主控的 GPIO方便软件复位。5.3 信号完整性HS400 模式下的眼图与调优HS400 是 eMMC 5.1 的最高速度模式200MHz 时钟双沿采样8 位数据。这个模式下信号完整性是成败关键。我一般会做几件事用示波器看 CLK 和 DAT 的眼图确认过冲和振铃在可接受范围。调整主控的 IO 驱动强度和采样相位。很多主控支持DSDrive Strength和Tuning配置通过扫描不同相位找到最佳采样点。如果眼图很差考虑在 CLK 上串一个 22Ω 或 33Ω 电阻减缓上升沿。实测下来HS400 能不能跑稳七分靠硬件三分靠调优。硬件走线不好软件怎么调都白搭。6. eMMC 命令格式与类型CMD、ACMD、响应类型6.1 命令格式48 位命令帧eMMC 的命令通过 CMD 线串行发送一帧 48 位。结构是起始位1 位固定 0传输方向1 位1 表示主控到 eMMC命令号6 位比如 CMD0、CMD1、CMD8参数32 位命令相关参数CRC77 位校验结束位1 位固定 1响应也是 48 位或 136 位取决于命令类型。比如 CMD8 的响应是 48 位包含 OCR 寄存器内容CMD2 的响应是 136 位包含 CID 寄存器。6.2 命令类型BC、BCR、AC、ADTCeMMC 命令按功能分四类类型全称说明例子BCBroadcast Command无响应广播CMD0 复位BCRBroadcast Command with Response有响应广播CMD1 查询 OCRACAddressed Command点对点无数据CMD7 选卡ADTCAddressed Data Transfer Command点对点有数据传输CMD17 读单块CMD0 是复位命令让所有 eMMC 回到 idle 状态。CMD1 是查询 OCR确认电压范围。CMD2 获取 CIDCMD3 分配 RCACMD7 选中卡。CMD8 读 EXT_CSD。CMD17/18 读数据CMD24/25 写数据。CMD6 是切换命令用于改总线宽度、速度模式、分区配置。6.3 常用命令实战初始化、读写、切换eMMC 初始化流程大致是CMD0 复位CMD1 查询 OCR确认电压CMD2 获取 CIDCMD3 分配 RCACMD9 获取 CSDCMD7 选中卡CMD8 读 EXT_CSDCMD6 切换总线宽度和速度模式在 u-boot 里这些流程由mmc_init函数完成。你可以用mmc info看初始化后的信息包括容量、速度模式、总线宽度。如果初始化失败常见原因是电压不匹配、时钟太快、CMD 线被拉低。我一般会先用低速 400KHz 初始化成功后再切高速。读写命令# 读 512 字节到内存 0x80000000 mmc read 0x80000000 0x0 0x1 # 从内存 0x80000000 写 512 字节到偏移 0x0 mmc write 0x80000000 0x0 0x1这里的偏移是扇区号不是字节地址。0x1表示 1 个扇区也就是 512 字节。写之前一定要确认目标区域可写Boot 区如果设了写保护写会失败。7. u-boot 对 eMMC 的管理驱动模型与命令体系7.1 u-boot MMC 子系统架构u-boot 的 MMC 子系统采用驱动模型DM核心结构是struct mmc和struct mmc_ops。mmc结构体里保存了 eMMC 的 CID、CSD、EXT_CSD、RCA、容量、速度模式等信息。mmc_ops是底层操作函数集包括send_cmd、set_ios、init等。具体主控的驱动实现这些函数比如sdhci、dw_mmc、sunxi_mmc。初始化流程主控驱动 probe注册mmc设备。调用mmc_init发送 CMD0、CMD1、CMD2、CMD3、CMD9、CMD7、CMD8。解析 EXT_CSD获取容量、分区信息。根据配置切换总线宽度和速度模式。注册块设备供mmc read/write使用。7.2 u-boot 下的 mmc 命令详解u-boot 的mmc命令是调试 eMMC 的利器。常用子命令命令作用mmc info显示当前 eMMC 信息mmc dev [dev] [part]切换设备或分区mmc part显示分区表mmc read addr blk cnt读数据到内存mmc write addr blk cnt从内存写数据mmc erase blk cnt擦除mmc rescan重新扫描mmc bootbus设置启动总线条件mmc bootpart设置启动分区mmc dev 0 1表示切换到设备 0 的分区 1。这里的“分区”是 eMMC 的硬件分区不是 GPT 分区表。分区号 0 是 User Area1 是 Boot 12 是 Boot 23 是 RPMB4~7 是 GPP。7.3 在 u-boot 中读写 Boot 区和 GPP假设你要在 u-boot 里更新 Boot Partition 1 的 SPL# 切换到 Boot 1 mmc dev 0 1 # 从内存写 512 字节到 Boot 1 偏移 0 mmc write 0x80000000 0x0 0x1 # 切回 User Area mmc dev 0 0如果要写 GPP1先确认 GPP1 已经配置好然后mmc dev 0 4再读写。注意u-boot 的mmc dev分区号是固定的GPP1 对应 4GPP2 对应 5依此类推。7.4 u-boot SPL 与 eMMC 启动流程SPL 是 Second Program Loader运行在 SoC 内部 SRAM 里。它的任务是从 eMMC 加载完整的 u-boot 到 DDR。启动流程SoC 上电BootROM 根据启动模式从 eMMC Boot 区读取 SPL 到 SRAM。SPL 初始化 DDR、时钟、eMMC 控制器。SPL 从 eMMC User Area 读取 u-boot 到 DDR。跳转到 u-boot 执行。SPL 里对 eMMC 的操作很底层通常直接调用mmc_init和mmc_read。如果 SPL 阶段 eMMC 初始化失败系统就起不来。常见原因是 SPL 里时钟配置太快或者电压没设对。我一般会在 SPL 里先用低速模式读成功后再切高速。8. 常见问题与排查技巧实录8.1 eMMC 初始化失败从电压到时钟的排查顺序eMMC 初始化失败是最常见的问题。我的排查顺序是量电压VCC 是否 3.3VVCCQ 是否 1.8V 或 3.3V。电压不对什么都别谈。量时钟CLK 是否有波形频率是否在 400KHz 左右。如果没波形查主控时钟配置。量 CMDCMD 线上是否有命令波形。如果没有查主控驱动是否 probe 成功。看响应用示波器抓 CMD 线看 eMMC 是否有响应。如果 CMD1 没响应可能是电压范围不匹配。降速把时钟降到 400KHz总线宽度设 1 位再试。如果低速能过高速不过就是信号完整性问题。8.2 读写数据 CRC 错误信号完整性与时序调优CRC 错误通常出现在高速模式。排查步骤降低时钟频率看是否消失。如果消失说明时序余量不足。检查 DAT 线等长和阻抗。用 TDR 测阻抗确认是否 50Ω。调整采样相位。很多主控支持tuning扫描相位找到最佳点。检查 VCCQ 纹波。纹波大IO 误码率高。我遇到过一颗 eMMCHS200 模式下读数据偶尔 CRC 错降到 HS 模式就没事。后来发现是 DAT 线走线太长且没有包地。改板后问题解决。8.3 分区切换后设备节点消失PARTITION_ACCESS 的坑在 Linux 下切换PARTITION_ACCESS后/dev/mmcblk0boot0可能会消失或出现。这是因为内核的 mmc 驱动会根据PARTITION_CONFIG动态创建块设备。如果你切换后没看到设备节点可以# 重新扫描 mmc 总线 echo 1 /sys/class/mmc_host/mmc0/device/rescan或者直接mmc rescanu-boot 下。有些内核版本需要重新加载 mmc 驱动模块。8.4 常见问题速查表问题现象可能原因解决方法初始化失败CMD1 无响应电压不对、时钟太快检查 VCC/VCCQ降时钟到 400KHz读写 CRC 错误信号完整性差、时序余量不足降速、调相位、检查走线Boot 区写不进去写保护开启读BOOT_WP关闭写保护切换分区后设备节点消失内核未重新扫描触发 rescan 或重新加载驱动GPP 配置后不出现未重新初始化写GP_SIZE_MULT后mmc rescanRPMB 读写失败未走认证流程使用专用 RPMB 工具确认密钥8.5 独家避坑技巧量产前的 eMMC 健康检查量产前我一般会做几件事读EXT_CSD[268]的PRE_EOL_INFO确认 eMMC 寿命状态。0x01 正常0x02 警告0x03 urgent。读EXT_CSD[269]的DEVICE_LIFE_TIME_EST_TYP_A和TYP_B估算寿命。全盘写 0 再读回确认没有坏块导致的读写错误。测试 Boot 区读写确认启动分区可写。测试 RPMB 认证流程确认安全功能正常。这些检查看起来麻烦但能避免量产后的批量返工。我见过一批板子因为 eMMC 寿命状态是警告结果用了三个月就大量返修。9. 从 eMMC 到实际项目我的几点经验体会eMMC 这东西入门容易精通难。协议文档几百页寄存器几百个但真正项目中常用的就那么几十个。我的建议是先把存储区域结构和PARTITION_CONFIG吃透这是理解 eMMC 分区管理的钥匙。然后动手在 u-boot 里用mmc命令读写各个分区观察EXT_CSD的变化。最后再深入命令格式和响应类型理解底层通信机制。硬件设计上不要省 RST_n 和去耦电容。高速模式下信号完整性决定一切。软件调试上先低速后高速先 1 位后 8 位逐步排查。遇到问题先量电压、时钟、信号再看寄存器配置。这套方法我在多个项目里用过基本能覆盖 90% 的 eMMC 问题。最后分享一个小技巧如果你不确定某个 EXT_CSD 寄存器的含义可以直接在 Linux 下mmc extcsd read然后对照 JEDEC 标准文档。标准文档虽然枯燥但它是唯一权威。网上很多博客写的寄存器偏移是错的以文档为准。
返回列表