基于Nandflash的Bootloader的设计与实现(WinCE&2410)

摘要:Bootloader是系统上电或复位后首先运行一段代码,是连接操作系统和硬件桥梁,负责初始化硬件和引导操作系统等。目前已有很多通用Bootloader,但是如何根据特定嵌入式平台,移植自己引导程序是一个重点和难点。文章详细说明了从Nandflash引导操作系统要完成主要任务和实现方法,并给出了在S3C2410上实现Nandflash启动试验结果。
关键词:Bootloader; 移植;Nandflash;S3C2410

0 引言

Bootloader通常称为系统引导加载程序,是系统加电或复位后执行第一段代码[ 1 ]。一般它只在系统启动时运行非常短时间,但对于嵌入式系统来说,这是一个非常重要系统组成部分。通过这段小程序,可以初始化硬件设备、建立内存空间映射图,从而将系统软硬件环境带到一个合适状态,以便为调用操作系统内核准备好正确环境,并同时提供基本输入、输出系统监控功能和程序调试功能。

Bootloader是严重地依赖于硬件而实现。每种不同体系结构处理器都有不同Bootloader。除了依赖于处理器体系结构以外,Bootloader实际上也依赖于具体嵌入式板级设备配置,也就是说,对于两块不同嵌入式板而言,即使它们是基于同一种处理器而构建,要想让运行在一块板子上Bootloader程序也能运行在另一块板子上,通常也都需要修改与目标硬件相关代码。因此有必要分析Bootloader,并理解和找出其中原理和规律,就其特定嵌入式系统,移植或开发属于自己Bootloader。

1 系统硬件平台简介
本系统采用是SamSung公司S3C2410处理器[ 2 ],它是专门为移动手持设备提供高性价比和高性能嵌入式微处理器解决方案。其内核是ARM920T,最高能工作在202.8MHz,为了减少系统总成本和减少外围器件,它集成了如下部件:分别为16KB指令和数据Cahce、1个LCD控制器、SDRAM控制器、NANDFLASH控制器、3通道UART、4通道DMA、4个具有PWM功能计时器和1个内部时钟、8通道10位ADC、触摸屏接口、I²S总线接口,2个USB主机接口、1个USB设备接口,2个SPI接口、SD和MMC卡接口、看门狗定时器、117位通用IO口、24位外部中断源、8通道10位AD控制器等。本文涉及S3C2410开发板硬件结构如图1所示,本文主要阐述从Nandflash引导操作系统要完成主要任务和实现方法,至于从Norflash引导操作系统,不打算具体实现。PCbfans.cn提示请看下图:

                                                                                                                                   图1 S3C2410硬件结构图

2 存储空间分布和映射图
硬件平台Nandflash(型号是:K9F1208U0M[ 3])空间为64MB,SDRAM(型号是:HY57V561620[ 4 ],32Mx2)空间为64M(0x30000000-0x33ffffff),采用如图2所示存储空间分布图,因为Nandflash只能存储程序,无法运行程序。为了能够从Nandflash启动,上电复位时,S3C2410通过硬件逻辑把Nandflash前4KB内容复制到片内SRAM中,而片内SRAM被映射到地址0x0,这样就可以从地址0x0处取到有效指令,开始执行bootloader,完成把Nandflash中内核代码复制到sdram中等工作。
PCbfans.cn提示请看下图:


                                                                                                   图2 引导代码和操作系统内核在Nandflash和存储空间中分布情况

3 Bootloader设计流程
Bootloader引导程序是硬件上电复位后首先运行代码,由它来加载嵌入式操作系统。然后由操作系统接管整个系统,进行进程管理、内存管理、磁盘管理和各个外设管理等工作。 BootLoader是操作系统内核运行之前一段自举程序,用来初始化硬件设备、改变处理器运行模式和重组中断向量,建立内存空间映射图,将系统软硬件环境带到一个由用户定制特定状态,然后加载操作系统内核。从操作系统角度来看,Bootloader总目标就是正确地调用内核来执行。Bootloader一般分为stage1和stage2两大部分[ 5 ],对于依赖于CPU体系结构代码,比如设备初始化代码等,通常都放在stage1中,而且通常都用汇编语言来实现,以达到短小精悍目,也就是前面说启动代码。而stage2则通常用C语言来实现,这样可以实现复杂功能,而且代码会具有更好可读性和可移植性。

3.1 Bootloaderstage1
这部分代码必须首先完成一些基本硬件初始化。为stage2 执行以及随后内核执行准备好一些基本硬件环境。Bootloader stage1 一般通用内容包括:
(1)设置中断和异常向量;(2)禁止看门狗;(3) 屏蔽所有中断, 在Boot Loader 执行全过程中可以不必响应任何中断, 中断屏蔽可以通过写CPU 中断屏蔽寄存器或状态寄存器CPSR 寄存器来完成;(4) 设置CPU 速度和时钟频率;(5) 对RAM进行初始化, 包括正确设置系统内存控制器功能寄存器等;(6)初始化LED或UART,就是通过GPIO来驱动LED,也可以通过初始化UART向串口打印Bootloader调试信息来表明系统状态是OK还是ERROR,以便跟踪系统运行情况;(7)关闭CPU 内部指令/数据高速缓存(cache);(8)为加载Bootloaderstage2准备RAM空间;(9)设置好堆栈;(10)跳转到stage2C入口点;其流程图如图3所示。

