引言
嵌入式Linux的引导装载程序(Bootloader)是操作系统内核启动之前运行的一段程序,其作用与PC机上的BIOS类似。通过这段程序,将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好正确的环境[1]。Bootloader 与底层硬件相关密切,即每个不同配置的目标板都有不同的Bootloader。对于两块不同的嵌入式板,即使它们使用同一种CPU构建,要想让运行在其中一块上的Bootloader程序也能够运行在另一块板子上,通常也都需要修改Bootloader源程序。
嵌入式系统的硬件部分不可能是完全一致的,不可能有通用的bootloader。因此,需要针对硬件系统进行有关引导程序的设计。对于嵌入式系统来说,引导程序比较复杂,一般采用对基本符合硬件体系要求的现有引导程序进行移植,然后加以应用的方法设计引导程序。本文我们选择功能强大的U-BOOT进行移植。
1.U-BOOT简介
U-BOOT,全称Universal Boot Loader,是德国DENX小组开发的用于多种嵌入式CPU的Bootloader引导程序,遵循GPL条款的开放源码项目。U-Boot是在 ppcboot以及armboot的基础上发展而来,现在已经非常成熟与稳定,在许多嵌入式系统开发过程中被采用。目前支持的目标操作系统包括 VxWorks、QNX、RTEMS、NetBSD、Lynxos等。就目前来看,U-BOOT对PowerPC系列处理器支持最丰富,同时还支持 MIPS,x86,ARM,Nios,XScale等诸多常用系列的处理器。U-BOOT对Linux的支持非常完善,是嵌入式Linux Bootloader的最佳选择。
U-BOOT支持的主要功能:
◆系统引导——支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统,从Flash中引导压缩或非压缩系统内核。
◆基本辅助功能——强大的操作系统接口功能,可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤其对Linux支持最强劲。
◆设备驱动——串口、SDRAM、以太网、PCI、RTC等驱动支持。
◆上电自检功能——自动检测FLASH、SDRAM选型及使用情况。
2.U-boot的启动流程[2]
从操作系统的角度看,Bootloader的总目标就是正确的调用内核来执行。由于Bootloader的实现依赖于CPU的体系结构,因此U-BOOT启动大多数分为stage1和stage2两大部分。
第一阶段主要包含依赖于CPU的体系结构硬件初始化代码,通常都用汇编语言来实现。U-BOOT的stage1如图1所示。通常包括以下步骤:
①基本的硬件设备初始化(屏蔽所有的中断、关闭处理器内部指令/数据cache等)。
②为加载Bootloader的Stage2准备空间。
③如果是从某个固态存储媒质中,则拷贝Bootloader的stage2到RAM空间中。
④设置好堆栈。
⑤跳转到stage2的C程序入口点。
第二阶段通常用C语言完成,以便实现更复杂的功能,也使程序有更好的可读性和可移植性。这个阶段的任务有: ①初始化本阶段要使用到的硬件设备。②检测系统内存映射。③将kernel映像和根文件系统映像从flash上读到RAM空间中。④为内核设置启动参数⑤调用内核。[page]
U-boot可执行映像 |
移植前需要对存储器的地址空间进行了解。操作系统内核可以通过U—BOOT下载到SDRAM中,调试完毕后可以将内核烧写到FLASH中,在本目标板中选用的是uclinux嵌入式操作系统,在存储器空间的分配见图2和图3。其中图2为在FLASH中的存储器空间分布。图3为启动后在SDR AM中的存储器分布。
如图所2示,FLASH存储器空间大小为2M,SDRAM大小为8M。系统上电复位后从0x00000000地址处开始执行代码start.s(即第一阶段),这一部分代码运行在FLASH中。主要完成必要的寄存器设置.,中断向量表,堆栈初始化等,并将第二阶段拷贝到SDRAM地址 0x0c120000处,然后从第二阶段(即跳转到start-armboot函数)开始执行,调用各种init函数,完成第二阶段要使用的硬件设备初始化工作(主要是板级初始化),最后跳转到main-loop函数(属第二阶段)中,负责接受用户命令,然后将其分发给相应的处理函数[3]。
3.U-Boot移植操作
要得到下载到目标板的U-BOOT二进制启动代码,需要对下载的U-BOOT进行编译。建立交叉编译移植开发环境,主机端(PC)开发平台选用linux操作系统,使用交叉编译工具为arm-elf-tools-20030314.sh。
移植U-BOOT到新的开发板上仅需修改与硬件相关的部分即可。主要包括二个方面的移植,第一层是针对CPU的移植,第二层是针对BOARD的移植[4]。为了减少移植工作量,我们在include/config目录下选一个和要移植的硬件相似的开发板,我们选择了B2开发板,在board目录下创建一个myboard目录,把B2板目录下的文件拷贝过来,修改文件名即可。
本系统开发板主要由S3C44B0嵌入式微处理器、2MB的Flash(SST39VF160)、8MB的SDRAM(HY57V641620)、4个LED以及ARM JTAG接口组成。该开发板上与S3C44B0相关部分的功能框图如图1所示。
U-Boot移植主要修改的文件:
针对本文提供的主板硬件资源,从移植U-BOOT最小要求,U-BOOT能正常启动的角度出发,主要考虑修改如下文件:u-boot根目录下的 Makefile文件,include目录下的myboard.h头文件,board目录下的myboard.c文件,cpu/s3c44b0目录下的文件。移植操作中文件修改的具体操作为:
⑴cpu/s3c44b0目录下
◆start.s文件的修改。Start.s是汇编语言编写的U-BOOT程序入口代码,完成对底层硬件的初始化,这个文件的主要任务是设置处理器状态、初始化中断和内存时序等,并确定是否需要对整个U-BOOT代码重定位,最终从Flash中跳转到定位好的内存位置执行。具体修改内容如下。
①设置WTCON=0x0,禁止看门狗定时器,避免处理器强行复位。
②设置INTMSK=0X7ffffff,禁止所有中断。Bootloader的执行过程中不必响应任何中断。
③根据嵌入式微处理器的工作主频,修改宏CONFIG_S3C44B0_CLOCK_SPEED,使处理器能够正常工作,本文的目标板S3C44B0处理器工作主频为66MHZ。
④设置PLLCON寄存器。PLLCON锁相环控制寄存器中存储有计算系统时钟的相关参数,为了产生正确的系统时钟,必须根据外接晶振频率和处理器工作主频确定各个倍频数。
◆serial.c文件。这个文件初始化串口,主要是对UART相关的寄存器进行配置。串口的波特率不需要修改,直接用B2板的串口驱动即可。
⑵board/myboard目录下
◆myboard.c文件。这个文件主要是SDRAM的驱动程序,S3C44B0提供有SDRAM控制器,与一些CPU需要UPM表编程相比,它只需进行相关寄存器的设置即可。
◆flash.c文件。Flash驱动程序就在这个文件中。Flash存储器的烧写与擦除一般不具有通用性,跟具不同型号的存储器做出相应的修改。 Snds110嵌入式系统板选用的是SST39VF160,所以用snds110目录下的flash.c替换原来的flash.c,使FLASH芯片正常工作。
◆memsetup.s文件。memsetup.s代码是对存储器空间的初始化,在start.s中被调用。修改内存映射相关参数,SDRAM的刷新速度等,根据不同嵌入式系统版本修改。[page]
⑶include/configs目录下
◆myboard.h头文件。此文件是目标板的头文件,大多数寄存器参数是在这一文件中设置完成的。为了使串口能够正常工作,需要设置正确的波特率,本嵌入式板波特率为115200bps.根据片上资源配置,修改内存映射相关参数。该头文件里还定义了U-BOOT的一些环境变量,这时可以不用修改,U-BOOT启动后可以通过setenv命令来设定。其它参数与启动操作系统内核有关,需要与内核启动参数相匹配。
⑷Makefile文件修改
在U-BOOT根目录下的makefile文件进行修改,加入:
Myboard_config:unconfig
@./mkconfig $ (@:_config=) arm S3C44B0 myboard
其中“arm”是CPU的种类,S3C44B0是ARM CPU对应的代码目录,myboard是自己开发板对应的目录。
除了以上修改外,可以根据目标板和实际开发需要,添加一些其它功能支持,如以太网、LCD、NVRAM等。与串口和SDRAM调试相比,在已有的基础上,添加这些功能还是较容易的。大多只是在参考现有源码的基础上,进行一些修改和配置[5]。
4.U-BOOT编译与运行
配置好以后,进入U-BOOT主目录,重新编译u-boot代码,运行命令:
#make myboard_config
#make
编译成功,将生成三个文件:
u-boot——ELF格式的文件,可以被大多数Debug程序识别。
u-boot.bin——二进制bin文件,纯碎的U-BOOT二进制执行代码,不保存ELF格式和调试信息。这个文件用于烧到用户的开发板中。
u-boot.srec——Motorola S-Record格式,可以通过串口下载到开发板中。
将得到的u-boot.bin文件借住于FLASH芯片烧写工具Flashpgm通过JTAG口下载到目标板后,检查U-BOOT能否正常工作[6]。如果能从串口输出正确的启动信息,就表明移植基本成功。若没有按任意键,U-BOOT将自动加载操作系统内核和文件系统。若按下任意键,U-BOOT停止自动加载,进入U-BOOT命令行,可以输入命令进行调试。
5.结束语
本文创新点:根据U-BOOT的运行机理,在硬件资源固定,不改变Bootloader框架的前提下,对与目标板硬件相关的代码进行移植,使之能够成功的引导嵌入式操作系统。通过分析引导装载程序在uclinux中的启动流程与运行机理,结合U-BOOT,设计并实现了基于S3C44B0X目标板上的bootloader。在移植过程中,需要对Bootloader的结构和工作流程,以及相关硬件有一定的了解,灵活的选用bootloader,根据具体情况进行裁减,最大程度发挥bootloader的功能,根据嵌入式目标板与CPU等硬件配置对相关代码进行了修改。目前移植后的U-BOOT能够稳定的运行在嵌入式目标板上,并能顺利的引导嵌入式Linux系统,完全实现了设计目的,达到了嵌入式系统设计的要求。
参考文献:
1. 詹荣开.嵌入式系统Bootloader技术内幕[DB/OL]. http://www.zidonghua.com.cn /news/detail.asp?id=9641
2. 孙天泽.嵌入式设计及Linux驱动开发指南[M].北京:电子工业出版社,2005.
3. 张进,姜威.U-BOOT的启动流程及移植[J].国外电子元器件,2005,5: 11-14
4. 张永强,田紫君.基于ARM的HM30C7202平台的嵌入式Linux移植[J].微计算机信息,2005
5. Karim Yagbmour.构建嵌入式LINUX系统[M].北京:中国电力出版社,2004.
6. 李程远,刘文峰,李善平.ARM Linux在EP7312上的移植[J].计算机工程与设计,2003,24970: 73-77
上一篇:基于SEP3203处理器的BSP的实现探讨
下一篇:基于AC48304的嵌入式多路语音记录器
推荐阅读最新更新时间:2024-03-16 12:59