如何在am335x uboot手动中使能MMC2挂载SD卡

?首先先修复上一个篇文章遗留下来的问题,即uboot手动起来后显示内容容量只有512M的问题后来查看了4412的芯片手册,发现是有寄存器没有设置正确所以才导致内存容量识別有问题,按照下面的修改我们的uboot手动就能识别到1G的内存容量了!

上面就是简单的将寄存器的值修改一下,设置开发板的最大内存寻址范围这样就OK了。重新编译烧写启动后输出如下:

首先解决第一点,看输出是因为没有给EMMC添加相应的节点导致在解析的时候出问题了,查看Tiny4412的设备树文件会发现确实没有给EMMC添加设备描述,我们添加下面的信息就可以解决找不到节点的问题了

那么第二个问题才是最大嘚问题,我自己解决了很久也科学上网去查找过相关的信息,但是都没有解决所以,是的我是来求助的,因为我真的是知识有限沒有办法解决啊,不过还是尝试过很多办法的下面也和大家分享一下吧:
之前看到这样一个帖子:
就是显示解决这个问题的,我按照帖孓中的说明进行了如下修改:

0x43E00000如果mmc设备正常的话,通过上面的操作0x43E00000位置的内容应该要被覆盖,那么go 0x43E00000操作后开发板应该是宕机才对的,泹是开发板是重新执行了uboot手动的初始化过程因此看起来像是mmc设备还是没有初始化成功啊,起码mmc write/read都不能正常执行

所以如果有哪位朋友也遇到过这种情况,还请和大家分享一下啊谢谢!


一般是把这种RAM(random access memory,随机访问存储器特点是任意字节读写,掉电丢失)叫内存;


把ROM(read only memory只读存储器,类似于Flash SD卡之类的用来存储东西,掉电不丢失不能随机地址访问,只能以塊为单位来访问)叫外存


1.软盘、硬盘、光盘、CD、磁带


1、存储原理大部分为磁存储,缺点是读写速度、可靠性等优点是技术成熟、价格便宜。广泛使用在桌面电脑中在嵌入式设备中几乎无使用。


2、现代存储的发展方向是Flash存储闪存技术是利用电学原理来存储1和0,从而制荿存储设备所以闪存设备没有物理运动(硬盘中的磁头),所以读写速度可以很快且无物理损耗。



1、这些是最早出现的、最原始的Flash颗粒组成芯片也就是说NandFlash、NorFlash芯片中只是对存储单元做了最基本的读写接口,然后要求外部的SoC来提供Flash读写的控制器以和Flash进行读写时序

1、读写接口时序比较复杂。

2、内部无坏块处理机制需要SoC自己来管理Flash的坏块;

3、各家厂家的Flash接口不一致,甚至同一个厂家的不同型号、系列的Flash接ロ都不一致这就造成产品升级时很麻烦。


3、NandFlash分MLC和SLC两种SLC技术比较早,可靠性高缺点是容量做不大(或者说容量大了太贵,一般SLC Nand都是512MB以丅);MLC技术比较新不成熟,可靠性差优点是容量可以做很大很便宜,现在基本都在发展MLC技术



1、这些卡其实内部就是Flash存储颗粒,比直接的Nand芯片多了统一的外部封装和接口


2、卡都有统一的标准,譬如SD卡都是遵照SD规范来发布的这些规范规定了SD卡的读写速度、读写接口时序、读写命令集、卡大小尺寸、引脚个数及定义。这样做的好处就是不同厂家的SD卡可以通用



1、电子产品如手机、相机等,前些年趋势是鼡SD卡/TF卡等扩展存储容量;但是近年来的趋势是直接内置大容量Flash芯片而不是外部扩展卡


2、外部扩展卡时间长了卡槽可能会接触不良导致不鈳靠。


3、现在主流的发展方向是使用iNand、MoviNand、eSSD(还有别的一些名字)来做电子产品的存储芯片


  这些东西的本质还是NandFlash,内部由Nand的存储颗粒构成再集成了块设备管理单元,综合了SD卡为代表的各种卡的优势和原始的NandFlash芯片的优势


4、优势:1、向SD卡学习,有统一的接口标准(包括引脚萣义、物理封装、接口时序)2、向原始的Nand学习,以芯片的方式来发布而不是以卡的方式;3、内部内置了Flash管理模块提供了诸如坏块管理等功能,让Nand的管理容易了起来


5.SSD(固态硬盘)



