uboot源码——mmc驱动分析

以下内容源于朱有鹏《物联网大讲坛》课程的学习,以及博客http://www.cnblogs.com/biaohc/p/6409197.html的学习整理,如有侵权,请告知删除。


一、uboot与linux驱动

1、uboot是裸机程序

  • 狭义的驱动的概念:操作系统中用来具体操控硬件的那部分代码叫驱动
  • 裸机中没有驱动的概念,因为没有操作系统。
  • 裸机程序是直接操控硬件的,而操作系统中则是通过驱动来操控硬件。两者的本质区别是分层

2、uboot的虚拟地址对硬件操作的影响

(1)操作系统下,MMU是开启的,即linux驱动使用的都是虚拟地址。纯裸机程序不会开启MMU,全部使用物理地址。

  • 这是裸机下和驱动中操控硬件的一个重要区别。

(2)uboot早期也是纯物理地址工作,但是现在的uboot开启了MMU做了虚拟地址映射。

  • 查uboot中的虚拟地址映射表,发现除了0x30000000-0x3FFFFFFF映射到了0xC0000000-0xCFFFFFFF之外,其余的虚拟地址空间全是原样映射的。
  • 我们驱动中主要是操控硬件寄存器,而S5PV210的SFR都在0xExxxxxx地址空间,因此驱动中不必考虑虚拟地址

3、uboot移植了linux驱动

(1)linux的驱动是模块化设计。

  • linux驱动本身和linux内核不是强耦合的,这是linux驱动可以被uboot移植的关键。

(2)uboot移植了linux驱动源代码。

  • uboot是从源代码级别去移植linux驱动的,这就是linux系统的开源性。

(3)uboot中的硬件驱动比linux简单。

  • linux驱动本身有更复杂的框架,需要实现更多的附带功能,而uboot本质上只是个裸机程序,uboot移植linux驱动时只是借用了linux驱动的一部分而已。

二、iNand/SD驱动解析


1、MMC驱动的初始化,是在start_armboot函数中,调用的是mmc_initialize函数



下面看一下mmc_initialize函数


(1)函数位于uboot/drivers/mmc/mmc.c。

(2)此函数主要是初始化开发板上MMC系统。

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

(3)mmc_devices,链表全局变量,用来记录系统中所有已经注册的SD/iNand设备。




  • 向系统中插入一个SD卡/iNand设备,则系统驱动就会向mmc_devices链表中插入一个数据结构表示这个设备。

(4)struct mmc类型的结构体指针


  • 这个struct mmc类型的结构体非常重要,我们说的驱动主要就是构建这个结构体;
  • 在这个结构体中构建了一些列变量、函数指针等;
  • 这些变量记录了mmc的一些信息,函数指针所指向的函数是用来向sd卡中发送命令、或者发送数据、直接操作最底层的特殊功能寄存器


下面看一下cpu_mmc_init函数

(1)函数位于uboot/cpu/s5pc11x/cpu.c中,通过调用3个函数来完成。

(2)setup_hsmmc_clock,在uboot/cpu/s5pc11x/setup_hsmmc.c中,用来初始化SoC中MMC控制器中的时钟部分的。

(3)setup_hsmmc_cfg_gpio,在uboot/cpu/s5pc11x/setup_hsmmc.c中,用来配置SoC中MMC控制器相关的GPIO的。


下面看一下setup_hsmmc_clock函数,主要是选择时钟源、分频



下面看一下setup_hsmmc_cfg_gpio函数,主要是初始化相关的GPIO




下面看一下smdk_s3c_hsmmc_init函数


(1)函数位于:uboot/drivers/mmc/s3c_hsmmc.c中。

(2)函数内部通过宏定义USE_MMCx来决定是否调用s3c_hsmmc_initialize来进行具体的初始化操作。


下面看一下s3c_hsmmc_initialize函数


(1)函数位于:uboot/drivers/mmc/s3c_hsmmc.c中。

(2)定义并且实例化一个struct mmc类型的对象

  • 即定义了一个指针,给指针分配内存,然后填充它的各种成员,最后调用mmc_register函数来向驱动框架注册这个mmc设备驱动。