更为详细的Bootloaderstage1代码及注解可查看:http://blog.csdn.net/xuyuefei1988/article/details/7388003

PCbfans.cn提示请看下图:


                                                                                                                                图3 Bootloaderstage1实现

3.2 Bootloaderstage2
为了让程序跳入C 语言“main”函数, 我们采用直接跳转到“main”函数方法, 实现代码如下:
b Main
进入main 函数后即可以开始本阶段stage2 初始化任务, 这包括:
(1) 如果在stage1没有初始化UART,这时候至少初始化一个串口, 以便和终端用户进行交互,当然也可以继续点亮或熄灭LED来判断程序执行情况;
(2) 修改时钟频率;
(3) 使能指令Cache;
(5) 从串口中打印一些必要交互信息,了解系统状态;
(6) 初始化中断, 包括屏蔽中断, 清除中断悬挂标志, 初始化中断向量表, 注册需要中断处理函数等;
(8)打印版本、时间等信息,并从Nandflash复制内核到SDRAM中;
(9)修改指针,直接跳到内核在SDRAM中首地址处,至此,完成了Bootloader全部运行加载工作;

下面是main()函数和从Nandflash复制内核到SDRAM中ReadImageFromNandflash()函数具体实现,但省略了一些具体细节,包括从串口打印启动、交互、调试信息和一些具体函数实现。一些具体函数实现可以参考三星评估版源代码。
void Main(void)
{
JumpAddr=0x30200000; //拷贝内核到sdram中起始地址,也是内核开始执行地址
ChangeClockDivider(1,1); //1:2:4
ChangeMPllValue(0x5c,0x1,0x1); // FCLK=202.8MHz
MMU_EnableICache(); //使能指令Cache
Uart_Init(); // 初始化串口
Port_Init(); //初始化I/O口
NF_Init(); //初始化Nandflash控制器
NF_ReadID(); //读取Nandflash存储器ID号
ReadImageFromNandflash();//把存储在Nandflash中内核拷贝到SDRAM中
rINTMSK=BIT_ALLMSK; //屏蔽所有中断
Launch(JumpAddr); //跳转到sdram中内核开始处,并运行内核
}
从Nandflash(Flash是K9F1208U0M)拷贝内核到SDRAM函数具体实现如下:
void ReadImageFromNandflash(void)
{
U8 Image_Buf[512];
U32 Sram_Space=0;
U32 j,k, numberblock;
static U32 i, SECTOR_SIZE=512;
static U8 isbad;
volatile U32 IMAGE_BASE=0x30200000; //内核在sdram中运行开始地址
rINTMSK = BIT_ALLMSK; //屏蔽所有中断
i=2; //从第2个block开始拷贝内核,第0个用于存储本文bootloader,第1个没用到
numberblock=2047; //拷贝多少个block到sdram中,视内核大小设置此值
while(1)
{
nextblock:
isbad=0;
isbad=NF_IsBadBlock(i); //判断正在拷贝block是否是坏block
if (isbad) //是坏block,就进行相应处理;否则就忽略此处,进行下面拷贝
{
i=i 1; //调整,指向下一个block
isbad=0;
if(i>= numberblock) //判断是否拷贝完了所需block
{
Launch(JumpAddr); //拷贝完了所需block,就跳到sdram中内核开始处
}
goto nextblock;
}
for(k=0;k<32;k ) //1 block=32 pages
{ // FMD_ReadSector()函数实现从Nandflash存储器中读取数据到数据缓冲区中
FMD_ReadSector(i, (U8 *)&Image_Buf, k);
for (j=0;j<SECTOR_SIZE;j ) //1 page=512 bytes
{ //从数据缓冲区中拷贝到sdram中
*((U8 *)(IMAGE_BASE Sram_Space j))=Image_Buf[j];
}
Sram_Space=Sram_Space SECTOR_SIZE; //调整sdram中偏移地址
}
i=i 1; //调整,指向下一个block
if(i>= numberblock) //判断是否拷贝完了所需block
{
Launch(JumpAddr); //拷贝完了所需block,就跳到sdram中内核开始处
}
}
}

4 试验结果
由于三星公司S3C2410集成了Nandflash控制器,它通过硬件逻辑把Nandflash前4KB内容,即把Bootloader复制到片内sram中,并被映射到地址0x0处。通过跳线设置默认从nandflash启动,那么,系统每次上电或复位后,首先开始运行就是Bootloader。使用ADS1.2集成开发环境建立Bootloader应用工程,添加必需文件并设置好编译环境,如BootloaderRO_Base设置为0x0,RW_Base设置为0x33ff0000等,调试并最后生成可执行二进制文件,通过JTAG接口把Bootloader烧写到Nandflash第0个block地址开始处,通过usb下载工具把操作系统烧写到第2个block地址开始处,复位启动系统运行后结果如图4所示,该程序用于基于uCOS操作系统图像采集系统引导。用同样方法烧写不同操作系统内核应用程序,试验结果每一次表明:Bootloader运行良好,启动加载内核快,且简单、实用、可靠。
PCbfans.cn提示请看下图:


                                                                                                                              图4 Bootloader引导运行系统

