Linux EMMC子系统分析-初始化流程

基于FPGA模拟EMMC工作流程 EMMC5.1 阅读详情

最近在解EMMC的一个bug,发现Linux EMMC有点小复杂,先整理个文档出来吧

用的是TI 平台,仅分析MMC,不分析SD和SDIO


mmc_init

2769 static int __init mmc_init(void)
2770 {
2774 
2775     workqueue = alloc_ordered_workqueue("kmmcd", 0);
2776     if (!workqueue)
2777         return -ENOMEM;
2778 
2779     ret = mmc_register_bus();
2780     if (ret)
2781         goto destroy_workqueue;
2782 
2783     ret = mmc_register_host_class();
2784     if (ret)
2785         goto unregister_bus;;
2793 

2802 }

2775分配一个workqueue,这个workqueue是专门用来处理card detect的,EMMC因为是unremovable的,所以不需要关注它

2779 注册mmc_bus_type,实现如下:

int mmc_register_bus(void)
{
    return bus_register(&mmc_bus_type);
}
把mmc_bus_type注册到bus系统,后面调用device_add函数时,则会辗转调用到mmc_bus_type中的probe函数,不必太纠结在这个代码


mmc_init调用时间比较早,会在host驱动初始化之前执行完。

subsys_initcall(mmc_init);

host驱动初始化

kernel/drivers/mmc/host/omap_hsmmc.c

host驱动位置是kernel/drivers/mmc/host/,一般来说都是platform_driver,以omap hsmmc host驱动为例

    <strong>.probe      = omap_hsmmc_probe,</strong>
    .remove     = omap_hsmmc_remove,
    .driver     = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
        .pm = &omap_hsmmc_dev_pm_ops,
        .of_match_table = of_match_ptr(omap_mmc_of_match),
    },
};

module_platform_driver(omap_hsmmc_driver);

只需要关注omap_hsmmc_probe即可,当系统匹配到platform_device时,会调用omap_hsmmc_probe,好长的一个函数

2627     base = devm_ioremap_resource(&pdev->dev, res);
2628     if (IS_ERR(base))
2629         return PTR_ERR(base);
2630 
2631     ret = omap_hsmmc_gpio_init(pdata);
2632     if (ret)
2633         goto err;
devm_ioremap_resource,实质就是ioremap,设备特定io资源到内核地址的映射,自行脑补一下ioremap。

omap_hsmmc_gpio_init是card detect和write protect gpio的初始化,Ignore it!!!

2635     mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev);
2636     if (!mmc) {
2637         ret = -ENOMEM;
2638         goto err_alloc;
2639     }
...............
mmc_alloc_host,分配一个omap_hsmmc_host结构(包含struct mmc_host),以供后面玩耍

2661     mmc->ops    = &omap_hsmmc_ops;

2410 static const struct mmc_host_ops omap_hsmmc_ops = {
2411     .enable = omap_hsmmc_enable_fclk,
2412     .disable = omap_hsmmc_disable_fclk,
2413     .post_req = omap_hsmmc_post_req,
2414     .pre_req = omap_hsmmc_pre_req,
2415     .request = omap_hsmmc_request,
2416     .set_ios = omap_hsmmc_set_ios,
2417     .get_cd = omap_hsmmc_get_cd,
2418     .get_ro = omap_hsmmc_get_ro,
2419     .init_card = omap_hsmmc_init_card,
2420     .start_signal_voltage_switch = omap_start_signal_voltage_switch,
2421     .card_busy = omap_hsmmc_card_busy,
2422     .execute_tuning = omap_execute_tuning,
2423     /* NYET -- enable_sdio_irq */
2424 };
 omap hsmmc host驱动和mmc子系统的所有接口都在这里了。

2663     mmc->f_min = OMAP_MMC_MIN_CLOCK;

2675     if (pdata->max_freq > 0) {
2676         mmc->f_max = pdata->max_freq;
2677         ret = clk_set_rate(host->fclk, pdata->max_freq);
2678         if (ret) {
2679             dev_err(dev, "failed to set clock to %d\n",
2680                 pdata->max_freq);
2681             goto err1;
2682         }
2683     } else {
2684         mmc->f_max = OMAP_MMC_MAX_CLOCK;
2685     }


