您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > u_boot移植(四)之nand flash启动
u_boot移植(四)之nandflash启动通过前面几节的介绍,我们了解了DDR2内存的初始化,K9F2G08U0BNandFlash的操作。接下来,是时候将我们的uboot烧写到NandFlash,然后从NandFlash启动了。在正式干活之前,我们先来了解一下S5PC100的启动流程。一、S5PC100启动流程通过上面英文的解释,我们可以知道:(1)S5PC100在上电的时候,可以选择从NandFlash、OneNand、SD卡、USB进行启动。我们这里选择从NandFlash进行启动。(2)S5PC100上电的时候,首先运行的是它内部ROM中程序。这段程序会自动拷贝NandFlash前16KB数据到S5PC100内部的SRAM中,接下来跳到内部的SRAM中执行。我们如果想将我们的uboot能从NANDFLASH启动,就必须把它烧写到NandFlash的启始位置。这样以一上电的时候,S5PC100内部ROM中的程序会将我们uboot的前16KB代码拷贝到其内部的SRAM中执行。嗯,这样我们就可以执行uboot的第一阶段代码了。通过前面我们对NANDFLASH启动流程的分析,我想大家应该知道,uboot第一阶段干的主要事情有三个:(1)初始化DRAM(2)拷贝NandFlash上的uboot到DRAM中(3)跳到DRAM中执行NandFlash的第二阶段下面,我画了一幅图,对上面的过程做了简单的一个总结,帮助大家更好的理解,uboot是如何从NandFlash启动的?好了,接下来我们就来修改uboot源码,让它支持从nandflash启动。二、修改uboot源码,支持从nandflash启动这里主要修改的是u_boot的第一阶段,我想通过前面对uboot的启动流程分析,大家应该很熟悉uboot的第一阶段了。好,开始干活吧!我们回顾一下,第一阶段设计到主要文件:需要关心的文件我已经在上图中标识出来了,接下来我们来看一下每个文件,确认需要修改的地方。1.start.S文件修改为了可以有后悔药吃,我们先将start.S备份成start-bak.S第一处修改:CONFIG_SKIP_LOWLEVEL_INIT宏在include/configs/fsc100.h中没有定义,所以这段代码是有效的,我们之前注释过这段代码,还有印象吗?当时,为了让我们的uboot能快速的跑起来,我们用开发板自带的uboot,通过tftp下载我们的uboot到内存中,然后运行。还记得当时我们为什么要注释掉这段代码吗?思考.....第二处修改:我们是从NandFlash中启动的,所以这段代码我们不需要,我们需要做的事情是读取NandFlash中的uboot到DRAM中。关于如何读NandFlash操作前面我们已经学过了,你学会了吗?修改代码如下:可以看出,我们修改完代码后,是可以通过CONFIG_NAND_FLASH_BOOT宏来决定那一段代码是有效的。我们想底下这段代码有效,就需要在include/configs/fsc100.h文件中定义这个宏。2.添加copy_uboot_to_dram代码不同的开发板外接的NandFlash不一样,所以这这段代码是板级相关的代码,我们需要在board/samsung/fsc100目录下添加。关于如何读nandflash前面我们已经学习过了,不再讲解。这段代码我们将它存放在nand_cp.c文件中,其内容如下:我们将nand_cp.c文件拷贝到board/samsung/fsc100目录下。问题来了,我们添加完nand_cp.c后,怎么让它编译到我们的uboot代码中去呀?聪明的你,一定知道只需要修改Makefile就可以。修改board/samsung/fsc100的Makefile如下:3.lowlevel_init.S文件修改为了可以有后悔药吃,我们先将lowlevel_init.S备份成lowlevel_init-bak.S在修改这个文件之前,我们先思考一个问题:什么时候,会执行lowlevel_init.S文件中的代码?在这个文件中,我们主要完成两件事情:(1)系统时钟初始化(2)DRAM初始化,修改如下:4.mem_setup.S文件修改为了可以有后悔药吃,我们先将mem_setup.S备份成mems_setup-bak.S在u_boot移植(三)之DDR2内存初始化一节,我们已经确定过,默认mem_setup.S中完成的是对LPDDR内存初始化。我们开发板FSC100外接的内存是DDR2,所以这个文件需要将其替换成DDR2的内存初始化文件。这个文件在前面我们已经编写过,将其拷贝到这个目录下来即可。好了,修改完毕。在修改结束后,请查看一下文件你修改是否正确。嗯,没问题,我们编译uboot吧!我去,编译报错了,错误如下:说我mem_ctrl_asm_ini没有定义,我们不是在mem_setup.S中定义过它吗?先到board/samsung/fsc100/mem_setup.S中查看是否有这个标签。经确认,是有的。那是为什么呢?难道没有编译这个文件?果然如此,没有编译这个文件。怎么办?废话,肯定是修改Makefile编译这个文件了。修改board/samsung/fsc100目录下的Makefile如下:接着编译,一路绿灯,编译成功。三、反汇编,找BUG也许,你还没来得及看下面,你已经兴高采烈的将uboot烧写到开发板中,接着你会淡定的看到没有任何反应,更会淡定的问貌似套路都对,为什么没有效果呢?。好,我们来确认一个事情:开发板上电的时候,从NandFlash启动,S5PC100会自动将NandFlash的前16KB代码拷贝到其内部的SRAM,接着执行SRAM的代码,也就是我们uboot的第一阶段代码。这第一阶段代码需要完成以下几件事情:(1)初始化系统时钟(2)初始化DDR2(3)拷贝NandFlash上的uboot到DRAM(4)跳到DRAM中执行uboot的第二阶段代码你会很自豪的告诉我,这些事情你都做过了。嗯,我们确实已经做过了这些事情。试想如果编译器在生成可执行文件的时候,没有将这些代码存放在可执行文件的前16KB,那会怎样呢?好,我们反汇编一下我们生成的uboot可执行文件,然后看看,编译器是否将这些代码安排到可执行文件的前16KB。反汇编的命令:arm-cortex_a8-linux-gnueabi-objdumpu-boot-Du-boot.dis以下是从u-boot.dis文件中摘出来的片段:可以看出,编译器将:copy_uboot_to_dram代码存放在0x20f0e4a4lowlevel_init代码存放在0x20f0e16csystem_clock_init代码存放在0x20f0e1dcmem_ctrl_asm_init代码存放在0x20f0e4ec我们指定的代码段起时为止为0x20f00000,而16KB为0x4000,可以看出编译器将我们的代码已经安排到16KB以外了。怎么才能让编译器将这些代码安排在前16KB呢?还记得链接脚本不,它就是用来安排代码在可执行文件中存放位置的。接下来我们就来修改链接脚本,让它将我们的代码安排到前16KB。修改cpu/arm_cortexa8/u_boo.lds如下:原理很简单,就是告诉编译器在链接的时候,将我们指定的.o文件链接到最前面。嗯,重新编译吧,在编译器前,先清除一下,然后重新生成uboot。四、烧写uboot到NandFlash呵呵,重新启动开发板,见证奇迹的时刻到了!回顾一下我们的工作:1没有实现DDR2内存初始化[完成]2不能从NandFlash启动,到目前为止我们都是直接下载到内存中运行的[完成]3不具备网络功能,没有驱动DM9000网卡,无法使用TFTP服务4不具备对NANDFLASH操作总之,一句话到目前为止,我们的任务只完成了2/4。
本文标题:u_boot移植(四)之nand flash启动
链接地址:https://www.777doc.com/doc-3225151 .html