uCLinux引导程序设计及其在LPC2478上的实现

时间:2022-08-14 11:24:35

uCLinux引导程序设计及其在LPC2478上的实现

摘要:针对NXP LPC2478 ARM处理器,提出了一种uCLinux嵌入式系统引导程序的设计方案。在明确了引导程序必须实现的各种功能之后,给出了实现这些功能的设计方案,详细说明了如何在由LPC2478所构成的嵌入式应用系统上实现uCLinux嵌入式系统引导程序。此外,对处理器对外扩非易失存储器NandFlash的控制作了详尽的说明。此方案在实际的系统环境中运行稳定。

关键词:嵌入式系统;引导程序;LPC2478;uclinux;Nandflash

On the Design of uCLinux's BootLoader with its Implementaion on LPC2478

YANG Tao, SHI Guo-liang

(Institute of Electronic Information Soochow University, Suzhou 215006, China)

Abstract: Presented in this paper is a bootloader scheme and its implementation on NXP LPC2478 ARM MCU. After defining all necessary functions to be included in a bootloader, specific design scheme for these functions are given. Then the implementation of the uclinux embedded operating system bootloader on LPC2478 is discussed in detail. At last, in-depth descriptions of how to control non-volatile NandFlash by MCU are presented.It runs well in the embedded system.

Key words: embedded system; bootloader; LPC2478; uclinux; nandflash

随着工业自动化与社会信息化水平的不断提高,嵌入式设备得到了广泛的应用,越来越多复杂程度较高的嵌入式设备中采用操作系统。uCLinux作为专门为无MMU(Memory Management Unit)处理器设计的嵌入式Linux操作系统[1],支持ARM、Motorola等多种架构的微处理器,加上32位ARM嵌入式处理器高性能、低功耗的出色特性,嵌入式系统中采用ARM+uCLinux的组合具有很好的适应性。在基于ARM+uClinux的嵌入式系统开发中,系统引导程序是成功实现上述应用组合的重要起点,因为实时系统能否正确引导决定了系统能否自举及自举后各类应用程序的运行环境能否正确构建。所以,对于系统引导程序的研究是十分必要的。

1 系统引导程序简介

系统引导程序即BootLoader,是在系统复位后执行的第一段代码,代码量小,负责嵌入式操作系统内核的引导和加载[2]。一般来说,它首先完成系统硬件的初始化,包括时钟的设置、存储区的映射,设置堆栈指针等,然后跳转到操作系统内核的入口,将系统控制权交给操作系统。BootLoader的实现高度依赖系统的硬件[2],不同的处理器架构,不同的目标板设备,它的配置是不相同的,因此在研究BootLoader的设计时,系统的硬件平台是首先要考虑的因素。

2 系统的硬件平台

本系统的硬件平台的主要包括恩智浦的微控制器LPC2478,串口, JTAG口,10/100M的以网口,外部扩展一片4M*4Banks*16bit的32M SDRAM和一片256M * 8bit的NandFlash。系统的硬件组成如图1所示。

主芯片LPC2478基于ARM7TDMI-S的内核,主频最高为72MHZ,拥有98K片内静态存储器,512K片内Flash存储器;拥有丰富的外设接口,除了图中的外部存储器接口,用于程序调试和下载的串口和JTAG口,支持LPC2478的网络功能的以太网接口, 还包括160个高速通用输入输出口,USB设备接口,CAN总线接口,支持配置优先级和向量地址的高级向量中断控制器,通用直接内存存取控制器,4个32位的定时器,实时时钟和开门狗等外设接口。基于上面的硬件平台,系统的软件平台包含三个方面:引导程序BootLoader、嵌入式操作系统uCLinux内核、文件系统。BootLoader是操作系统内核uCLinux,文件系统加载的前提,它的作用是不言而喻的。当把系统控制权交给uCLinux之后,系统的运行和BootLoader就没有任何关系,这表明BootLoader是独立于uCLinux的。目前在uCLinux的发行包里不包含BootLoader,因此需要专门进行设计。

3 Bootloader的程序设计