定义了最小时钟400K,在系统初始化阶段为了兼容的原因会使用这个时钟。最大时钟为52MHZ,后面还有机会再修改这个时钟频率。

2724     mmc->max_segs = 1024;
2725 
2726     mmc->max_blk_size = 512;       /* Block Length at max can be 1024 */
2727     mmc->max_blk_count = 0xFFFF;    /* No. of Blocks is 16 bits */
2728     mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
2729     mmc->max_seg_size = mmc->max_req_size;

mmc作为快设备,最主要的操作就是数据sectors读写,max_segs定义了block设备的request所支持的最大segment

max_blk_count 一个request中所包含的最大block数

其实多少都不重要,反正就是和request相关的一些上限。

2731     mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
2732              MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
2733 
2734     mmc->caps |= mmc_slot(host).c
eMMC Sampling Tuning and linux mmc driver support 目录 1. eMMC 总线 Sampling Tuning 1.1 Sampling Tuning 流程 1.2 Tuning Block 数据 1.3 retuning mode 2. linux mmc driver中的retuning触发机制 2.1 设备初始化时tuning 2.2 timer retuning(software) 2.3 Auto-Tuning(hard... 阅读详情

相关推荐

eMMC驱动分析

作者:Aningsk ,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。    基于ATMEL-sama5d3芯片与Linux-3.6.9内核。     SD卡系列简介 这些都是网上找出来的,权当作为开场白了。   MMC卡全称Multi Media Card,由西门子公司和SanDisk公司1997年推出的多媒体记忆卡标准。MMC卡尺寸为...

Aningsk 1万+

基于RK3399的Linux驱动开发 -- EMMC驱动框架

文章目录一、概述二、host层1、dw_mci框架`dw_mci_drv_data``dw_mci_dma_ops``dw_mci``dw_mci_pltfm_register``dw_mci_probe``dw_mci_init_slot``dw_mci_init_dma`2、dw_mci-rockchip驱动`dw_mci_rockchip_probe`三、core层1、对接host层的接口`...

Venkee 4473

emmc linux 识别分区_EMMC总结

通俗的来说,eMMC=NAND闪存+闪存控制芯片+标准接口封装。本文大致做下边几个小结:(1)MMC与Host之间的连接连接由下图可见(2)eMMC和NAND Flash与Host的连接比较NAND Flash直接接入HostNAND Flash直接接入Host时,Host端通常需要有NAND Flash Translation Layer,即NFTL或者NAND Fla...

weixin_28961645的博客 793

SD/eMMC初始化流程、读写流程(dwc mshc)

dwc mshc

yangguoyu8023的博客 1万+

eMMC协议:嵌入式设备中的eMMC初始化过程

在开始eMMC初始化之前,首先需要将eMMC与嵌入式设备的主控制器进行正确的硬件连接。具体的连接方式和引脚定义可能因具体的嵌入式平台而异,通常需要连接电源、时钟以及数据线(包括命令线和数据线)。通过以上的步骤,可以完成嵌入式设备中eMMC的初始化过程。请注意,以上示例代码仅供参考,具体的eMMC初始化过程请根据具体的嵌入式平台和eMMC芯片规格进行适当的修改和调整。初始化命令的具体内容和顺序可以根据eMMC芯片的规格进行调整。在实际应用中,需要根据具体的eMMC芯片型号和嵌入式设备的要求进行寄存器配置。

CodeMaven的博客 1037

Linux 块设备 EMMC 驱动介绍

在设备初始化之前,需要根据设备的节点信息获取设备资源。其中,寄存器地址和中断号是必须要获取的,而时钟是可选的,因为不是所有的MMC设备都需要时钟。在基于Linux 4.4内核的EMMC块设备驱动框架中,EMMC驱动和主机控制器驱动直接与硬件交互,而通用块层子系统和MTD子系统则为用户提供一个统一的访问接口,便于上层应用程序开发和移植。eMMC设备可以看作是块设备的一种,因此需要进行块设备的初始化,包括分区表读取等操作。设备初始化完成后,需要向系统注册一个MMC设备,并分配一个新的主设备号。

zljdfaljsfd的博客 3345

STM32F407VE支持4位EMMC读写和FATFS

已经在STM32F407VE上验证测试可以读写EMMC,并支持FATFS,支持文件的读写。

uniapp串口通信实战:从零搭建物联网设备控制App(附完整代码)

本文详细介绍了如何使用Uniapp实现串口通信,从零搭建物联网设备控制App。内容涵盖环境配置、串口初始化、数据收发、错误处理等核心功能,并提供了完整的代码示例,帮助开发者快速掌握跨平台串口通信技术,适用于智能农业、工业自动化等物联网场景。

weixin_30369041的博客 593

【CATIA的二次开发38】对象Selection交互选择部分方法介绍01

在CATIA V5的VBA开发中,Selection对象是用户交互的核心组件,用于管理用户在图形区域或特征树中的选择操作。Selection 对象是 CATIA VBA 中的中央交互枢纽,充当用户界面与程序逻辑之间的桥梁。它代表当前在图形区域或特征树中被选中的元素集合,是自动化操作的基础。

学习共勉:不积跬步,无以至千里; 不积小流,无以成江海。 1328

Grok-1.5+Ollama企业级本地化部署与合规实践指南

本文详细介绍了Grok-1.5+Ollama企业级本地化部署与合规实践指南,重点分析了本地化部署的成本优势和数据主权保障。通过RTX 4090显卡的硬件选型、Ubuntu 22.04系统优化及部署流程中的关键陷阱规避,为企业提供了高效、安全的AI模型部署方案。特别适合金融、医疗等敏感行业。

weixin_29094539的博客 177

iPhone用户必看:TrollStore巨魔商店在线安装保姆级教程(iOS 14-16.6.1适用)

本文为iOS 14至16.6.1系统的iPhone用户提供了一份详细的TrollStore(巨魔商店)在线安装教程。文章从核心原理、安装前准备讲起,逐步详解了通过Safari浏览器获取安装器、信任企业证书、部署TrollStore及关键后置配置的全过程,并附带了常见问题排错指南,帮助用户安全、高效地实现无需越狱安装第三方应用。

h0i1j2k3l的博客 1891

第一节:初识n8n与下一代工作流自动化

本章介绍了n8n的Fair-code理念与节点式架构,对比了其与Zapier/Make的核心差异,并引导读者在n8n Cloud上完成首次界面导览,建立了工作流自动化的宏观认知。

easeyoo的专栏 97

Lumerical 教程,包含作者个人理解及相关设计案例 (目前共计184篇,持续更新中)

4138。

u011699626的博客 1544

2 硬件工程师笔面试高频知识考点真题解析——电容

本文全面解析了电容在电子电路中的关键应用与技术要点。主要内容包括:1. 电容选型核心要素:介质材质(陶瓷/电解/钽电容等)、容值精度、耐压等级、温度特性、ESR参数等,不同应用场景(滤波/去耦/谐振等)的选型策略。2. 典型电路应用原理:详细阐述去耦电容布局规则、晶振负载电容作用、共射放大电路旁路电容功能,以及RC电路的滤波/定时等应用。3. 特殊问题解决方案:MLCC啸叫机理与对策、寄生电容影响与消除、高速信号线电容使用禁忌等工程实践难题。4. 安全规范要点:X/Y电容的区别与选用、电解/钽电容防反接措施

XU157303764的博客 1547

android 14.0 控制wifi启用禁用功能实现

在14.0的产品rom定制化开发中,在产品开发中,对于功能的开发的功能也是挺多的,而在对于wifi的功能定制需求,有要求需要通过系统属性来控制wifi开关是否可以打开 来控制是否可以连接wifi,打开控制wifi的功能,接下来分析wifi的开启流程来实现该功能的实现

安卓兼职framework和app工程师的博客 1767

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: Out of memory, OOM killer输出信息分析
下一篇: EMMC子系统分析-读写流程
kickxxx
博客等级 码龄16年 587粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值