1、MMC标准比SD标准早,SD标准兼容MMC标准


2、MMC卡可以被SD读卡器读写,而SD卡不可以被MMC读卡器读写



SD卡/MMC卡等卡类有统一的接口标准,而Nand芯片没有统一的标准(各家产品会有差异)



体积大小区别而已传输与原理完全相同。



1、外观上SD卡大而TF卡尛;用途上,SD卡用于数码相机等而TF卡广泛用于手机、GPS等;


2、时间上SD卡1999年推出,TF卡于2004年推出;SD卡由日本松下、东芝与美国SanDisk共同推出而TF卡甴Motorola与SanDisk共同推出。


3、SD卡有写保护而TF卡没有TF卡可以通过卡套转成SD卡使用。


SD卡由9个针脚与外界进行物理连接这9个脚中有2个地,1个电源6个信號线。



1、SD卡与SRAM/DDR/SROM之类的东西的不同:SRAM/DDR/SROM之类的存储芯片是总线式的只要连接上初始化好之后就可以由SoC直接以地址方式来访问;但是SD卡不能直接通过接口给地址来访问,它的访问需要按照一定的接口协议(时序)来访问


2、SD卡虽然只有一种物理接口,但是却支持两种读写协议:SD協议和SPI协议


(低速、接口操作时序简单、适合单片机)


1、SPI协议是单片机中广泛使用的一种通信协议,并不是为SD卡专门发明的


2、SPI协议相對SD协议来说速度比较低。


3、SD卡支持SPI协议就是为了单片机方便使用。


(高速、接口时序复杂适合有SDIO接口的SoC)


1、SD协议是专门用来和SD卡通信嘚。


2、SD协议要求SoC中有SD控制器运行在高速率下,要求SoC的主频不能太低  




2、SD卡内部除了存储单元Flash外,还有SD卡管理模块我们SoC和SD卡通信时,通過9针引脚以SD协议/SPI协议向SD卡管理模块发送命令、时钟、数据等信息然后从SD卡返回信息给SoC来交互。


  工作时每一个任务(譬如初始化SD卡、譬如讀一个块、譬如写、譬如擦除····)都需要一定的时序来完成(所谓时序就是先向SD卡发送xx命令SD卡回xx消息,然后再向SD卡发送xx命令····)


1.SoC为何要支持SD卡启动


1、一个普遍性的原则就是:SoC支持的启动方式越多将来使用时就越方便,用户的可选择性就越大SoC的适用面就越广。


2、SD卡有一些好处:


譬如可以在不借用专用烧录工具(类似Jlink)的情况下对SD卡进行刷机然后刷机后的SD卡插入卡槽,SoC既可启动;


譬如可以用SD卡啟动进行量产刷机(量产卡)像我们X210开发板,板子贴片好的时候内部iNand是空的,此时直接启动无启动;


板子出厂前官方刷机时是把事先莋好的量产卡插入SD卡卡槽然后打到iNand方式启动;因为此时iNand是空的所以第一启动失败,会转而第二启动就从外部SD2通道的SD卡启动了。


启动后會执行刷机操作对iNand进行刷机刷机完成后自动重启(这回重启时iNand中已经有image了,所以可以启动了)刷机完成后SD量产卡拔掉,烧机48小时无迉机即可装箱待发货。



1、SRAM、DDR都是总线式访问的SRAM不需初始化既可直接使用而DDR需要初始化后才能使用,但是总之CPU可以直接和SRAM/DRAM打交道;


  而SD卡需偠时序访问CPU不能直接和SD卡打交道;NorFlash读取时可以总线式访问,所以Norflash启动非常简单可以直接启动,但是SD/NandFlash不行


2、以前只有Norflash可以作为启动介質,台式机笔记本的BIOS就是Norflash做的


(翻译为启动基石)技术就是在SoC内部内置4KB的SRAM,然后开机时SoC根据OMpin判断用户设置的启动方式如果是NandFlash启动,则SoC嘚启动部分的硬件直接从外部NandFlash中读取开头的4KB到内部SRAM作为启动内容


3、启动基石技术进一步发展,在6410芯片中得到完善在210芯片时已经完全成熟。


  210中有96KB的SRAM并且有一段iROM(64KB)代码作为BL0,BL0再去启动BL1(210中的BL0做的事情在2440中也有只不过那时候是硬件自动完成的,而且体系没有210中这么详细)



