uboot移植之uboot中的SD卡驱动解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介:

1:地址对硬件操作的影响

    (1)操作系统(指的是linux)下MMU肯定是开启的,也就是说linux驱动中肯定都使用的是虚拟地址。而纯裸机程序中根本不会开MMU,全部使用的是物理地址。这是裸机下和驱动中操控硬件的一个重要区别。

    (2)uboot早期也是纯物理地址工作的,但是现在的uboot开启了MMU做了虚拟地址映射,这个东西驱动也必须考虑。查uboot中的虚拟地址映射表,发现210开发板里面,除了0x30000000-0x3FFFFFFF映射到了0xC0000000-0xCFFFFFFF之外,其余的虚拟地址空间全是原样映射的。而我们驱动中主要是操控硬件寄存器,而S5PV210的SFR都在0xExxxxxx地址空间,因此驱动中不必考虑虚拟地址。

2:从start_armboot开始

这里的();就是SD卡的初始化函数,这个函数的作用就是初始化开发板上MMC系统。MMC系统的初始化应该包含这么几部分:SoC里的MMC控制器初始化

(MMC系统时钟的初始化、SFR初始化)、SoC里MMC相关的GPIO的初始化、SD卡/iNand芯片的初始化

3:mmc_initialize()函数分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int  mmc_initialize(bd_t *bis)
{
struct  mmc *mmc;
int  err;
INIT_LIST_HEAD(&mmc_devices);     //初始化内核链表,next指针和prev指针都指向自身
cur_dev_num = 0; // SD 卡的插槽,我们这里有4个插槽
if  (board_mmc_init(bis) < 0)
cpu_mmc_init(bis);    //时钟初始化  GPIO初始化,但是目前都是初始化SoC内部,并没有
               //涉及外部的SD卡的初始化
#if defined(DEBUG_S3C_HSMMC)
print_mmc_devices( ',' );
#endif
#ifdef CONFIG_CHECK_X210CV3
mmc = find_mmc_device(1); //lqm
#else
mmc = find_mmc_device(0);
#endif
if  (mmc) {
err = mmc_init(mmc);
if  (err)
err = mmc_init(mmc);
if  (err) {
printf ( "Card init fail!\n" );
return  err;
}
}
printf ( "%ldMB\n" , (mmc->capacity/(1024*1024/(1<<9))));
return  0;
}

    (1)INIT_LIST_HEAD(&mmc_devices);

内核链表的初始化函数,内核链表在初始化的时候,链表的next指针和prev指针都是指向其自身。mmc_devices链表全局变量,用来记录系统中所有已经注册的SD/iNand设备。所以向系统中插入一个SD卡/iNand设备,则系统驱动就会向mmc_devices链表中插入一个数据结构表示这个设备。

    (2)if (board_mmc_init(bis) < 0)

查看代码可知,board_mmc_init(),其实是__def_mmc_init()函数的别名,而__def_mmc_init()函数的返回值固定是-1,所以if判断成立,执行cpu_mmc_init()函数。

    (3)cpu_mmc_init()函数

cpu_mmc_init()函数在uboot/cpu/s5pc11x/cpu.c中,

int cpu_mmc_init(bd_t *bis)

{

#ifdef CONFIG_S3C_HSMMC

setup_hsmmc_clock();

setup_hsmmc_cfg_gpio();

return smdk_s3c_hsmmc_init();

#else

return 0;

#endif

}

setup_hsmmc_clock():在uboot/cpu/s5pc11x/setup_hsmmc.c中。hsmmc高速mmc,clock时钟,所以这个函数应该是用于mmc控制器的时钟初始化。里面是通过宏定义来选择配置哪些通道的时钟(通过MPLL分频得到)。x210选择的是通道0和通道2(SD卡)

setup_hsmmc_cfg_gpio():MMC控制器IO引脚的设置。在在uboot/cpu/s5pc11x/setup_hsmmc.c中中

smdk_s3c_hsmmc_init():uboot/drivers/mmc/s3c_hsmmc.c中。该函数里面主要调用s3c_hsmmc_initialize(int channel)函数,参数channel表示的是MMC的通道。

至此,cpu_mmc_init()函数分析结束,继续分析mmc_initialize()函数。

    (4) find_mmc_device(0)函数