(3)mmc_register功能是进行mmc设备的注册,注册方法其实就是将当前这个struct mmc使用链表连接到mmc_devices这个全局变量中去。

(4)在X210中定义了USE_MMC0和USE_MMC2

  • 因此在我们的uboot初始化时,会调用2次s3c_hsmmc_initialize函数,传递参数分别是0和2;
  • 因此完成之后系统中会注册上2个mmc设备,表示当前系统中有2个mmc通道在工作。平常我们说的通道0和通道2?

(5)真正的操作寄存器的函数是s3c_hsmmc_send_command、s3c_hsmmc_set_ios、s3c_hsmmc_init;

  • 发送命令、发送数据、初始化三个函数;
  • 这三个函数是最底层的、直接操作GPIO进而特殊功能寄存器的函数;
  • 这三个函数以及一些变量被封装在struct mmc结构体中,因而操作系统对mmc设备进行操作的时候,到封装以后的这个结构体中进行操作即可;

(6)至此cpu_mmc_init函数分析完成。


下面看一下find_mmc_device函数


(1)函数位于uboot/drivers/mmc/mmc.c中。

(2)通过mmc设备编号来在系统中查找对应的mmc设备(struct mmc的对象,根据上面分析系统中有2个,编号分别是0和2)。

  • 通过遍历mmc_devices链表,去依次寻找系统中注册的mmc设备,然后对比其设备编号和我们当前要查找的设备编号,如果相同则就找到了要找的设备。
  • 找到了后调用mmc_init函数来初始化它。

下面看一下mmc_init函数


(1)函数位于:drivers/mmc/mmc.c中。

(2)分析猜测这个函数应该要进行mmc卡的初始化了(前面已经进行了SoC端控制器的初始化)

(3)函数的调用关系为:

mmc_init

mmc_go_idle

mmc_send_cmd

mmc_send_if_cond

mmc_send_cmd……

(4)分析可知,mmc_init函数通过依次向mmc卡发送命令码(CMD0、CMD2那些)来初始化SD卡/iNand内部的控制器,以达到初始化SD卡的目的。

  • 调用struct mmc 中的函数进行了一些时序操作

(5)send_cmd函数的细节找不到……


2、总结

(1)至此整个MMC系统初始化结束。

(2)整个MMC系统初始化分为2大部分

  • SoC这一端的MMC控制器的初始化,SD卡这一端卡本身的初始化。
  • 前一步主要是在cpu_mmc_init函数中完成,后一部分主要是在mmc_init函数中完成。

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

(4)顺着操作追下去,到了mmc_send_cmd函数处就断了,真正的向SD卡发送命令的硬件操作的函数找不到。这就是学习驱动的麻烦之处。

(6)struct mmc结构体是关键。

  • 上述两部分初始化之间用mmc结构体来链接的;
  • 初始化完了后对mmc卡的常规读写操作也是通过mmc结构体来链接的。

三、关于驱动的理解

1、驱动的关键数据结构

(1)驱动的设计中有一个关键数据结构。譬如MMC驱动的结构体就是struct mmc。

  • 这些结构体中包含一些变量和一些函数指针,变量用来记录驱动相关的一些属性,函数指针用来记录驱动相关的操作方法。
  • 这些变量和函数指针加起来就构成了驱动。驱动就被抽象为这个结构体

(2)一个驱动工作时主要分两部分

  • 驱动构建(构建一个struct mmc然后填充它);
  • 驱动运行时(调用这些函数指针指针的函数和变量);

2、分离思想

(1)分离思想,即在驱动中将操作方法和数据分开。

(2)操作方法就是函数,数据就是变量。

  • 所谓操作方法和数据分离的意思就是,在不同的地方来存储和管理驱动的操作方法和变量,这样的优势就是驱动便于移植。

3、分层思想

(1)分层思想,是指一个整个的驱动分为好多个层次。

  • 简单理解就是驱动分为很多个源文件,放在很多个文件夹中
  • 譬如本课程讲的mmc的驱动涉及到drivers/mmc下面的2个文件、cpu/s5pc11x下的好几个文件。