在本系统中,引导程序的作用就是引导和加载嵌入式操作系统uCLinux,把系统的软硬件环境带到一个合适的状态。uCLinux的BootLoader的设计主要包括下面几个方面:

1) uCLinux的固化

将uCLinux操作系统代码固化在系统的Flash中,其方法很多,主机可以通过JTAG口、以太网接口或串口将uCLinux的映像文件烧写到系统目标板指定的Flash位置。串口烧写需要ARM监控程序支持,网口烧写需要以太网支持,JTAG口的烧写需要配备一个支持JTAG口的仿真器。本系统采用JTAG口烧写,利用串口来打印uCLinux调试和运行信息。因此BootLoader需要初始化一条链接主机和目标机的串口通道。

2) 系统硬件的初始化

系统刚加电时,uCLinux还没有被加载,系统硬件的初始化工作全部由BootLoader完成。系统硬件的初始化要明确哪些硬件是uCLinux能够自举, BootLoader必须要配置的硬件。跟其它目标板一样,本系统里的引导程序要初始化的系统硬件相关的部分包括异常向量表建立、LPC2478各种模式下的堆栈空间建立、通用输入输出口配置、硬件时钟建立、使能屏蔽中断等。

3) uCLinux的加载

uCLinux有两种运行方式:一种方式是直接在Flash中运行uCLinux自带的引导程序;另一种方式是将固化在Flash中的uCLinux先拷贝到SDRAM的某一段地址区间,再从该段地址区间的首地址运行uCLinux。uCLinux编译后目标文件一般可控制在几百KB量级,加上应用程序,则可达到几M量级。主芯片LPC2478的片内512k的Flash根本不能满足uCLinux的存储要求,所以采用第二种方式,将固化在NandFlash里的uCLinux拷贝到片外的SDRAM的某段地址中,再从该段地址区内运行uCLinux。由此看来,BootLoader除了要完成上面提到的系统硬件初始化,串口通信,还要完成NandFlash和SDRAM的初始化,将uCLinux从NandFlash拷贝到SDRAM。

4) 地址映射表的配置和中断向量的重映射

所谓地址映射是指对片内和片上的存储器系统及外部设备进行统一编址并分配地址范围,应用程序则可根据地址范围辨识相应的设备。微处理器LPC2478共有4GB的寻址空间,外部设备挂接在两种内部总线APB(Advanced Peripheral Bus)和AHB(Advanced- High-performance Bus)上,挂在APB总线上的外设称为APB外设,挂在AHB总线上的外设称为AHB外设。在上电复位后,LPC2478的存储器地址空间的映射如图2所示。

图2中这些地址范围是已经设置好的,不能修改只能使用,但跟重映射并不矛盾。重映射的提出是与处理器的异常处理机制相关,LPC2478支持7种异常处理,将所有的异常处理程序的地址保存在一段连续的存储空间里,称为异常向量表,它的地址范围是0x00000000~0x0000003F,这段地址范围称为异常向量地址空间。系统一上电,把存储在片内Flash的异常向量表复制到片内SRAM中,然后通过LPC2478的映射控制器把SRAM中的异常向量表重映射到地址0x0000 0000开始处。这样,当系统发生异常时,就会从已经映射到异常向量地址空间的片内SRAM中找到对应异常处理程序的入口地址。这么做可以提高系统对异常的实时响应能力和克服易失性存储器掉电丢失的弊端。

按照上面的论述,下面给出了针对本系统硬件平台,uCLinux的BootLoader的启动过程流程图。

如流程图3所示, BootLoader的程序设计主要包括以下几个内容:

1) 设置异常向量表和各模式下的堆栈空间。

2) 建立地址映射表,中断向量重映射。

3) 目标板初始化。包括时钟建立、GPIO初始化、中断向量控制器初始化、UART初始化。

4) 内核的拷贝。包括外部存储器32MSDRAM和256MNandFlash的读写,处理器DMA(Direct Memory Access)方式实现。

