U-Boot从NAND Flash启动的实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
U -Boot 从NAND Flash 启动的实现
王磊
(太原理工大学信息工程学院,山西太原030024)
摘要:U -Boot 不能从NAND Flash 启动给应用带来些不便,因此修改U -Boot 使其支持从NAND Flash 启动。分析了
U -Boot 启动流程的两个阶段及实现从NAND Flash 启动的原理和思路,并根据NAND Flash 的物理结构和存储特
点,增加U -Boot 对NAND Flash 的操作支持,从而完成把存储在NAND Flash 上的U -Boot 代码复制到SDRAM 中执行,实现从NAND Flash 的启动。修改过后的U -Boot 可以直接从NAND Flash 启动,给应用带来便利。关键词:U -Boot ;NAND Flash ;Bootloader ;S3C2440;移植中图分类号:TP316
文献标识码:A
文章编号:1674-6236(2010)05-0098-03
Realization of U -Boot booting through NAND Flash
WANG Lei
(Department of Information Engineering ,Taiyuan University of Technology ,Taiyuan 030024,China )
Abstract:It is not convenient that U -Boot can ’t boot through NAND Flash.In this paper ,the codes of U -Boot is modified to support that.This paper analyzes two steps of U -Boot and the method of supporting that the U -Boot boots from NAND Flash.Based on the memory characteristics and the physical structure of NAND Flash ,this paper adds the codes of NAND Flash in order to carry the codes to SDRAM that stored in the NAND Flash ,thus realizes U -Boot boots from NAND Flash.The modified U -Boot runs through NAND Flash straightly ,it is a great convenience to the application of U -Boot.Key words:U -Boot ;NAND Flash ;Bootloader ;S3C2440;porting
电子设计工程
Electronic Design Engineering
第18卷
Vol.18
第5期No.52010年5月May.2010
收稿日期:2009-10-11
稿件编号:200910032
作者简介:王磊(1985—),男,山西河津人,硕士研究生。研究方向:嵌入式系统、DCS 、自动控制。
Bootloader 引导装载程序是系统上电后运行的第一段程
序,其作用是完成基本的硬件初始化工作,所以引导装载程序跟硬件有着紧密的联系。因此必须根据开发板的硬件配置对引导装载程序进行修改才可以使其运行起来。随着嵌入式系统的复杂化,大容量数据存储的NAND Flash 的应用会越来越广泛,同时U -Boot 是功能最丰富的Bootloader ,但遗憾的是U -Boot 不支持从NAND Flash 启动。所以如果能实现
U -Boot 从NAND Flash 启动的话将会给应用带来很大的方
便。本文讨论修改U -Boot 使其支持从NAND Flash 启动,采用基于S3C2440的开发板。
1U -Boot 简介及流程分析
U -Boot ,全称universal boot loader ,是遵循GPL 条款的开
放源代码项目。可以引导多种操作系统,支持多种架构的
CPU 。它支持如下操作系统:Linux 、NetBSD 、VxWorks 等,支持
如下架构的CPU :PowerPC 、MIPS 、X86、ARM 、NIOS 、XScale 等,同时支持NFS 挂载,是一个功能丰富的BootLoader 。它的整个程序框架清晰,易于移植,许多设计人员将自己的移植代码上传到网站(http :///projects/u-boot/)上,更新速度很快。目前的版本是1.1.6,本论文正是采用此版本进行说明,U -Boot 的目录结构参见U -Boot 源代码。要进行U -Boot 的修改移植必须了解U -Boot 的程序运行流程,这是必要的一步。U -Boot 属于两阶段的BootLoader ,其启动流程如图1所示。第一阶段的文件为cpu/arm920t/start.S 和board/smdk2410/lowlevel_init.S ,用ARM 汇编语言编写,前者是平台相关的,后者是开发板相关的[1]。第一阶段主要是关于基本硬件的初始化,包括关闭MMU 、CACHE 、设置PLL 时钟比例、关闭看门狗;初始化SDRAM ,为复制第二阶段代码做准备,最后复制第二阶段代码到SDRAM 中,然后跳到
图1
U -Boot 启动流程
-98-
SDRAM中运行第二阶段。第二阶段代码都是用C语言编写的,功能更加复杂,主要是进一步初始化硬件设备、检测内存映射、复制内核镜像和根文件系统到SDRAM以及设置启动参数从而启动内核。
2支持NAND启动的代码修改
2.1添加NAND Flash的初始化函数
U-Boot中关于NAND Flash的初始化流程如下:在上电后最先运行的汇编程序cpu\arm920t\start.S中调用start_arm-boot函数,而start_armboot该函数则调用了一系列的关于设备的初始化函数。这一系列的函数中包含一个名为nand_init 的函数,nand_init就是完成NAND Flash的初始化工作。
在1.1.6版本的U-Boot的include\linux\mtd\nand.h中定义了nand_chip结构体,该结构体中定义了关于NAND Flash 操作的所有函数,包括读、写、ECC校验等,而这些函数在U-Boot中都有完整编写,只是有些个别函数需要根据自己的要求重新编写。而实现NAND Flash初始化的nand_init函数主要任务就是完成这些需要重新编写的函数和用这些函数连同U-Boot中其他默认函数来初始化nand_chip结构体。NAND_init中的board_nand_init函数在U-Boot中并未实现,显然需要重新编写的函数就在其内添加[2]。
先在cpu\arm920t\s3c24x0中添加nand.c文件,然后在该文件中实现所需要的初始化函数。一般只需要重新编写nand_chip结构体中相对应的hwcontrol、dev_ready和se-lect_chip函数。这些函数的构建可参照linux内核2.6版本里的drivers\mtd\nand\s3c2410.c文件来进行编写,如内核文件中的s3c2440_nand_hwcontrol,s3c2440_nand_devready,s3c2410_ nand_select_chip函数,然后将其赋值给nand_chip结构体中对应的函数[3-4]。
static int s3c2440_nand_devready(struct mtd_info*mtd)
{S3C2440_NAND*const s3c2440nand=S3C2440_Get-Base_NAND();
return(s3c2440nand->NFSTAT&S3C2440_NFSTAT_ READY);
}
void board_nand_init(struct nand_chip*chip)
{chip->dev_ready=s3c2440_nand_devready;
...}
接着在/include/configs/SMDK2410.h中的CONFIG_COM-MANDS内添加
CFG_CMD_NAND
同时在最后添加
#define CFG_NAND_BASE0
#define CFG_MAX_NAND_DEVICE1
#define NAND_MAX_CHIPS1
初始化函数工作基本完成。最后修改Makefile,把nand.c 文件添加进工程。2.2实现NAND启动
由于NAND的自身特点,对NAND Flash的操作不能像对NOR Flash那样方便地直接对地址进行操作,而是通过读写NAND Flash控制器的寄存器来完成。三星公司的S3C2440自带NAND Flash控制器,寄存器的地址是从nGCS4的地址开始。S3C2440处理器有NOR和NAND两种启动模式,当选择从NAND模式启动时,S3C2440会把NAND Flash的前4K数据搬运到内部称为Steppingstone的硬件中,同时把Steppingstone映射到地址0X00处,从而启动,启动完成后处理器会把Steppingstone释放掉以作为他用。U-Boot的一般大小都上100K,远大于4K,所以实现从NAND启动的原理就是让前4K代码完成基本初始化,重要的是把NAND Flash中的U-Boot代码复制到SDRAM中,从而跳到SDRAM中去执行[5]。分析可知,S3C2440的该特点为U-Boot从NAND Flash启动提供了可能。本文讨论的实现思路就是依据此原理。
源代码中有/board/smdk2410/u-boot/lds,该文件是U-Boot代码的链接脚本,有如下代码:
SECTIONS
{
.=0x00000000;
.=ALIGN(4);
.text:
{cpu/arm920t/start.o(.text)
*(.text)
}
可以看到Text段也就是程序代码段,被编译链接到0X00地址处,同时start.S编译后的目标文件start.o被放到text段的第一个文件处,所以start.S就是程序上电运行的第一段代码,而/cpu/arm920t/start.S这个汇编文件正是U-Boot 的程序代码入口。因此代码修改和添加主要在start.S中完成,以此来保证NAND启动代码可以在最终程序编译链接所生成的文件的前4K内。
NAND Flash读写操作比较复杂,汇编实现较为麻烦,没有C语言简单容易,因此用C语言实现对NAND的操作复制工作,最后在start.s中调用编写的C程序即可。
在/board/smdk2410/中添加boot_init.c文件,在其中实现nand_reset(nand重置函数)、wait_idle(等待即查询设备是否读写就位)、nand_select_chip(片选使能)、nand_deselect_chip (取消片选)、write_cmd(写命令)、write_addr(写地址)、read_data(读数据)、nand_init(nand控制器初始化)这些子函数和copy2ram函数,同时在copy2ram中依据NAND Flash 的读写操作特点来调用这些子函数。具体操作流程如图2所示。
对NAND Flash中的代码复制操作函数已经完成,接下来只要在start.S中调用copy2ram函数就完成工作。汇编文件start.S中,relocate、copy_loop段代码为U-Boot中原先的复制
王磊U-Boot从NAND Flash启动的实现
-99-