find_mmc_device()uboot/drivers/mmc/mmc.c中,这个函数其实就是通过mmc设备编号来在系统中查找对应的mmc设备(struct mmc的对象,根据上面分析系统中有2个,编号分别是0和2)。函数工作原理就是通过遍历mmc_devices链表,去依次寻找系统中注册的mmc设备,然后对比其设备编号和我们当前要查找的设备编号,如果相同则就找到了要找的设备。找到了后调用mmc_init函数来初始化它。

    (5)mmc_init()函数

mmc_init()函数在drivers/mmc/mmc.c中。这个函数的主要作用是进行mmc卡的初始化。mmc_init函数内部就是依次通过向mmc卡发送命令码(CMD0、CMD2那些)来初始化SD卡/iNand内部的控制器,以达到初始化SD卡的目的。


4:总结

    (1)整个MMC系统初始化分为2大部分:SoC这一端的MMC控制器的初始化,SD卡这一端卡本身的初始化。前一步主要是在cpu_mmc_init函数中完成,后一部分主要是在mmc_init函数中完成。

    (2)整个初始化完成后去使用sd卡/iNand时,操作方法和mmc_init函数中初始化SD卡的操作一样的方式。读写sd卡时也是通过总线向SD卡发送命令、读取/写入数据来完成的。

    (3)struct mmc结构体是关键。两部分初始化之间用mmc结构体来链接的,初始化完了后对mmc卡的常规读写操作也是通过mmc结构体来链接的。



本文转自 菜鸟养成记 51CTO博客,原文链接:http://blog.51cto.com/11674570/1927550
相关文章
|
8月前
|
消息中间件 Cloud Native Java
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
|
存储 边缘计算 数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
400 0
|
3月前
|
Java 关系型数据库 MySQL
【编程基础知识】Eclipse连接MySQL 8.0时的JDK版本和驱动问题全解析
本文详细解析了在使用Eclipse连接MySQL 8.0时常见的JDK版本不兼容、驱动类错误和时区设置问题,并提供了清晰的解决方案。通过正确配置JDK版本、选择合适的驱动类和设置时区,确保Java应用能够顺利连接MySQL 8.0。
288 1
|
5月前
|
消息中间件 Java RocketMQ
微服务架构师的福音:深度解析Spring Cloud RocketMQ,打造高可靠消息驱动系统的不二之选!
【8月更文挑战第29天】Spring Cloud RocketMQ结合了Spring Cloud生态与RocketMQ消息中间件的优势,简化了RocketMQ在微服务中的集成,使开发者能更专注业务逻辑。通过配置依赖和连接信息,可轻松搭建消息生产和消费流程,支持消息过滤、转换及分布式事务等功能,确保微服务间解耦的同时,提升了系统的稳定性和效率。掌握其应用,有助于构建复杂分布式系统。
78 0
|
6月前
|
自然语言处理 Java 测试技术
Java中的行为驱动开发(BDD)方法论解析
Java中的行为驱动开发(BDD)方法论解析
|
7月前
|
网络协议 Linux 编译器
【原创】EtherCAT主站IgH解析(二)-- 如何将Igh移植到Linux/Windows/RTOS等多操作系统移植指南
EtherCAT主站方案对比:商业的如Acontis、TwinCAT3和开源的igh、SOEM。SOEM易移植但功能和实时性不足,适合简单应用;igh功能强大,实时性能优秀,基于内核态,适合复杂场景。igh能移植到其他RTOS,但需克服多任务无调度的挑战。依赖操作系统服务如定时器、内存分配,适合Linux内核,但移植到裸机复杂。
337 0
|
8月前
|
人工智能 安全 大数据
开源软件全景解析:驱动技术创新与行业革新的力量
开源软件全景解析:驱动技术创新与行业革新的力量
565 0
开源软件全景解析:驱动技术创新与行业革新的力量
|
8月前
|
存储 机器学习/深度学习 数据挖掘
数据仓库与数据湖:解析数据驱动的未来
在数字化时代,数据成为企业决策的核心资源。本文将深入探讨数据仓库和数据湖的概念、特点以及应用场景,分析其在实现数据驱动决策过程中的重要性和优势,并展望数据驱动的未来发展趋势。
213 5
|
存储 Linux Go
Docker 存储驱动解析:选择最适合你的存储方案
Docker 存储驱动解析:选择最适合你的存储方案
218 0
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
257 1

推荐镜像

更多