BootLoader的程序实现采用汇编语言和C语言混合编程。汇编语言主要完成异常向量表建立,7个模式下的堆栈空间配置,地址映射表配置。C语言完成目标板的初始化和内核的拷贝。目标板初始化包括异常向量表重映射,硬件时钟建立,通用输入输出口配置,中断向量控制器设置,定时器初始化,串口通信等。内核拷贝与系统的通用DMA控制器和外部存储器控制器有关, LPC2478拥有一个通用DMA控制器,支持存储器到存储器、存储器到外设、外设到存储器和外设到外设的数据传输。内核的拷贝可以利用这种数据传输方式实现外部存储器NandFlash到外部存储器SDRAM的数据搬移,通过建立一个DMA的外部中断程序就可以实现;外部存储器控制器为LPC2478支持外部静态存储器和动态存储器提供了可能,外部存储器控制器也称为EMC(External Memory Control)模块,它是一个AHB从机模块,支持多达8个单独配置的存储器组,其中静态存储器和动态存储器各4个Bank,静态存储器组的每个组存储容量为16MB,动态存储器组的每个组的容量为256M。本系统里,主芯片就是通过EMC模块控制扩展的异步静态存储器(NandFlash)和动态存储器(SDRAM)的,在使用过程中,需要仔细阅读外扩存储器芯片资料,获得准确的配置参数,配置EMC提供的相关寄存器,才能使得外扩存储器使用正常。由于不同系列的处理器对NandFlash的控制并没有通用性,因此有必要给LPC2478对NandFlash的控制做一个阐述。

4 NandFlash的软件和硬件控制

4.1 NandFlash的硬件控制

正如上面讲述的,微处理器LPC2478通过EMC模块来控制NandFlash的操作,主芯片并没有NandFlash读写时需要的直接的硬件接口,它是通过EMC功能模块给NandFlash提供控制信号,然后通过软件编程实现LPC2478对NandFlash的控制。图4给出的是本系统中NandFlash与处理器的硬件连接。

如图4所示,CE(Chip Enable)片选信号用来选择NandFlash芯片,由P0口控制;I/O[7:0]是数据输入输出口,指令、地址、数据复用,与EMC模块的数据线连接,提供8位的数据传输;WE(Write Enable)写使能信号,在它的上升沿将I/O上的指令、地址、数据锁存,由EMC的片选信号CS1和写信号经过74HC32或门产生;指令CLE(Command LatchEnable)命令锁存信号,在WE的上升沿并且CLE为高电平时将指令锁存,由地址线A21控制;R/B(ready/busy)用来显示NandFlash的操作状态,当它为高电平时表示有编程、擦除或读取操作在运行,它连接在P0口上,在运行过程中通过读取该端口的状态来判断NandFlash的操作是否完成;WP(Write Protection)写保护信号,低电平有效。在软件模拟中,比较关键的就是CLE和ALE的模拟,CLE由地址线A21控制,将它置成高电平,可以实现指令的锁存,由LPC2478的用户手册可知,CS1选择的静态存储器组的地址映射范围为0x81000000~0x81FFFFFF,所以可以设置一个指针常量*PCLE=0x81200000来实现CLE的控制,ALE的设置类似,这里不再赘述。

除了上述的NandFlash的硬件连接, NandFlash的存储结构和寻址方式也非常重要。本系统中用的是一款由三星生产的256M * 8bit 的NandFlash芯片8位位宽,工作电压为3.3V,内部存储结构为2112bytes*64pages*2048blocks。页大小为2048Byte+64Byte,前2048(211)byte称为有效数据域,用来存放要存储的数据,后64Byte称为空白域,用来存放ECC数据校验和芯片信息等。

NandFlash的寻址方式与NandFlash的存储结构密不可分,256M(228)的NandFlash的寻址理论上需要28个bit,可以用A[27:0]表示,其中2048个byte需要11个bit,用A[10:0]表示称为column address;64个page需要6个bit,用A[16:11]表示,称为page address;2048个block需要11个bit,用A[27:17]表示,称为block address。在NandFlash中,地址只能在I/O[7:0]上传递,需要通过移位,进行5次的8位地址传递。

