李向阳,戴学丰,邵林(齐齐哈尔大学黑龙江齐齐哈尔161006)0引言Bootloader是操作系统启动运行之前执行的一段小程序。它是基于特定硬件平台实现的,通过它可以初始化硬件设备,建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核作好准备。嵌入式系统的硬件部分不可能完全一致,由于嵌入式系统需要硬件与软件的配合才能正常工作,因此需要针对硬件系统进行有关引导程序的设计。对于嵌入式系统来说,引导
李向阳,戴学丰,邵 林
(齐齐哈尔大学 黑龙江齐齐哈尔 161006)
0引 言
Bootloader是操作系统启动运行之前执行的一段小程序。它是基于特定硬件平台实现的,通过它可以初始化硬件设备,建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核作好准备。嵌入式系统的硬件部分不可能完全一致,由于嵌入式系统需要硬件与软件的配合才能正常工作,因此需要针对硬件系统进行有关引导程序的设计。对于嵌入式系统来说,引导程序比较复杂,一般采用在基本符合硬件体系要求的现有引导程序的基础上进行修改,然后通过应用的方法设计引导程序,这就是引导程序的移植。
1 U-boot介绍
U-boot(Universal Boot Loader)源自DENX软件工程中心的Wolfgang Denk,基于8xxrom的源码创建的PPCBoot工程,遵循GPL条款的开放源码项目,已经可以支持PowerPC,ARM,X86,MIPS等体系结构上的上百种开发板。U-boot提供:启动加载(Boot Loading)和下载(Down Loading)两种操作模式。并具有大型Bootloader的全部功能。主要特性有:SCC/FEC以太网支持;BOOTP/TFTP引导——IP,MAC预置功能;在线读写FLASH,DOC,IDE,I2C,E2ROM,RTC;支持串行口kermit,S-record下载代码;识别二进制、ELF32,plmage格式的Image;对Linux引导有特别的支持;监控(minitor)命令集;具有读写I/O、内存、寄存器、外设测试等功能。
U-boot还支持多种文件系统,如cramfs,ext2,fat,reiserfs和jffs2等;支持多种嵌入式操作系统内核,如Linux,NetBSD,VxWorks,QNX,RTEMS,ARTOS和LynxOS等,并对Linux引导有特别的支持。另外,U-boot还提供单任务软件运行环境,可以在没有操作系统的情况下动态加载和运行独立的应用程序,这些独立的应用程序可以利用U-boot提供控制台的I/O函数、内存申请和中断服务等。
2 U-boot启动流程
对ARM7核处理器,U-boot启动流程主要体现在3个文件上,即start.s.lib_arm/board.C和U-boot/common/main.C。下面详细分析启动流程。
2.1 start.s文件
startl.s文件主要是CPU的初始化,用汇编语言编写,其主要代码流程如下:
(1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(FLASH)的0x0地址,在start.s文件中有如下语句:
因此,必须通知编译器使其知道这个人口,该工作可通过修改连接器脚本文件U-boot.lds来完成。
(2)设置异常向量(Exception Vector)。异常中断向量表是U-boot与操作系统内核发生联系的关键所在之一。即使操作系统内核已经得到处理器的控制权运行,一旦发生中断,处理器还是会自动跳转到从0x0地址开始的异常中断向量表中的某个位置(依据于中断类型)读取指令运行的。
(3)设置CPU的速度、时钟频率及中断控制寄存器。依次为关闭看门狗计时器,屏蔽所有中断,配置时钟(包括3个寄存器:PLLCON,CLKON,LOCK-TIME)。
(4)初始化内存控制器。内存控制器初始化主要通过设置13个从1c80000开始的特殊功能寄存器来完成,包括外部数据总线宽度、访问周期、定时的控制信号等。
(5)将ROM中的程序复制到RAM中。首先利用PC取得BootLoader在FLASH的起始地址,再通过标号之差计算出这个程序代码的大小。通过寄存器(r3~r10)为复制的中间媒介将代码复制到RAM中。
(6)初始化堆栈。进入各种模式设置相应模式的堆栈。
(7)转到RAM中执行。该工作可使用指令ldr pc来完成,即ldr pc,_start_armboot。
2.2 lib arm/board.c文件()
U-boot/Lib arm/board.c中的start_armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,该函数主要是调用一系列的初始化函数。进行各种初始化设置。该函数完成的操作是:
(1)调用一系列的初始化函数,包括:cpu_init(CPU相关的设置),board_init(板子相关的设置),interrupt_init(中断设置),env_init(环境变量设置),init_baudrate(baud参数设置),serial_init(串口初始化),console_init_f(控制台设置),display_banner(显示标题),dram_init(可用内存配置);
(2)初始化FLASH设备;
(3)初始化系统内存分配函数;
(4)如果目标系统拥有NAND设备,则初始化NAND设备;
(5)如果目标系统有显示设备,则初始化该类设备;
(6)初始化相关网络设备,填写IP、MAC地址等。
2.3 U-boot/common/main.c文件
完成上述初始化后,进入命令循环(即整个boot的工作循环),代码为:
3移植过程
在此使用的是创维特公司的EB4480开发板,系统相关配置如下:
处理器:SamsungS3C44B0X,工作频率60 MHz; FLASH地址:0x00000000~ 0x00400000(1X2MX16位); SDRAM地址:0x0c000000~ 0x0c800000(1X4MX16位); CS8900A地址:0x04000300~0x0400030f; 2个串口,4个可编程的LED以及14针JTAG接口。
为了降低移植的难度,在移植过程中,一般都是选择与目标处理器以及目标板最接近的一个版本进行移植。因此选择B2进行移植。从U-boot的官方网站上下载最新版的源代码,目前最高版本为1.3.3。移植主要修改的文件有:cpu/s3c44b0/start.s,board/dave/ b2/lowlevel init.s,board/dave/b2/b2.c,board/dave/common/FLASH.c,include/configs/b2.h,board/dave/b2/config.mk。
3.1 cpu/s3c44b0/start.s文件
start.s是汇编语言编写的U-boot程序入口代码,主要包括处理器内部各个寄存器的初始化以及代码的搬移。主要完成设置处理器状态、初始化中断、堆栈、内存控制器等,并确定是否需要对整个U-boot代码重定位,最终从FLASH中跳转到定位好的内存位置执行。下面对其中一些代码进行针对性的分析。
(1)设置WTCON=0x0,禁止看门狗定时器,避免处理器强行复位;
(2)设置INTMSK=0x7ffffff,禁止所有中断,Bootloader的执行过程中不必要响应任何中断;
(3)根据嵌入式微处理器工作主频,修改宏CON-FIG_S3C4480_CLOCK_SPEED=60 MHz,使处理器能够正常工作;
(4)设置PLLCON=0x34031,PLLCON锁相环控制寄存器中储存有计算系统时钟的相关参数,为了产生正确的系统时钟,必须根据外接晶振频率和处理器工作主频确定各个倍频系数。
3.2 board/dave/b2/lowlevel init.S文件
该文件由汇编代码完成,主要包括SDRAM工作参数的设置,以及处理器内存控制器的初始化,参数需要根据SDRAM芯片资料进行设置。
3.3 board/dave/b2/b2.C文件
该文件中的代码主要是SDRAM的驱动程序,并完成了处理器各个I/O口的初始化,根据具体的目标板进行适当的修改即可。
3.4 board/dave/common/FLASH.c
这个文件是FLASH的驱动程序。FLASH存储器的烧写与擦除一般不具有通用性,根据不同型号的存储器做出相应的修改。EB4480开发板采用的是Intel28F320C3B,总共71个块,1~8每块大小是8 KB,9~71每块大小是64 KB,它的特殊性决定了需要对write_word(),FLASH_get_size(),FLASH_print_info(),FLASH_get_offsets(),FLASH_erase(),进行修改,具体内容如下:
3.5 include/configs/b2.h文件
该文件中包含了B2目标板的一些配置的宏定义,主要有系统工作频率、环境变量缓冲区长度、串口波特率、FLASH起始地址及容量、DRAM起始地址及容量、环境变量保存位置、FLASH读/写命令字、网络芯片的基地址、目标板IP地址、硬件地址MAC、主机IP地址、内核装载地址、交互操作命令等。
3.6 board/dave/b2/config.mk文件
U-boot将其代码从FLASH复制到SDRAM的位置在0x0c700000处,修改TEXT BASE=0x0c700000。
U-boot是在Linux环境下开发的,因此需要在Linux下进行编译,使用的操作系统为Fedora core 7,从http://opensrc.see.samsung.com/download/arm-elf-tools-20040427.sh下载arm-elf-tools-20040427.sh,使用的编译器为arm-elf-gcc,在U-boot根目录下对其中的makefile文件进行相应的修改,然后在命令行中运行以下指令:
#make disclean #make B2_config #make
编译连接后生成U-boot,U-boot.bin,U-boot.srec,其中的U-boot.bin是二进制bin文件,纯粹的U-boot二进制执行代码,不保存ELF格式和调试信息,这个文件用于烧写到用户的开发板中。通过创维特集成开发环境自带的FLASH烧写工具载入到SDRAM中运行,从超级终端显示U-boot的启动信息,分别试验erase,cp,printenv,saveenv等命令,并检测对FLASH的操作;使用tftp命令,以检测网口下载功能,然后装载操作系统内核,完成以上任务则移植成功。经过以上步骤移植的U-boot已经在自己开发的ARM板上顺利地引导了μClinux操作系统。
4结 语
Bootloader是连接系统硬件和操作系统的桥梁,这里根据U-boot的运行机制,在硬件资源固定,不改变Bootloader框架的前提下,对与目标板硬件相关的代码,特别是FLASH芯片Intel 28F320C3B的代码进行修改,成功移植到EB44B0开发板上,并且结合U-boot和μClinux的启动流程与运行机制,成功设计并实现了在基于S3C44B0目标板上引导嵌入式操作系统。在移植过程中,要熟悉U-boot的组织结构和工作流程,对相关的硬件资源有一定的了解,根据实际情况进行裁减,灵活选用功能模块。目前,移植后的U-boot能够稳定地运行在嵌入式目标板上,并能顺利地引导嵌入式μClinux系统,已成功应用在智能机器人的避障系统中。
|