基于AT91RM9200的BootLoader设计与实现
作者:佚名; 更新时间:2014-12-05
摘 要:随着微电子技术和计算机技术的发展,微处理器芯片的功能越来越强大,信捷职称论文写作发表网,嵌入式技术也越来越受到人们的关注。但是在嵌入式系统设计过程中,Boot Loader的设计是遇到的第一个难点。本文以AT91RM9200为例,介绍Boot Loader的一般实现流程以及功能更为强大的u-boot的移植。
关键词:BootLoader AT91RM9200 u-boot移植 嵌入式系统
一、引言
嵌入式系统是以应用为中心,以计算机技术为基础,软硬件可裁减来适应系统对功能、可靠性、成本、体积、功耗要求严格的专用计算机系统。随着各种微处理器功能越来越强大以及软件上操作系统的支持,使得整个嵌入式系统拥有了完整构架。近年来各种嵌如式操作系统也是层出不穷以适应各种不同功能的微处理器。然而如何加载操作系统却成了大家学习嵌入式系统遇到的第一个拦路虎。这就是BootLoader,他把嵌入式硬件和嵌入式操作系统衔接起来,对于嵌入式系统后续软件的开发十分重要,在整个开发中也占有相当大的比例。BootLoader的功能是引导和加载内核镜像,是在系统复位后执行的第一段代码,BootLoader首先完成系统硬件的初始化,包括时钟的设置、存储区映射、设置堆栈指针,以及完成处理器和周边电路和设备正常运行所要的初始化工作,创建内核需要的信息并将系统的软硬件带到一个合适的状态,然后跳转到操作系统内核入口,将系统控制权交给操作系统,在此之后系统的运行和BootLoader再无任何关系。u-boot是当前比较流行、功能强大的BootLoader,可以支持多种体系结构。
二、BootLoader主要任务及典型结构
一个嵌入式Linux系统从软件的角度看通常可以分为四个层次:引导加载程序、Linux内核、文件系统、用户应用程序。如图2.1所示
BootLoader是依赖于硬件实现的,特别是在嵌入式系统中。不同的体系结构需求的BootLoader是不同的;除了体系结构,BootLoader还依赖于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式板而言,即使它们基于相同的CPU构建,运行在其中一块电路板上的Boot Loader,未必能够运行在另一块电路开发板上。
BootLoader的启动过程可以是单阶段的,也可以是多阶段的。通常多阶段的BootLoader能提供更为复杂的功能,以及更好的可移植性。从固态存储设备上启动的BootLoader大多数是二阶段的启动过程,也即启动过程可以分为stage 1和stage 2两部分。
用户应用程序
文件系统
Linux内核
引导加载程序
图 2.1
依赖于CPU体系结构的代码,比如设备初始化、开关中断、初始化时钟等,通常都放在stage 1中,而且都用汇编来实现,以达到短小精悍的目的。而stage 2通常用C语言来实现,这样可以实现较复杂的功能,而且代码有较好的可读性和可移植性。
Boot Loader的stage1通常包括以下步骤:
(1)初始化各种模式的堆栈和寄存器。
(2)初始化系统时钟、系统总线速率及一些系统常量。
(3)初始化存储控制器,如FLASH和SDRAM的大小、类型、数据宽度、地址范围等
(4)初始化各种I/O口和各种控制器。
(5)为stage2做准备。
Boot Loader的stage2通常包括以下步骤:
(1)初始化本阶段要使用到的硬件设备。
(2)检测系统内存映射(memory map).
(3)将内核映像和根文件系统映像从flash拷贝SDRAM中。
(4)为内核设置启动参数。
(5)调用内核。
综合起来,整个BootLoader的实现流程如图2.2所示:
基本硬件初始化
拷贝阶段2镜像至RAM
扩展功能所需硬件初始化
图 2.2
三、BootLoader的实现
u-boot是当前比较流行、功能强大的BootLoader,而且是通用的免费开放源码的Boot Loader程序,可以支持多种体系结构。u-boot是由德国的工程师Wolfgang Denk从8XXROM代码发展而来的。目前最新版本是u-boot-1.1.4。现以ATMEL公司生产的AT91RM9200为例,介绍如何在以AT91RM9200为核心处理器的最小系统上的u-boot-1.1.0的移植。本系统包括:
flash :4MB
sdram:32MB
1.u-boot源代码目录结构
(1)board:和一些已有开发板的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。
(2)common:与体系结构无关文件,实现各种命令的C文件。
(3)cpu:CPU相关文件,其中的子目录都是以u-boot所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等;interrupt.c设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是U-BOOT启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为进入C程序奠定基础。
(4)disk:disk驱动的分区处理代码。
(5)doc:u-boot的说明文档。
(6)drivers:通用设备驱动程序,比如各种网卡、支持CFI的Flash、串口和USB总线等。
(7)fs:支持文件系统的文件,U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。
(8)include:头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。
(9)net:与网络有关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。
(10)lib_arm:与ARM体系结构相关的代码。
(11)tools:创建S-Record格式文件 和U-BOOT images的工具。
2.对u-boot-1.1.0的修改和移植
为了使u-boot-1.1.0支持新的开发板,u-boot已经支持的开发板中选择一种接近的进行修改。由于u-boot- 1.1.0已经支持ARM-920T内核,所以选择基于ARM-920T内核的at91rm9200为模板。相关的源代码在board/at91rm9200/下。
(1)与at91rm9200相关的u-boot代码
①在include/configs/at91rm9200dk.h 它包括开发板的CPU、系统时钟、SDRAM、Flash系统及其它相关配置信息。
#define PHYS_SDRAM 0X20000000
#define PHYS_SDRAM_SIZE 0X2000000
#define PHYS_FLASH_1 0x10000000
#define PHYS_FLASH_SIZE 0x400000
②在include/asm-arm/AT91RM9200.h, 该文件描述了at91rm9200寄存器的结构及若干宏定义。具体内容要参考文献4。暂不用修改。
③在include/flash.h中,该文件定义了flash的属性
④)在cpu/at91rm9200/目录下别为cpu.c、interrupts.c和serial.c等文件。
⑤在board/at91rm9200dk/目录下分别为flash.c、at91rm9200dk.c, config.mk, Makefile,u-boot.lds。
⑥flash.c : u-boot读、写和删除Flash设备的源代码文件。由于不同开发板中Flash存储器的种类各不相同,所以,修改flash.c时需参考相应的Flash芯片手册。它包括如下几个函数:
unsigned long flash_init (void ),Flash初始化;
void flash_print_info (flash_info_t *info),打印Flash信息;
int flash_erase (flash_info_t *info, int s_first, int s_last),Flash擦除;
volatile static int write_dword (flash_info_t *info, ulong dest, ulong data),Flash写入;
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt),从内存复制数据。
⑦u-boot.lds :linker scripte, 设置u-boot中各个目标文件的连接地址。
(2)网卡设备控制程序
在drivers/目录中网口设备控制程序cs8900, bcm570x等, 还可以添加其他网卡驱
int eth_init (bd_t *bd) : 初始化网络设备;
void eth_halt (void) : 关闭网络设备;
int eth_send (volatile void *packet,int len) : 发送数据包;
int eth_rx (void) : 接收数据包。
(3)修改Makefile文件
在u-boot-1.0.0/Makefile中加入
at91rm9200dk_config : unconfig
./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk
其中“arm”是CPU的种类, at91rm9200 是ARM CPU对应的代码目
at91rm9200dk是自己开发板对应的目录。
四、生成目标文件
先运行make clean,
[zeng@localhost u-boot-1.1.0]$make clean
然后运行at91rm9200dk_config,
[zeng@localhost u-boot-1.1.0]$ make at91rm9200dk_config
Configuring for at91rm9200 board...
再运行make,
[zeng@localhost u-boot-1.1.0]$make
之后会生成三个文件:
1.u-boot——ELF格式的文件,可以被大多数Debug程序识别;
2.u-boot.bin——二进制bin文件,纯粹的U-BOOT二进制执行代码,不保存ELF格式和调试信息。这个文件一般用于烧录到用户开发板中;
3.u-boot.srec——Motorola S-Record格式,可以通过串行口下载到开发板中。
以上工作完成我们可以通过串口将u-boot.bin下载到主板的SDRAM中,它会自动执行, 并出现uboot>,这里我们可以通过串口把u-boot.bin, u-boot.bin.gz下载到主板,再用u-boot的提供的写flash功能分别把u-boot.bin, u-boot.bin.gz写入到flash中,完成以上工作后,对主板跳线选择片外启动,板子复位后会自动启动u-boot
五、结语
BootLoader是操作系统和硬件的枢纽,它为操作系统内核的启动提供了必要的条件和参数。在移植过程中,开发人员除了要掌握BootLoader 的结构和工作流程外,还要对相关硬件有一定了解。目前,移植的u-boot已经能够稳定地运行在开发板上,而且可以通过Flash和网络加载内核和文件系统,为后续开发,特别是驱动程序的开发奠定了良好基础。
参考文献
[1] 李驹光,聂雪媛,王兆卫.ARM应用系统详解.北京:清华大学出版社,2004.
[2] 詹容开.BootLoader技术内幕.
[3] .
[4] 杜春雷.ARM体系结构与编程[M].北京:清华大学出版社.2004.
[5] AT91RM9200 User Manual. ATMEL , 2005
关键词:BootLoader AT91RM9200 u-boot移植 嵌入式系统
一、引言
嵌入式系统是以应用为中心,以计算机技术为基础,软硬件可裁减来适应系统对功能、可靠性、成本、体积、功耗要求严格的专用计算机系统。随着各种微处理器功能越来越强大以及软件上操作系统的支持,使得整个嵌入式系统拥有了完整构架。近年来各种嵌如式操作系统也是层出不穷以适应各种不同功能的微处理器。然而如何加载操作系统却成了大家学习嵌入式系统遇到的第一个拦路虎。这就是BootLoader,他把嵌入式硬件和嵌入式操作系统衔接起来,对于嵌入式系统后续软件的开发十分重要,在整个开发中也占有相当大的比例。BootLoader的功能是引导和加载内核镜像,是在系统复位后执行的第一段代码,BootLoader首先完成系统硬件的初始化,包括时钟的设置、存储区映射、设置堆栈指针,以及完成处理器和周边电路和设备正常运行所要的初始化工作,创建内核需要的信息并将系统的软硬件带到一个合适的状态,然后跳转到操作系统内核入口,将系统控制权交给操作系统,在此之后系统的运行和BootLoader再无任何关系。u-boot是当前比较流行、功能强大的BootLoader,可以支持多种体系结构。
二、BootLoader主要任务及典型结构
一个嵌入式Linux系统从软件的角度看通常可以分为四个层次:引导加载程序、Linux内核、文件系统、用户应用程序。如图2.1所示
BootLoader是依赖于硬件实现的,特别是在嵌入式系统中。不同的体系结构需求的BootLoader是不同的;除了体系结构,BootLoader还依赖于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式板而言,即使它们基于相同的CPU构建,运行在其中一块电路板上的Boot Loader,未必能够运行在另一块电路开发板上。
BootLoader的启动过程可以是单阶段的,也可以是多阶段的。通常多阶段的BootLoader能提供更为复杂的功能,以及更好的可移植性。从固态存储设备上启动的BootLoader大多数是二阶段的启动过程,也即启动过程可以分为stage 1和stage 2两部分。
用户应用程序
文件系统
Linux内核
引导加载程序
图 2.1
依赖于CPU体系结构的代码,比如设备初始化、开关中断、初始化时钟等,通常都放在stage 1中,而且都用汇编来实现,以达到短小精悍的目的。而stage 2通常用C语言来实现,这样可以实现较复杂的功能,而且代码有较好的可读性和可移植性。
Boot Loader的stage1通常包括以下步骤:
(1)初始化各种模式的堆栈和寄存器。
(2)初始化系统时钟、系统总线速率及一些系统常量。
(3)初始化存储控制器,如FLASH和SDRAM的大小、类型、数据宽度、地址范围等
(4)初始化各种I/O口和各种控制器。
(5)为stage2做准备。
Boot Loader的stage2通常包括以下步骤:
(1)初始化本阶段要使用到的硬件设备。
(2)检测系统内存映射(memory map).
(3)将内核映像和根文件系统映像从flash拷贝SDRAM中。
(4)为内核设置启动参数。
(5)调用内核。
综合起来,整个BootLoader的实现流程如图2.2所示:
基本硬件初始化
拷贝阶段2镜像至RAM
扩展功能所需硬件初始化
图 2.2
三、BootLoader的实现
u-boot是当前比较流行、功能强大的BootLoader,而且是通用的免费开放源码的Boot Loader程序,可以支持多种体系结构。u-boot是由德国的工程师Wolfgang Denk从8XXROM代码发展而来的。目前最新版本是u-boot-1.1.4。现以ATMEL公司生产的AT91RM9200为例,介绍如何在以AT91RM9200为核心处理器的最小系统上的u-boot-1.1.0的移植。本系统包括:
flash :4MB
sdram:32MB
1.u-boot源代码目录结构
(1)board:和一些已有开发板的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。
(2)common:与体系结构无关文件,实现各种命令的C文件。
(3)cpu:CPU相关文件,其中的子目录都是以u-boot所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等;interrupt.c设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是U-BOOT启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为进入C程序奠定基础。
(4)disk:disk驱动的分区处理代码。
(5)doc:u-boot的说明文档。
(6)drivers:通用设备驱动程序,比如各种网卡、支持CFI的Flash、串口和USB总线等。
(7)fs:支持文件系统的文件,U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。
(8)include:头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。
(9)net:与网络有关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。
(10)lib_arm:与ARM体系结构相关的代码。
(11)tools:创建S-Record格式文件 和U-BOOT images的工具。
2.对u-boot-1.1.0的修改和移植
为了使u-boot-1.1.0支持新的开发板,u-boot已经支持的开发板中选择一种接近的进行修改。由于u-boot- 1.1.0已经支持ARM-920T内核,所以选择基于ARM-920T内核的at91rm9200为模板。相关的源代码在board/at91rm9200/下。
(1)与at91rm9200相关的u-boot代码
①在include/configs/at91rm9200dk.h 它包括开发板的CPU、系统时钟、SDRAM、Flash系统及其它相关配置信息。
#define PHYS_SDRAM 0X20000000
#define PHYS_SDRAM_SIZE 0X2000000
#define PHYS_FLASH_1 0x10000000
#define PHYS_FLASH_SIZE 0x400000
②在include/asm-arm/AT91RM9200.h, 该文件描述了at91rm9200寄存器的结构及若干宏定义。具体内容要参考文献4。暂不用修改。
③在include/flash.h中,该文件定义了flash的属性
④)在cpu/at91rm9200/目录下别为cpu.c、interrupts.c和serial.c等文件。
⑤在board/at91rm9200dk/目录下分别为flash.c、at91rm9200dk.c, config.mk, Makefile,u-boot.lds。
⑥flash.c : u-boot读、写和删除Flash设备的源代码文件。由于不同开发板中Flash存储器的种类各不相同,所以,修改flash.c时需参考相应的Flash芯片手册。它包括如下几个函数:
unsigned long flash_init (void ),Flash初始化;
void flash_print_info (flash_info_t *info),打印Flash信息;
int flash_erase (flash_info_t *info, int s_first, int s_last),Flash擦除;
volatile static int write_dword (flash_info_t *info, ulong dest, ulong data),Flash写入;
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt),从内存复制数据。
⑦u-boot.lds :linker scripte, 设置u-boot中各个目标文件的连接地址。
(2)网卡设备控制程序
在drivers/目录中网口设备控制程序cs8900, bcm570x等, 还可以添加其他网卡驱
int eth_init (bd_t *bd) : 初始化网络设备;
void eth_halt (void) : 关闭网络设备;
int eth_send (volatile void *packet,int len) : 发送数据包;
int eth_rx (void) : 接收数据包。
(3)修改Makefile文件
在u-boot-1.0.0/Makefile中加入
at91rm9200dk_config : unconfig
./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk
其中“arm”是CPU的种类, at91rm9200 是ARM CPU对应的代码目
at91rm9200dk是自己开发板对应的目录。
四、生成目标文件
先运行make clean,
[zeng@localhost u-boot-1.1.0]$make clean
然后运行at91rm9200dk_config,
[zeng@localhost u-boot-1.1.0]$ make at91rm9200dk_config
Configuring for at91rm9200 board...
再运行make,
[zeng@localhost u-boot-1.1.0]$make
之后会生成三个文件:
1.u-boot——ELF格式的文件,可以被大多数Debug程序识别;
2.u-boot.bin——二进制bin文件,纯粹的U-BOOT二进制执行代码,不保存ELF格式和调试信息。这个文件一般用于烧录到用户开发板中;
3.u-boot.srec——Motorola S-Record格式,可以通过串行口下载到开发板中。
以上工作完成我们可以通过串口将u-boot.bin下载到主板的SDRAM中,它会自动执行, 并出现uboot>,这里我们可以通过串口把u-boot.bin, u-boot.bin.gz下载到主板,再用u-boot的提供的写flash功能分别把u-boot.bin, u-boot.bin.gz写入到flash中,完成以上工作后,对主板跳线选择片外启动,板子复位后会自动启动u-boot
五、结语
BootLoader是操作系统和硬件的枢纽,它为操作系统内核的启动提供了必要的条件和参数。在移植过程中,开发人员除了要掌握BootLoader 的结构和工作流程外,还要对相关硬件有一定了解。目前,移植的u-boot已经能够稳定地运行在开发板上,而且可以通过Flash和网络加载内核和文件系统,为后续开发,特别是驱动程序的开发奠定了良好基础。
参考文献
[1] 李驹光,聂雪媛,王兆卫.ARM应用系统详解.北京:清华大学出版社,2004.
[2] 詹容开.BootLoader技术内幕.
[3] .
[4] 杜春雷.ARM体系结构与编程[M].北京:清华大学出版社.2004.
[5] AT91RM9200 User Manual. ATMEL , 2005
热门论文