上面主要讨论了NandFlash的硬件连接,结构和寻址方式,下面要说明的是根据芯片手册对总线的读取时序进行设置。软件模拟时序关键在设置正确的时间延迟。EMC模块为每个静态存储器Bank提供了7个静态存储器寄存器,写使能芯片延迟、输出使能延迟,读访问延迟,写访问延迟寄存器对数据的读取影响最大。按照NandFlash芯片手册,它的写使能的延迟Twc和输出使能延迟Trc都至少为30ns[3],写使能延迟和读使能延迟配置是以EMC模块的时钟频率为单位的,在本系统中,EMC模块的时钟频率为28.8M,一个时钟频率约为30ns,所以Twc/TRc应该至少是一个时钟频率,再加上硬件连接上CS和WE信号经过一个或门的延迟,所以可以把Twc设置为3个周期,Trc设置为2个周期。另外两个比较重要的延迟就是读访问延迟和写访问延迟,根据NandFlash的读写时序可以看出在在读取数据时,先把一页的数据从NandFlash的存储单元传送到数据缓冲区,等到NandFlash的R/B显示Ready状态时,才会开始读取数据,读访问延迟寄存器配置的就是这段时间,按照芯片手册的数据,这段时间最大约25us[3],所以配置成最大的32个时钟频率。如此,NandFlash的时序设置就完成了。

4.2 NandFlash的软件控制

上面主要介绍了NandFlash的硬件连接,结构,寻址方式和如何正确软件模拟读写时序。下面要讨论的是对NandFlash的软件控制。图5给出的是本系统设计的NandFlash的程序流程图,用来测试NandFlash的操作。如图5所示,一个完整的LPC2478对NandFlash的操作包括NandFlash的ID号的读写,块的擦除,坏块检测,页的读写。在程序运行过程中,串口最后能够输出NandFlash测试成功,表明NandFlash的运行正常。

5 测试结果与分析

将编译好的BootLoader烧写到片内Flash的0x00000000开始的存储空间内,系统一上电复位后,从入口地址0x00000000开始运行BootLoader,串口输出一系列的验证成功信息,基本上算运行成功。对于片内存储容量为k级的微控制器而言, uCLinux的引导程序设计相对比较繁琐,工作量比较大。特别是非易失性存储器NandFlash的控制与烧写不容易实现,目前通用的烧写工具对片外NandFlash的支持也很少。为了节省

开发时间,在设计系统的硬件平台时,尤其是大型的嵌入式系统,可以尽量选择片内存储容量M级以上的主芯片,或者选择目前烧写支持比较多的外扩存储器芯片系列。在这个设计里,由于Windows平台下的集成开发环境Keil不支持uCLinux的编译,uCLinux的映像文件的固化采用专门的烧写工具烧写,因此并不具有普遍的适用性;另外,NandFlash的坏块检测只是检测了它在出厂时含有的坏块,对于在使用过程中产生的坏块的管理并没有涉及,这些都需要在以后的使用过程中继续完善。

6 结论

本文介绍了一种针对LPC2478的嵌入式系统中uCLinux的引导程序的设计方案,对自己设计BootLoader做了些许尝试与深入的研究。此方案对于同样架构和不同架构的微处理器的BootLoader设计,或者现在流行的开源BootLoader的移植都有很大的借鉴作用。

参考文献:

[1] 桂电-丰宝联合实验室.ARM原理与嵌入式应用[M].北京:电子工业出版社,2008:262-264.

[2] Yagbmour K.构建嵌入式Linux系统[M].北京:中国电力出版社,2005:254-256.

[3] SAMSUNG公司.K9F2G08 datasheet[EB/OL]..

[4] 周立功.ARM微控制器基础与实战[M].2版.北京:北京航空航天大学出版社,2005.

[5] 张伟,胡晨,张哲.NAND FLASH在系统中的应用设计[D].南京:东南大学,2006.

[6] NXP公司.LPC2478 User Manual[EB/OL]..

上一篇:数据信息知识策略的演化及其表示的研究 下一篇:基于Flash的计算机硬件组装仿真实验平台的设计...