1. 项目背景与核心挑战
在嵌入式Linux开发中,EMMC驱动适配是系统移植过程中最关键的硬件适配环节之一。最近在Ubuntu 20.04环境下为某ARM平台移植Linux内核时,遇到了EMMC控制器无法正确识别存储设备的问题。这个问题直接导致系统无法从EMMC启动,也影响了后续根文件系统的部署。
通过内核启动日志分析,发现控制器虽然能正常初始化,但在执行CMD8命令(发送接口条件)时出现超时错误。这个问题在嵌入式开发中相当典型——原厂提供的内核源码往往针对特定开发板做了优化,当我们需要在不同硬件平台上移植时,驱动层的适配工作就变得尤为重要。
2. 驱动修改前的准备工作
2.1 环境确认与源码获取
首先需要确保基础环境配置正确:
bash复制# 确认交叉编译工具链
arm-linux-gnueabihf-gcc --version
# 获取目标内核源码(以4.19.y为例)
git clone -b linux-4.19.y https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
特别要注意的是,Ubuntu 20.04默认的gcc版本是9.3.0,这个版本对较老的内核可能存在兼容性问题。建议安装gcc-8:
bash复制sudo apt install gcc-8
export CC=gcc-8
2.2 硬件参数收集
修改驱动前必须明确硬件参数:
- 通过原理图确认EMMC控制器型号(如DWMMC 2.80a)
- 测量实际时钟频率(使用示波器抓取CLK信号)
- 记录GPIO复用情况(特别是CMD和DAT线的引脚分配)
这些信息将直接影响驱动参数配置的正确性。我曾遇到过因为忽略GPIO复用配置,导致DAT线信号异常的案例,花费了两天时间才定位到问题。
3. EMMC驱动关键修改步骤
3.1 时钟配置调整
找到drivers/mmc/host/dw_mmc.c文件,修改时钟分频参数:
c复制/* 原配置 */
host->bus_hz = 52000000;
/* 修改为实际测量值 */
host->bus_hz = 48000000;
同时需要调整SDCLK频率限制:
code复制
