Cortex-A8的Bootloader设计与实现※

2015-07-03 03:33叶茂李智任和
单片机与嵌入式系统应用 2015年2期
关键词:源码环境变量网卡

叶茂,李智,任和

(四川大学 电子信息学院,成都610064)

引 言

随着电子行业日新月异的发展,ARM处理器凭借自身高性能、低成本、低功耗等特点,广泛应用于消费电子、数字家电、工业生产等领域中[1]。Cortex-A8为Cortex系列中的“A”系列,采用ARM v7架构,主要面向搭载操作系统、高性能的应用领域。Bootloader是系统上电后执行的第一段代码,其功能类似于电脑的BIOS[2]。简单来说,Bootloader的工作主要有两点:其一是初始化底层硬件资源,为操作系统启动提供必要的环境;其二是从存储设备中读取操作系统镜像并启动[3-4]。但为了方便后期开发,往往要为Bootloader添加其他的功能,如支持串口打印调试信息、NFS网络下载、根文件系统烧写等[5]。本文以u-boot-2013.01为源码包,设计了一个基于S5PV210平台,功能齐全且高效稳定的Bootloader。

1 硬件平台

1.1 S5PV210简介

S5PV210是三星公司推出的一款基于Cortex-A8架构的高性能应用处理器。该处理器支持ARM v7指令集,具有32位内部总线结构,主频最高可达1 GHz,另外还支持挂接LPDDR1、LPDDR2和DDR2类型的RAM,Flash方面可选择NAND Flash或NOR Flash等。不仅如此,该处理器还提供了包括串口、LCD、I2C、SPI、USB、HDMI等丰富的外部接口资源。目前S5PV210已经广泛应用于智能手机和平板电脑之中。

1.2 S5PV210的启动方式

S5PV210支持多种启动方式,启动流程如图1所示。

图1 S5PV210的启动流程

S5PV210的启动过程由BL0、BL1和BL2(BL为Bootloader的简称)3部分代码实现,其中BL0在出厂时已经被固化到64 KB的iROM中。S5PV210上电后首先执行BL0,该段代码主要负责一些简单的初始化工作,如关看门狗、初始化ICache等;然后BL0会根据硬件设置判断使用何种方式启动,并将BL1从启动设备(OneNand、Nand Flash、USB、UART、SD card等)拷贝到Internal SRAM的BL1区中;最后BL0会比较一个校验值,如果相等则跳转到BL1中继续执行,否则转入其他启动方式。该校验值存在于BL1的头部,大小为16字节。

开发人员一般会单独编写一个工具为BL1编译出的二进制文件添加头部。其校验值(checksum)的计算方法如下:

由于BL1的大小被限制为16 KB,所以一般情况下BL1负责的工作也不多。BL1被执行后首先初始化系统时钟、内存、串口等,然后将BL2代码拷贝到Internal SRAM的BL2区中并跳转执行。实际上SRAM的BL2区的大小只有80 KB,但很多情况下BL2代码的大小远远超过80 KB,所以将BL2代码拷贝到SRAM中意义不大。更好的做法是直接将BL2拷贝到容量更大的内存中,不过在拷贝之前一定要先初始化好系统时钟和内存。BL2是整个Bootloader的主体部分,因此它需要完成更多的初始化工作,例如初始化网卡、Flash等,之后BL2读取操作系统镜像到内存中运行。一般把操作系统镜像放到Flash上,也可以放到SD卡上,根据具体的开发平台而定。

2 软件平台

2.1 U-Boot介绍

U-Boot(全称 Universal Bootloader)是Bootloader的一种,其他常见的Bootloader还有RedBoot、vivi等。与它们相比,U-Boot具有代码开源、可靠性和扩展性较高等优点。另外,对于类似于Nand Flash、Nor Flash、网卡、LCD等硬件资源,U-Boot已经抽象出与硬件平台无关的代码作为设备驱动源码提供给开发者。对于与硬件平台相关的代码,U-Boot将其定义成宏并保留在配置文件中,开发者往往只需要修改这些宏的值就能成功使用这些硬件资源,让移植工作变得十分简单。

2.2 U-Boot中几个比较重要的源文件

U-Boot的源码包含有上千个源文件,但经过分析之后,可以找出如下几个比较重要的源文件(括号中为该源文件所在源码包的位置):

(1)start.S(arch\arm\cpu\armv7\start.S)

通过分析U-Boot的链接文件可以发现,start.S是UBoot上电后执行的第一个源文件。该源文件包括定义了异常向量入口、相关的全局变量、禁用L2缓存、关闭MMU等,之后跳转到lowlevel_init()函数中继续执行。

(2)lowlevel_init.S(board\samsung\smdkv210\lowlevel_init.S)

该源文件用汇编代码编写,其中只定义了一个函数lowlevel_init()。该函数实现对平台硬件资源的一系列初始化过程,包括关看门狗、初始化系统时钟、内存和串口。