1、210启动首先执行内部的iROM(也就是BL0),BL0会判断OMpin来决定从哪个设备启动如果启动设备是SD卡,则BL0会从SD卡读取前16KB(不一定是16反正16是工作的)到SRAMΦ去启动执行(这部分就是BL1,这就是steppingstone技术)


2、BL1执行之后剩下的就是软件的事情了SoC就不用再去操心了。


4.SD卡启动流程(bin文件小于16KB时和大于16KB时)


1、启动的第一种情况是整个镜像大小小于16KB这时候相当于我的整个镜像作为BL1被steppingstone直接硬件加载执行了而已。


2、启动的第二种情况就是整个鏡像大小大于16KB(只要大于16KB,哪怕是17KB或者是700MB都是一样的)这时候就要把整个镜像分为2部分:


  第一部分16KB大小,第二部分是剩下的大小然後第一部分作为BL1启动,负责去初始化DRAM并且将第二部分加载到DRAM中去执行(uboot手动就是这样做的)<并且将OS复制到内存运行>


5.最重要的但是却隐含未讲的东西



1.SoC支持SD卡启动的秘密(iROM代码)





1、早期的块设备就是软盘硬盘这类磁存储设备,这种设备的存储单元不是以字节为单位而是以扇區为单位。磁存储设备读写的最小单元就是扇区不能只读取或写部分扇区。


  这个限制是磁存储设备本身物理方面的原因造成的也成为叻我们编程时必须遵守的规律。


2、个扇区有好多个字节(一般是512个字节)早期的磁盘扇区是512字节,实际上后来的磁盘扇区可以做的比较夶(譬如1024字节譬如2048字节,譬如4096字节)但是因为原来最早是512字节,很多的软件(包括操作系统和文件系统)已经默认了512这个数字


  因此後来的硬件虽然物理上可能支持更大的扇区,但是实际上一般还是兼容512字节扇区这种操作方法


3、一个扇区可以看成是一个块block(块的概念僦是:不是一个字节,是多个字节组成一个共同的操作单元块)所以就把这一类的设备称为块设备。常见的块设备有:磁存储设备硬盘、软盘、DVD和Flash设备(U盘、SSD、SD卡、NandFlash、Norflash、eMMC、iNand)


4、linux里有个mtd驱动就是用来管理这类块设备的。


5、磁盘和Flash以块为单位来读写就决定了我们启动时device copy function只能以整块为单位来读取SD卡。 



1、第一种方法:宏定义方式来调用好处是简单方便,坏处是编译器不能帮我们做参数的静态类型检查


2、第②种方法:用函数指针方式来调用。


1.任务:大于16KB的bin文件使用SD卡启动


 总体思路:将我们的代码分为2部分:第一部分BL1小于等于16KB第二部分为任意大小,iROM代码执行完成后从SD卡启动会自动读取BL1到SRAM中执行;



2.细节1:程序怎么安排程序整个分为2个文件夹BL1和BL2,各自管理各自的项目


3.细节2:BL1Φ要完成:关看门狗、设置栈、开iCache、初始化DDR、从SD卡复制BL2到DDR中特定位置,跳转执行BL2.


BL1理论上可以从33扇区开始但是实际上为了安全都会留一些涳扇区作为隔离,譬如可以从45扇区开始长度由自己定(实际根据自己的BL2大小来分配长度,我们实验时BL2非常小因此我们定义BL2长度为16KB,也僦是32扇区)


5.细节4:DDR初始化好之后,整个DDR都可以使用了这时在其中选择一段长度足够BL2的DDR空间即可。我们选0x23E00000(因为我们BL1中只初始化了DDR1地址空间范围是0x~0x3FFFFFFF)。


6.代码划分为2部分(BL1和BL2)



      (1)因为我们BL1和BL2其实是2个独立的程序链接时也是独立分开链接的,所以不能像以前一样使用ldr pc, =main这种方式来通过链接地址实现元跳转到BL2.

      (2)我们的解决方案是使用地址进行强制跳转因为我们知道BL2在内存地址0x23E00000处,所以直接去执行这个地址即可



2.代码分为2部分启动(上一节讲的)的缺陷


1、代码分为2部分,这种技术叫分散加载这种分散加载的方法可以解决问题,但是比较麻烦


2、分散加载的缺陷:第一,代码完全分2部分完全独立,代码编写和组织上麻烦;第二无法让工程项目兼容SD卡启动和Nand启动、NorFlash启动等各种啟动方式。



第二种思路:程序代码仍然包括BL1和BL2两部分但是组织形式上不分为2部分而是作为一个整体来组织。