(2)以mmc驱动为例来分析各个文件的作用

uboot/drivers/mmc/mmc.c

  • 本文件是和MMC卡操作有关的方法,譬如MMC卡设置空闲状态的、卡读写数据等。
  • 本文件中并没有具体的硬件操作函数,操作最终指向的是struct mmc结构体中的函数指针,这些函数指针是在驱动构建的时候和真正硬件操作的函数挂接的(真正的硬件操作的函数在别的文件中)。

uboot/drivers/mmc/s3c_hsmmc.c:

  • 本文件是SoC内部MMC控制器的硬件操作的方法,譬如向SD卡发送命令的函数(s3c_hsmmc_send_command),譬如和SD卡读写数据的函数(s3c_hsmmc_set_ios)
  • 这些函数是具体操作硬件的函数,即mmc.c中需要的那些硬件操作函数。这些函数在mmc驱动初始化构建时(s3c_hsmmc_initialize函数中)和struct mmc挂接起来。


由上分析可知

  • mmc.c和s3c_hsmmc.c构成了一个分层,mmc.c中调用了s3c_hsmmc.中的函数,所以mmc.c在上层,s3c_hsmmc.c在下层。
  • mmc.c中不涉及具体硬件的操作,s3c_hsmmc.c中不涉及驱动工程时的时序操作。
  • 如果我们要把这一套mmc驱动移植到别的SoC上,那么mmc.c就不用动,修改s3c_hsmmc.c即可;
  • 如果SoC没变但是SD卡升级了,这时候只需要更换mmc.c,不需要更换s3c_hsmm。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RDIFramework.NET(.NET快速开发框架) 答客户问(2014-02-23)

1、框架的部署安装,服务器端和客户端 答:开发版以上版本支持SOA模式,也即真正的面向服务端的模式,在实际使用过程中,可根据项目的实际需要,来选择性的进行部署(直连模式或SOA模式)&a…

I2C通信——I2C通信的基础介绍

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除 。 参考博客 SPI、I2C、UART(即串口)三种串行总线详解_天糊土的博客-CSDN博客_串口总线 s5pv210 I2C通信详解 - biaohc - 博客园 嵌入式常用技术概览之IIC(I2C)_C_XianRen的博…

IBM SOA[ESB,BPM,Portal等]基础架构图解

最近公司对众多的异构系统进行SOA化,产品选型为IBM的Websphere系列产品的WMB,BPM,Portal,LDAP等技术,根据具体的描述,连猜带蒙的画了个系统协作图,有不对的地方欢迎大家拍砖....谢谢。 SOA详细技…

css3图标悬停导航菜单

纯css3制作的图标悬停导航菜单,包含9中不同的悬停风格,干净大气。转载于:https://blog.51cto.com/jimanyu/1362823

I2C通信——S5PV210的I2C通信简单案例

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 参考内容 I2C子系统详解3——I2C总线驱动层代码分析_天糊土的博客-CSDN博客 一、S5PV210的I2C控制器 1、为什么需要控制器? 通信双方通过时序协调工作,但是时序比较复杂而…

POJ 2718

题意:给出最多10个数字,将它们划分为两个整数,求差异值最小的值(除非只有一位数,否则不允许出现先导0) 题解:很显然如果总共有n个数,必然有一个整数长n/2,另一个长n-n/2,…

HDUOJ---1879 继续畅通工程

继续畅通工程 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11473 Accepted Submission(s): 5026 Problem Description省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一…

动态载入树 (ASP+数据库)

ASPACCESS 在数据量达100万条记录下&#xff0c;载入速度仍然惊人.... // 网上转载. 忘了作者... : ) //********************** Index.asp ************************// 1<%LANGUAGE"VBSCRIPT"CODEPAGE"936"%>2<%OptionExplicit%>3<htm…