(3)mem_setup.S(board\samsung\smdkv210)

该源文件包含对内存进行初始化的汇编源码。

(4)board.c(arch\arm\lib\board.c)

该源文件是用C语言编写的,主要实现了U-Boot第二阶段启动过程,包括初始化环境变量、串口控制台、Flash和打印调试信息等,最后调用main_loop()函数。

(5)smdkv210.h(include\configs\Smdkv210.h)

S5PV210平台的配置文件,该源文件定义了一些与CPU或者外设相关的参数,这些参数都是用宏来定义的。

2.3 U-Boot启动的一般流程

2.3.1 第一阶段初始化

U-Boot的启动过程分为两个阶段:第一阶段主要由汇编代码实现,负责对CPU及底层硬件资源的初始化;第二阶段用C语言实现,负责使能Flash、网卡和引导操作系统等。第一阶段启动流程如图2所示。

图2 U-Boot第一阶段启动流程

上电后,U-Boot首先会设置CPU为管理模式、禁用L1缓存、关闭MMU和清除Caches,之后调用底层初始化函数lowlevel_init()。该函数实现略——编者注。

初始化完成之后,U-Boot首先调用一个拷贝函数将BL2拷贝到内存地址为0x 3FF0 0000处,然后跳转到该位置执行BL2。在U-Boot中,BL1和BL2是基于相同的一些源文件编译生成的。开发者在编写代码时需要使用预编译宏CONFIG_SPL_BUILD来实现BL1和BL2不同的功能。其拷贝函数实现略——编者注。

2.3.2 第二阶段初始化

进入第二阶段后,U-Boot首先声明一个gd_t结构体类型的指针指向内存地址(0x 4000 0000~GD_SIZE)处。0x 4000 0000为内存结束地址,GD_SIZE为结构体gd_t的大小,这样相当于在内存最顶端分配了一段空间用于存放一个临时结构体gd_t。该结构体在global_data.h中被定义,U-Boot用它来存储所有的全局变量。之后U-Boot会调用board_init_f()和board_init_r()两个函数进一步对底板进行初始化。

(1)board_init_f()

进入board_init_f()之后,U-Boot首先设置之前分配的临时结构体,然后开始划分内存空间,其内存分配状态如图3所示。

图3 U-Boot内存分配状态

从图3中可以看到,gd指针指向的临时结构体存放在内存的最顶部。BL2代码存放在内存地址0x 3ff0 0000处,即距离内存顶部1 MB空间的位置,接下来依次分配malloc空间、bd_t结构体空间和gd_t结构体空间,并且重新设置栈,最后将临时结构体拷贝到ID指针所指向的位置。board_init_f()实现过程略——编者注。

(2)board_init_r()

board_init_r()负责对其他硬件资源进行初始化,如网卡、Flash、MMC、中断等,最后调用 main_loop(),等待用户输入命令。

3 设计实现

3.1 支持Nand Flash读写

Nand Flash是嵌入式系统中重要的存储设备,存储对象包括Bootloader、操作系统内核、环境变量、根文件系统等,所以使能Nand Flash读写是U-Boot移植过程中必须完成的一个步骤。U-Boot中Nand Flash初始化函数调用关系为:board_init_r()->nand_init()->nand_init_chip()->board_nand_init()。

board_nand_init()完成两件事:①对S5PV210关于Nand Flash控制器的相关寄存器进行设置。②对nand_chip结构体进行设置。需要设置的成员项有IO_ADDR_R和IO_ADDR_W,这两个成员都指向地址0x B0E0 0010,即Nand Flash控制器的数据寄存器的地址。此外还需要实现以下3个成员函数:

①void(*select_chip)(struct mtd_info*mtd,int chip);

该函数实现Nand Flash设备选中或取消选中。

②void(*cmd_ctrl)(struct mtd_info *mtd,int dat,unsigned int ctrl);

该函数实现对Nand Flash发送命令或者地址。

③int(*dev_ready)(struct mtd_info*mtd);

该函数实现检测Nand Flash设备状态。最后将成员ecc.mode设置为NAND_ECC_SOFT,即ECC软件校验。

配置文件中相应的宏定义略——编者注。

3.2 支持网卡

支持NFS或TFTP网络下载会极大地方便从Linux服务器上下载文件或镜像到硬件平台上,所以使能网卡在U-Boot移植过程中就显得非常重要。以网卡DM9000为例,U-Boot已经抽象出一套完整的关于DM9000的驱动代码(其源码路径为drivers\net\dm9000x.c),用户只需要根据具体的硬件电路配置相应的宏即可。U-Boot中DM9000网卡初始化函数的调用关系为:board_init_r()->eth_initialize()->board_eth_init()->dm9000_initialize()。

配置文件中相应的宏定义略——编者注。

3.3 支持环境变量的保存和修改