5 结论
Bootloader设计与实现是一个非常复杂过程,因此要根据具体硬件和软件需求分析来进行移植或设计。本文设计Bootloader完成主要功能包括:试验板硬件初始化、串口初始化、时钟频率修改以及从Nandflash复制操作系统到SDRAM中运行等,并通过PC机上超级终端显示了正确启动运行信息,且可执行代码只有3K左右。因此,本文所详细描述Bootloader启动运行全过程,对理解、设计和移植Bootloader具有一定参考意义。

参考文献:
[1] 徐宇清,黄彦平等.S3C44B0XBootloader技术分析[J]. 上海理工大学学报,2005,27(4):369-372.
[2]SAMSUNG公司. Samsung s3c2410a User Manual v1.0.pdf.
[3]SAMSUNG公司.K9F1208U0M-YCB0.pdf.
[4] http://www.icpdf.com/pdf/HY57V561620.htm. HY57V561620(L)T.pdf.
[5]张嵛编著.32位嵌入式系统硬件设计与调试.北京:机械工业出版社,2005,7.

[作者简介]
郝卫东(1964-),男,汉族,河北定县人,桂林电子科技大学高级工程师,硕士研究生导师,主要从事机器人技术和医疗电子方面研究。

刘溯奇(1977-),男,汉族,广西桂林人,广西桂林电子科技大学机器人中心硕士研究生,主要从事机器人技术、嵌入式系统应用方面研究。

以上转自:http://www.pcbfans.cn/article/06/4789.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于FPGA的NAND Flash读写是一种常见的存储器读写方式。FPGA通过控制NAND Flash的控制信号和数据信号,实现NAND Flash的读写操作。这种读写方式具有速度快、可靠性高、容量大等优点,被广泛应用于嵌入式系统、存储器控制器等领域。 ### 回答2: FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,具有高度可定制性和可重构性,由于它可以实现复杂的算法和处理器实现,因此可以广泛应用于数字电路设计嵌入式系统。 NAND Flash是一种非易失性存储器,一般应用于嵌入式系统中以提供数据存储。在使用FPGA来读写NAND Flash时,需要进行以下几个步骤: 1、初始化FPGA 和 NAND Flash: 在使用FPGA读写NAND Flash之前,需要对FPGA进行初始化。这包括设置引脚、时钟、控制器和其他必要的组件。此外,还需要初始化NAND Flash,包括读写保持时间、NAND Flash interface protocol等。 2、检测NAND Flash状态: 在读写NAND Flash之前,需要首先检测NAND Flash的状态,以确认其是否可用。如果NAND Flash不可用,则需要重新初始化NAND Flash。 3、执行NAND Flash操作:FPGA读取NAND Flash是通过控制器来完成的。控制器通过读地址信号和控制信号到达NAND Flash。读方案实际上是从NAND Flash中读取块,页面和数据。在读过程中,FPGA通过读取NAND Flash的请求来检索块的数据。 4、执行NAND Flash操作:写NAND Flash是通过控制器来完成的。FPGA需要将数据和页面地址发送到控制器,然后控制器将数据写入NAND Flash中。在写入期间,必须确保数据的正确性和完整性,即将相应的错误检查和纠正操作应用于数据。 5、结束操作:最后,读写操作完成后,必须对FPGA和NAND Flash进行适当的清理,以确保下一次正常操作。 总之,使用FPGA读写NAND Flash是一项复杂的任务,需要仔细考虑并遵循正确的设计程序。使用FPGA可实现高速读写操作,增加系统的快速响应能力,提高系统的性能。 ### 回答3: 基于FPGA的NAND Flash读写技术,是指在FPGA芯片上通过内部逻辑电路实现NAND Flash的控制和数据传输。这种技术在嵌入式系统、存储设计和其他领域中应用广泛,并且具有许多优势。 首先,基于FPGA的NAND Flash读写技术可以提高读写速度。由于FPGA芯片本身就是一种高性能逻辑芯片,能够在毫秒级别内完成复杂的计算和处理。同时,该技术采用并行传输方式,大大提高了数据传输速度。 其次,此技术可以简化传统存储器控制电路的设计和系统集成。NAND Flash的控制需要大量的硬件资源,如地址线、数据线、控制线等,而FPGA则具有可编程性,可以按照需要灵活配置与重新布线,因此可以有效地减少系统的复杂度和成本。 第三,基于FPGA的NAND Flash读写技术具有较高的可靠性。由于FPGA芯片内部的逻辑电路可以通过同步时钟方式进行控制和管理,使得数据传输更为准确可靠。同时,FPGA芯片本身还具有自我监测与自我调整的能力,能够及时检测和修复系统中存在的故障。 总之,基于FPGA的NAND Flash读写技术在性能、灵活性和可靠性等方面都具有许多优势,并且已广泛应用于嵌入式系统、存储设计、以及其他领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值