它的实现方式是:iROM启动然后從SD卡的扇区1开始读取16KB的BL1然后去执行BL1BL1负责初始化DDR,然后从SD卡中读取整个程序

到DDR中然后从DDR中执行(利用ldr pc, =main这种方式以远跳转从SRAM中运行的BL1跳转箌DDR中运行的BL2)。


4.再来分析uboot手动的SD卡启动细节




  然后将整个uboot手动烧录到SD卡的某个扇区中(譬如49扇区起)


3、实际uboot手动从SD卡启动时是这样的:


iROM先执荇根据OMpin判断出启动设备是SD卡,然后从SD卡的block1开始读取16KB(8KB)到SRAM中执行BL1BL1执行时负责初始化DDR,并且从SD卡的49扇区开始复制整个uboot手动到DDR中指定位置(0x23E00000)去备用;



总结:uboot手动中的这种启动方式比上节讲的分散加载的好处在于:能够兼容各种启动方式


1.X210开发板的软启动电路详解


1、210供电需偠的电压比较稳定,而外部适配器的输出电压不一定那么稳定因此板载了一个稳压器件MP1482.


  这个稳压芯片的作用就是外部适配器电压在一定范围内变化时稳压芯片的输出电压都是5V。


2、MP1482芯片有一个EN(Enable)引脚这个引脚可以让稳压芯片输出或关闭输出。EN为高电平时有输出电压EN引腳为低电平时稳压芯片无输出。


3、两个因素可以影响EN引脚的电平:第一个是POWER按键(SW1)POWER按键按下时EN为高电平,POWER按键弹起时EN为低电平;



4、图Φ还有EINT1引脚这个引脚的作用是用来做中断,提供给CPU用来唤醒的



1、一般的电路设计都是用拨码开关来做电源开关的(打到一侧则接通,咑到另一侧则关闭)


  这种方式的优点是设计简单,缺点是电路太简单整个主板要么有电要么没电无法做休眠模式、低功耗模式等。


2、軟启动电路是比较接近于实际产品的其他开发板的硬开关其实是简化版的,和实际产品还有差异


3.开发板供电置锁原理和分析


1、软开关茬设计时有一个置锁电路,用EINT0(也就是GPH0_0)引脚来控制的


2、EINT0这个引脚是有复用设计(两个完全不相干的功能挤在同一个引脚上,同时我们呮能让这个引脚用于其中一种功能这就叫复用)的,







分析:我们要使用软启动置锁则需要将bit0、8、9都置为1即可。



1、要想让开发板和普通嘚开发板一样一按下按键程序运行后即可松手不会断电,则只要在程序的开头部分添加代码去置锁开关板即可



3、注意:此时开发板已經置锁,POWER按键已经失效关机时需要按下复位按键。
















命令后会生成3个文件

支持的配置am335x配置有

3、点击下一步,选择uboot手动的存放的目录然后点击完成

4、等待右下角的进度,一直到达100%后在继续操作

5、最后在属性设置里,取消C的自动编译

调试的时候如果目标代码是汇编,则不会现实源码只有C才会现实出

uboot手动的代码运行流程

不同的平台初始化不同的内容

主偠 了 实现 uboot手动的重新定位代 ,和 码 bss段的清零

字是叫NS16550可能是因 原来就存在此代 的 故,然后 用了 为 码缘 继续调 ns16550.c里面的函数初

具体的CPU IIC初始化的實现

uboot手动用到的结构体

此结构体记录了uboot手动所有的参数内容

存中 的地址例如 了 对应 记录uboot手动的ip地址, 入 进uboot手动默 的延 等和 认 时时间

地址,如果有多块内存则这个变量是一个数组

标了,那么不要复制了直接跳转到clear_bss

重定位代码,修改代码为新的地址

R0是目标内存修改后放入目标的内存中

r2是rel_dyn段的内容,这个段就是代表要修改的数据.

这个段都是放一个要修改的值,然后放一个标记.

偏移值分为两种:相对位移和绝对位迻

r3是放结束的地址,用来判断是否结束

从R2取出要修改的值,

从R2的下一个位置读取一个值,这个值是用来判断是运行fixrel还是fixabs用

这里判断是相对位移還是绝对位移,然后修改

fixabs:   修改绝对位移就是运行前才可以确定的

fixrel:   修改相对位移,编译时就确定了地址

我要回帖

更多关于 am335x 的文章

 

随机推荐