蒋维(青海民族学院电子工程与信息科学系,青海省西宁市810007)0引言一个完整的嵌入式系统从软件角度看分为4层,分别是引导加载程序、操作系统内核、文件系统和用户应用程序。引导加载程序是系统上电后首先运行的代码。在PC机中引导加载程序由BIOS(基本输入输出系统)和位于MBR(主引导记录)的操作系统Bootload-er共同组成。而在嵌入式系统中一般没有BIOS那样的固件程序,整个系统的引导加载由Bootloader来完成。也就是说,Bootloader
蒋维
(青海民族学院电子工程与信息科学系,青海省西宁市 810007)
0引言
一个完整的嵌入式系统从软件角度看分为4层,分别是引导加载程序、操作系统内核、文件系统和用户应用程序。引导加载程序是系统上电后首先运行的代码。在PC机中引导加载程序由BIOS(基本输入输出系统)和位于MBR(主引导记录)的操作系统Bootload-er共同组成。而在嵌入式系统中一般没有BIOS那样的固件程序,整个系统的引导加载由Bootloader来完成。也就是说,Bootloader是在操作系统内核运行前执行的一段小程序,通过Bootloader的运行对系统板的CPU、SDRAM、Flash、串口等主要部件进行初始化,创建内核需要的一些信息并将这些信息传递给内核,从而将系统的软硬件环境带到一个合适的状态,最终调用操作系统内核,真正起到引导加载内核的作用。在没有操作系统的情况下,通过Bootloader程序,也可以下载简单应用文件到系统板运行。
1S3C2410开发版
S3C2410开发版是一款通用的ARM9开发版,其基本配置为CPU采用三星公司S3C2410 ARM920T,主频203MHz。集成有SDRAM控制器、NAND Flash控制器、SD卡控制器、USBHost和USB Device控制器、LCD控制器、IIC总线控制器、IIS总线控制器、SPI总线接口等。操作系统支持Linux2.4以上版本,且支持Windows CE。NAND Flash采用32 MB的K9F5608U,8位数据总线。SDRAM采用2片16M×16 bit的HY57V561620,组成32位总线。S3C2410将系统的存储空间分为8个Bank,共1 GB空间,其中Bank0~Bank5的开始地址固定,大小为128 MB,用于ROM或SRAM,Bank6与Bank7的大小是可编程的,用于ROM、SRAM或SDRAM。在这里,NAND Flash位于Bank0区,地址范围为0x00000000~0x01ffffff,2片SDRAM分别位于Bank6和Bank7区,地址范围分别为0x30000000~0x31ffffff和0x32000000~0x33ffffff。当核心板上电复位时,系统首先将NAND Flash开始的0~4 kB的程序映射到自己内部的SteppingStone区,并把其首地址设为Ox00000000,CPU从这个地址开始执行程序。
2设计流程
系统以三星公司的S3C2410为开发版,以ARMDeveloper Suite 1.2作为系统开发环境。使用ARM9-JTAG调试代理,开发流程如图1所示。
3启动流程分析与具体实现
3.1启动流程分析
系统加电复位后,CPU从复位地址0x00000000处取第1条指令执行,S3C2410开发版的NAND Flash被映射到这个预先设置好的地址上,在开发时可通过集成开发环境将Bootloader定位在复位地址开始的存储空间内。基于S3C2410开发版系统的启动流程如图2所示。
3.2 Bootloader的具体实现
一般Bootloader分为Stage1和Stage2两个阶段。Stage1阶段建立一个2410INIT.S文件,这是一个汇编语言文件,其文件功能是S3C2410启动代码、配置存储器、ISR、堆栈、初始化C向量地址等。具体所做的工作是设置异常向量表、初始化看门狗和外围电路、初始化存储器、初始化堆栈、初始化数据区、跳转到C程序的Main()函数。
3.2.1设置异常向量表
ARM的异常向量表放在0地址开始处:
由于每个中断只占据向量表中4个字节的存储空间,因此只能存放一条ARM指令。一旦系统运行有异常中断发生时,ARM处理器便把PC指针强制置为向量表中对应中断类型的地址值,从而跳到存储器其他位置的相应标号处执行。当硬件系统刚刚上电复位时,程序从0x00000000地址处跳转到标号为ResetHandler的程序处,接着便进入启动引导过程。
3.2.2初始化看门狗和外围电路
主要实现S3C2410的看门狗、中断、PLL和MPLL配置寄存器的初始化。
具体代码如下:
3.2.3初始化存储器
主要设置内存控制寄存器,具体代码如下:
其中SMRDATA的作用是设置存储器控制寄存器的值。具体定义可参考文献[2]。
3.2.4初始化堆栈
ARM有7种工作模式,而每一种模式所用堆栈是不同的,所以初始化堆栈必须初始化这7种模式下的堆栈。具体代码如下:
关于USERMODE等的具体定义为:
3.2.5初始化数据区
内核映像开始总是在Flash里面的,其中RO部分可以在Flash中执行,也可以转移到RAM中执行,而RW和ZI必须转移到RAM中执行。所以所谓数据区初始化就是完成必要的部分从Flash到RAM的数据传输和内容清零。
具体代码如下:
3.2.6跳转到C程序的Main()函数
这是Bootloader的Stage1部分的最后一个环节,是改变处理器模式,转入到C程序的人口操作。
具体代码如下:
3.2.7 Main()函数的具体实现
这部分是实现Bootloader的Stage2的功能,其文件功能为初始化系统频率、初始化I/O端口、初始化中断处理程序表、初始化串口、其他硬件的初始化、进入主程序。
Main()函数的主要代码如下:
4程序的在线仿真和烧写
4.1 程序的在线仿真
以上Bootloader程序通过ADS软件和JTJAG口在目标板上进行仿真,其步骤如下: a)在ARM Developer Suite 1.2中打开boot.mcp工程文件。 b)对打开的boot.mcp工程文件下的所有汇编语言及C语言文件进行编译。 c)使目标板上电,打开ARM9-JTAG调试代理,软硬件连接正确将检测到ARM9内核。打开超级终端。 d)在AXD中下载并运行编译后生成的Boot.axf文件。
此时在显示器上显示目标板的启动信息。
4.2将程序固化到Flash中并在目标板上运行
a)进行并口驱动的安装与设置,并用JFLASH线将PC并口与目标板连接。 b)将要下载的.bin文件放到与SJF2410.exe同一个目录下,再编辑批处理文件。SJF2410_BIOS.BAT内容为:SJF2410/f:boot.bin。 c)执行批处理文件将bin文件通过JTAG烧写入Flash中。
5 结束语
Bootloader的修改和移植是针对具体的CPU和外围电路进行的,虽然市场上有很多成熟工具,移植起来简单快捷,但都存在一定的局限性,具体表现在代码量大、不够灵活。针对特定的目标板自己编写Bootloader,不仅代码量小,而且灵活性强,便于维护。 |