为了方便用户配置,U-Boot将一部分变量,如串口波特率、IP地址、内核参数、启动命令等存在Flash或SD卡上,这部分数据称为环境变量。每次上电启动时,U-Boot会检查Flash或SD卡上是否存放有环境变量。如果有则将其读取出来并使用,如果没有就使用默认的环境变量。默认的环境变量定义在env_default.h中,用户也可以随时修改或保存环境变量到Flash或SD卡中。

环境变量的移植非常简单。以Nand Flash为例,开发人员在smdkv210.h源文件中只需要添加如下的宏定义:

4 测试结果

4.1 测试U-Boot启动

测试平台的软硬件环境:硬件平台为友善之臂的smart210开发板;Linux服务器版本为ubuntu9.0;U-Boot版本为2013-01;GCC交叉编译工具链版本为4.3.2。

首先将修改后的源码包放到装有交叉编译工具链的Linux服务器上,输入命令make即可以编译生成两个二进制文件。一个是smdkv210-spl.bin,即BL1代码,存放在spl目录下;另一个是u-boot.bin,即BL2代码,存放在顶层目录下。然后插入SD卡,执行write2sd.sh脚本就可以把BL1和BL2分别烧写到SD卡的第1扇区和第49扇区。write2sd.sh脚本实现如下:

烧写完成之后将SD卡插入到smart210开发板的SD卡槽中,连接好串口和网线,上电启动。通过串口工具(本次测试使用的是SecureCRT)看到输出信息,即表示该UBoot已经成功运行在开发板上,测试U-Boot启动图略——编者注。

4.2 测试Nand Flash和网卡

在等待命令状态下输入“nfs 20000000 192.168.1.123:/work/nfs_root/uImage”,该命令表示从IP为192.168.1.123的Linux服务器上,通过NFS下载该服务器上“/work/nfs_root”目录下的uImage,并存放在内存地址为0x 2000 0000处,uImage为适配于S5PV210开发板的Linux内核镜像。等待一段时间后看到“Bytes transferred=2127008(2074a0 hex)”字样,表示下载成功。

下载成功之后输入命令“nand erase.part kernel”,该命令表示擦除Nand Flash上的kernel分区。接着输入命令“nand write 2000 0000 kernel”,该命令表示拷贝内存地址为0x 2000 0000的内容,烧写到Nand Flash的kernel分区中。内存地址0x 2000 0000存放的内容正是之前从Linux服务器上下载下来的uImage。kernel保存在环境变量mtdparts中,kernel规定了该分区的起始地址和大小。执行完这两条命令后看到“4194304 bytes written:OK”字样,表示系统内核已经成功烧写到Nand Flash中,证明了Nand Flash和网卡均可以正常使用。其实验结果略——编者注。

4.3 测试引导内核启动

烧写完内核之后执行boot命令就可以启动该内核。boot命令实际上是执行环境变量bootcmd中的一条语句,其内容为“nand read 2000 0000 kernel;bootm 20000000”,该语句表示从Nand Flash的kernel分区中读出内核并存放在内存地址为0x 2000 0000处,然后跳转在该地址执行内核镜像。启动过程中可以看到串口打印出的信息,证明了该U-Boot已经成功支持引导Linux操作系统。测试引导内核启动图略——编者注。

结 语

本文首先从硬件和软件两个方面分析了S5PV210的特性及启动方式,然后通过u-boot-2013.01源码包详细阐述了U-Boot启动过程中的两个阶段,最后结合smart210开发板成功设计了一个基于SD卡启动、多功能的Bootloader。测试结果表明,该Bootloader支持Nand Flash读写、NFS网络下载、环境变量保存和修改等功能,为后期开发带来了极大的便利。

编者注:本文为期刊缩略版,全文见本刊网站www.mesnet.com.cn。

[1]冯林琳,耿恒山.基于S3C6410的Uboot分析与移植[J].计算机与现代化,2013(1):119-121.

[2]王茜.基于ARM的平板电脑硬件平台设计[J].微型机与应用,2012(22):29-31.

[3]梁超,杨峰,雷鹏,等.U-Boot SD卡启动方式的移植分析与功能扩展[J].现代电子技术,2013(20):84-86,90.

[4]张健,周书林,朱文静.基于硬件抽象层的Bootloader研究与实现[J].现代电子技术,2010(8):38-40.

[5]郭锋,袁国良,王丽芳.嵌入式Linux引导加载程序分析与设计[J].信息技术,2011(11):123-125.

猜你喜欢
源码环境变量网卡
面向数据可靠传输的高译码率带反馈的LT码
国内一站式工程设备租赁平台众能联合完成C2、C3两轮融资
浅谈开源操作系统的历史
企业如何保护源码
从桌面右键菜单调用环境变量选项
彻底弄懂Windows 10环境变量
Server 2016网卡组合模式
基于三阶段DEA—Malmquist模型的中国省域城镇化效率测度及其收敛分析
挑战Killer网卡Realtek网游专用Dragon网卡
RHEL7 Network Teaming(网卡绑定)配置与测试