设为首页 加入收藏

TOP

移植U-Boot 1.3.4到GT2440(第二版2.0)(一)
2014-11-24 11:36:42 来源: 作者: 【 】 浏览:0
Tags:移植 U-Boot 1.3.4 GT2440 第二 2.0

第二版主要是对于第一版的一些错误改正,之前nand flash的移植失败,特在此处使用另一种nand flash移植方法.另外在这里还介绍一下uboot支持yaffs烧写功能的移植(新版里已经支持了),还介绍一下yaffs2文件系统的制作与使用。


移植U-Boot 1.3.4到GT2440(第一版)下载地址


具体下载目录在 /2011年资料/嵌入式Linux/移植U-Boot 1.3.4到GT2440/


硬件配置


1、 GT2440\其它开发板


2、 其中nand flash为2Kb一页(具体和512byte的有什么区别,参考nand元件手册,或者上网搜一下,对于uboot,主要是读nand时的写地址时序的不一样)


3、 串行线


4、 J-link\j-tag(笔者用的是jlink,主要用于uboot的调试,因为你移植马上能用的可能性不大,所以需要调试)


软件配置:


1、u-boot-1.3.4


2、- j-link或者H-jtag


Uboot 源码是不支持从nand中启动的,但是2410 2440是支持的,而且对于闪存,nand比较大容量,比较便宜,所以使用nand启动uboot是比较需要的。那么它启动的原理是什么?


其实从nand flash 控制器有一个特殊功能,会自动把nand flash前4K内容复制到4K SRAM中(注意,是只有4k的SRAM而不是SDRAM,超过怎么办,所以要复制到SDRAM中,如下图)中,并把0x00000000设置成内存起始地址,cpu从这个地址开始运行。这个过程不需要程序干涉。在配置NAND启动模式之后,S3C2440上电会先将NAND中的0x0 - 0x1000共4096字节的数据拷贝到位于Bank0中的Boot Internal SRAM上


这4K的内容,主要是保存的uboot的部分功能(拷贝功能),执行后,再把nand里的内容拷贝到SDRAM中,原因有下:


1、 SDRAM运行速度快


2、 实际的uboot代码永远大于4Kb的空间,,所以要开辟一个新空间给uboot运行





二、uboot的运行流程


首先先大概分析一下uboot,这样有利于明白,移植的每一步是需要做些什么?


在讲uboot启动前,先讲一下arm启动流程,arm启动是先运行芯片厂家固化的boot block,这段程序是引导块,芯片厂家将boot block地址重映射到片内存储器空间最高处,接近接近2G(0x8000 0000靠MMU映射)。运行完这段程序后,就会运行0x0 地址。看回上面的2440存储映射图,假如是nor的话,就会直接运行Nor 里的内容,如果是nand的话,nand控制器先拷4k到0x0000 0000里的SRAM,然后0x4000000后的内容会被重映射到0x0000 0000的映射,这样就代表前4k直接操作的是bootinternal的SRAM,而不是nand的前4k,可能是因为SRAM速度快.



上个很好的图:



现在看回uboot启动流程:


像网上说的,uboot编译时首先编译的是u-boot-1.3.4\board\你的开发板文件夹\u-boot.lds,看一个2410的例子:


ENTRY(_start)


SECTIONS


{


. = 0x00000000;


. = ALIGN(4);


.text :


{


cpu\arm920t\start.o (.text)


*(.text)


}



. = ALIGN(4);


.rodata : { *(.rodata) }



. = ALIGN(4);


.data : { *(.data) }



. = ALIGN(4);


.got : { *(.got) }



__u_boot_cmd_start = .;


.u_boot_cmd : { *(.u_boot_cmd) }


__u_boot_cmd_end = .;



. = ALIGN(4);


__bss_start = .;


.bss : { *(.bss) }


_end = .;


}


(1) 从ENTRY(_start)可以看出u-boot的入口函数是_start,这个没错


(2) 从. = 0x00000000也许可以看出_start的地址是0x00000000,事实并不是这样的,


.text为代码段,可以看出cpu/arm920t/start.o 在代码段的最前面,所以会先执行start.o 中的代码, 如何设置从0x33f80000开始呢 ~这是链接的时候指定的


在根目录下面的config.mk中有下面一句


LDFLAGS +=-Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)


关键就是其中的-Ttext $(TEXT_BASE),这句指明了代码段的起始地址


而TEXT_BASE在 board/smdk2440/config.mk中定义 TEXT_BASE = 0x33F8 0000


为什么是0x33F80000呢 ~


这是将NAND中Uboot拷贝到RAM中的起始地址,所以在代码拷贝到RAM之前不能使用绝对地址(链接后都会加上_TEXT_BASE)来寻址数据,只能用相对地址(相对于当前PC)(adr r0, _start可以确定程序在哪里运行,因为adr是基于pc当前值的,假如在内存中0x33f8000就应该是0x33f8000+_start,假如是在flash中,就应该是0+_start )


ARM汇编中,常有两种跳转方法:b跳转指令、ldr指令向PC赋值。 (参考《[NAND]UBOOT从NAND FLASH启动分析》)


要特别注意这两条指令的意思:


(a) b step:b跳转指令是相对跳转,依赖当前PC的值,偏移量是通过该


指令本身的 bit[23:0]算出来的,这使得使用b指令的程序不依赖于要跳到的代


码的位置,只看指令本身。具体是将这24位左移两位加上PC再赋给PC寄存器,得到目标地址


(b) ldr pc, =step :该指令是一个伪指令编译后会生成以下代码:


ldr pc, 0x30008000


<0x30008000 > step


是从内存中的某个位置(step)读出数据并赋给PC,同样依赖当前PC的值,但


是偏移量是step的连接地址(运行时的地址),所以可以用它实现从Flash到RAM的程


序跳转。


(c)此外,有必要回味一下adr伪指令,U-boot中那段relocate代码就是通过adr实


现当前程序是在RAM中还是flash中:


relocate: /* 把U-Boot


重新定位到RAM*/


adr r0, _start /* r0是代码的当


前位置 */


/* adr伪指令,汇编器自动通过当前PC的值算出这条指令中“_start"的值,执行到_


start时PC的值放到r0中:


当此段在flash中执行时r0 = _start = 0;当此段在RAM中执行时_start = _TEXT_B


ASE(在board/smdk2410/con

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux块设备子系统浅析(2.6.26) 下一篇交叉编译工具arm_linux_gcc安装

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·求navicat for mysql (2025-12-26 13:21:33)
·有哪位大哥推荐一下m (2025-12-26 13:21:30)
·MySQL下载与安装教程 (2025-12-26 13:21:26)
·Linux_百度百科 (2025-12-26 12:51:52)
·Shell 流程控制 | 菜 (2025-12-26 12:51:49)