网站开发洲际,马鞍山网站制作公司,网站后台图片模板,开发网站软件X-007-UBOOT-DDR的初始化(Bubblegum-96平台)作者#xff1a;wowo 发布于#xff1a;2016-7-21 22:47分类#xff1a;X Project1. 前言到目前为止#xff0c;“X Project”在Bubblegum-96平台上的代码#xff0c;都是运行在SRAM中。由于SRAM的size很小(最多也就96KB)#…X-007-UBOOT-DDR的初始化(Bubblegum-96平台)作者wowo 发布于2016-7-21 22:47分类X Project1. 前言到目前为止“X Project”在Bubblegum-96平台上的代码都是运行在SRAM中。由于SRAM的size很小(最多也就96KB)如果要做更多的事情就必须把DDR跑起来。不过关于Bubblegum-96平台的DDR driver我和codingbelief同学折腾了很久试图找出一个最佳的方法给大家呈现出DDR driver的开发方法和开发步骤。最终受限于“资源”的短缺还是失败了。根据Bubblegum-96公开的资料只知道它包含了一个2GB的、单bank的LPDDR除此之外找不到任何技术有关的细节如LPDDR的datasheet、S900 DDR controller的说明、DDR时钟的配置等等。没有这些东西我们根本无法完成DDR的配置更不用说以此介绍、分析DDR driver了。但是虽然困难重重“X Project”还是要进行下去既然常规方法走不通我们就采用一些非常规的手段无论如何还是能把DDR成功的初始化起来的。由于是非常规手段当然就无法开源也无法给大家讲解了。因此本文关于DDR的技术细节不多主要目的是结合DDR的初始化进一步介绍嵌入式linux开发的基本过程包括如下知识点嵌入式Linux的启动过程。u-boot SPL的使用场景。u-boot启动过程中DDR初始化的流程。2. Bubblegum-96的启动过程由于RAM资源的短缺嵌入式系统的启动过程是相当繁琐的以Bubblegum-96为例CPU启动时只有96KB的SRAM可用。CPU启动时ROM code只会从外部存储介质中(NAND、MMC、SD等)拷贝并执行2KB的代码。首先与上面两个条件Bubblegum-96的启动代码必须具备如下的特点。1)软件从外部存储介质加载并执行的时候a)第一个被执行的image必须小于2KB(我们暂时称它为SPLSecondary Program Loader)。b)SPL在有限的size中必须完成两个事情初始化DDR将后续的启动代码(如u-boot)从存储介质中copy到DDR中执行。c)u-boot在DDR中运行(不再受限于系统资源)进行必要的初始化之后将linux kernel copy到DDR中并执行。d)linux kernel执行并加载rootfs。2)固件更新的时候(这里提供一种方案将借助Android的fastboot不唯一)a)第一个被执行的image(SPL)必须小于SRAM的size(根据经验Bubblegum-96平台要小于70KB)。b)通过ROM code的DFU程序将SPL上传到SRAM并执行。c)SPL初始化DDR并将控制权重新交给ROM code的DFU程序。d)通过ROM code的DFU程序将u-boot(size不再受限)上传到DDR并执行。e)u-boot中启动fastboot服务通过fastboot协议更新固件。本文将基于“X Project”前面的成果介绍通过将SPL上传到SRAM并执行、初始化DDR然后再把u-boot上传到DDR并执行的过程。3. 初始化过程介绍3.1 编写DDR driver正确初始化DDR由于非技术的原因这里无法多说感兴趣的同学可以在资料充足的情况下在自己的板子上尝试。最终的结果就是导出一个类似于xxx_ddr_init()的接口该接口会被SPL调用。3.2 在SPL的初始化代码中调用DDR的init接口初始化DDR然后将控制权交回给ROM code基于“X-003-UBOOT-基于Bubblegum-96平台的u-boot移植说明”的成果我们已经可以在SPL的board_init_f接口中点亮一盏LED灯现在要做的就是调用DDR的初始化接口如下void board_init_f(ulong bootflag){bubblegum_early_debug(1);#ifdef HAS_DDR_SOURCE_CODEs900_ddr_init();#endifreboot_to_adfu();}注1这里之所以要加一个宏定义是因为源代码中没有DDR的source code避免编译错误而已。DDR初始化完成后需要把控制权交回给ROM code的DFU程序这可要费一番心思如下static void reboot_to_adfu(void){void (*call_adfu)(void);//call_adfu (void (*)(void))0xffff5a00;call_adfu (void (*)(void))0xffff0400;call_adfu();while (1);}我这里用了一个比较笨的方法直接跳转到S900 ROM code的起始地址了大家可以根据自己平台的实际情况自行处理。以上SPL并没有source code提供我把编译出来的bin文件共享出来了可参考3.3 修改u-boot的代码完善dram_init接口告诉u-boot当前DDR的sizeint dram_init(void){printf(dram_init\n);bubblegum_early_debug(11);/* no need do dram init in here, we have done it in SPL */gd-ram_size 2 * 1024 * 1024 * 1024; /* 2GB, TODO */printf(dram_init OK\n);return 0;}由于SPL已经完成了DDR初始化这里什么事情都不需要做只要通过gd-ram_size告知u-boot DDR的size(这里是2GB)即可。当然这里的赋值有点粗暴后续再完善吧。3.4 修改u-boot的配置项将u-boot编译到DDR中从DDR执行改动如下-#define CONFIG_SYS_TEXT_BASE CONFIG_SPL_TEXT_BASE-#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SPL_STACK#define CONFIG_SYS_TEXT_BASE 0x11000000#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE 0x7ff00)/* Some commands use this as the default load address, TODO */-#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE)#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE 0x7ffc0)S900 DDR的地址映射是从0x0开始的我们随便找一个地址(这里是0x11000000)。编译生成新的bin文件后进行简单的测试具体如下。以上可参考如下patch4. 测试在build目录编译完成后按照如下的步骤执行1)按住Bubblegum-96的ADFU键使板子进入DFU模式2)按住Bubblegum-96的ADFU键不松开将splboot.bin(就是我们的SPL image)上传到SRAM并执行sudo ../tools/dfu/dfu bubblegum 0xe406b200 ../tools/actions/splboot.bin 13)执行完毕后会重新进入DFU模式进入后可以松开ADFU按键。4)将u-boot上传到DDR并执行(注意上传位置和CONFIG_SYS_TEXT_BASE 一致)sudo ../tools/dfu/dfu bubblegum 0x11000000 out/u-boot/u-boot-dtb.bin 15)检查串口打印执行成功。原创文章转发请注明出处。蜗窝科技www.wowotech.net。评论ary2016-08-07 20:06我觉得wowo可以考虑先在一个成熟的开源板子上做一遍移植一是通用的板子大家都能买到另外就是开源板子硬件公开程度更高资料更全移植更方便2016-08-07 20:27ary多谢提议其实不用太在意板子大家可以用不同的板子思路一样就可以了。另外不成熟的板子会遇到一些问题有问题也是学习的过程。现在有同学在tiny210上面移植了(比较成熟了)可以参看http://www.wowotech.net/forum/viewtopic.php?id522016-07-25 19:39wowo:Bubblegum-96这个板子你们是买的还是2016-07-26 08:52pingchangxin我们手上的是厂家送的。发表评论昵称邮件地址 (选填)个人主页 (选填)