ADC——S5PV210的ADC的理论与操作

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 s5pv210 AD转换 - biaohc - 博客园 一、ADC的相关概念 1、量程&#xff08;模拟量的输入范围&#xff09; ADC只能输入电压信号&#xff0c;其他种类的模拟信号要经过传感器的转换&#x…

【洛谷 2661】信息传递

题目描述 有 nn 个同学&#xff08;编号为 11 到 nn &#xff09;正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象&#xff0c;其中&#xff0c;编号为 ii 的同学的信息传递对象是编号为 T_iTi​ 的同学。 游戏开始时&#xff0c;每人都只知道自己的生日。之…

kernel移植——从三星官方内核开始移植

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 一、内核移植初体验 1、获取三星官方的内核源码包 三星SMDKV210开发板附带的光盘里有内核源码包&#xff1a;下载地址。 2、构建移植环境 &#xff08;1&#xff09;Windows下建立SI工程&…

Android中实时视频传输(摄像头实时视频传输)解决方案二

为什么80%的码农都做不了架构师&#xff1f;>>> 1、使用FFMpeg进行视频采集&#xff0c;使用Live555进行RTP传输&#xff0c;使用VideoView进行播放。 csdn提到&#xff1a;重载FrameSource&#xff0c;写一个服务类&#xff0c;可以从FrameSource的派生类读取帧数…

定时器——S5PV210定时器的理论与操作

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、定时器简介 1、定时器的含义 定时器作为SoC的外设&#xff0c;主要用来实现定时执行代码的功能&#xff0c;它相对SoC而言&#xff0c;就像闹钟相对于人的意义一样。定时器内部的计数器每隔一个…

uboot的移植——DM9000移植的理论基础

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权请告知删除。 一、网卡相关的基本知识 1、DM9000网卡芯片和SoC的连接 如上图所示&#xff0c;DM9000网卡芯片是通过SROM总线接口&#xff0c;或者说SROM控制器接入SoC的。下面分别介绍SROM控制器、DM9000网卡芯片的相关…

javascript深入浅出

第一章 数据类型 1&#xff0c;六种数据类型&#xff1a;原始类型&#xff08;number&#xff0c;string&#xff0c;boolean&#xff0c;null&#xff0c;undefined&#xff09; object对象&#xff08;Function Array Date&#xff09; 2&#xff0c;隐式转换&#xff1a;Na…

网络通信基础常识

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 1、网络通信属于进程间通信 进程间通信的一种方法是使用套接字socket&#xff0c;网络通信其实就是位于网络中不同主机上面的2个进程之间的通信。 2、网络通信的层次 网络通信的层次&#xff0c;即…

Android NDK工程创建与编译运行

首发地址&#xff1a;http://www.eoeandroid.com/thread-201993-1-1.html一、 工程创建1. 创建一个Android工程配置好开发环境并加载好对应版本sdk后&#xff0c;选择菜单File->New-> Project创建工程&#xff0c;工程类型选择Android Project&#xff0c;如下图所示&…

[Quatsch]Quantum Or Optics

小生预言&#xff0c;鉴于目前CG产业中学术界与生产界之间的差异&#xff0c;未来必将有一门独立的学科&#xff0c;专门用于研究自然界的材质特性与表现&#xff0c;从此艺术界与学术界将呈现完美之统一&#xff0c;应该先在MIT或者Cornell出现。本人姑且将这门学科命名为“应…

C#事件 的讲解

一、事件的本质事件是软件系统里的两个子系统之间&#xff0c;或者两个模块之间&#xff0c;或者两个对象之间发送消息&#xff0c;并处理消息的过程。在面向对象的世界里&#xff0c;就可以统一认为是两个对象之间的行为。两个对象之间发送的这种消息&#xff0c;对发送方来讲…

phpMyAdmin密码设置

2019独角兽企业重金招聘Python工程师标准>>> 在使用phpMyAdmin操作数据库时&#xff0c;首先需要设置mysql的root用户的密码。具体操作参考前一篇博文。设置完mysql的root密码之后&#xff0c;需要对phpMyAdmin的登录进行一些配置。 未经配置的phpMyAdmin很不安全&a…