《基于ARM9的嵌入式Linux系统开发原理与实践》课件第7章_第1页
《基于ARM9的嵌入式Linux系统开发原理与实践》课件第7章_第2页
《基于ARM9的嵌入式Linux系统开发原理与实践》课件第7章_第3页
《基于ARM9的嵌入式Linux系统开发原理与实践》课件第7章_第4页
《基于ARM9的嵌入式Linux系统开发原理与实践》课件第7章_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章嵌入式Linux引导程序7.1引导程序(Bootloader)概述7.2ARMBootloader的作用7.3Bootloader通用的概念7.4Bootloader的主要任务与框架结构7.5vivi7.6vivi移植实例(移植vivi到博创2410)本章小结

7.1引导程序(Bootloader)概述

简单地说,Bootloader就是在操作系统内核运行前运行的一段小程序。通过这段小程序,可以对硬件设备,如CPU、SDRAM、Flash、串口等进行初始化,也可以下载文件到开发板,对Flash进行擦除和编程,真正起到引导和加载内核镜像的作用。

7.2ARMBootloader的作用

1.初始化RAM(必需)

Bootloader必须能够初始化RAM,因为将来系统要通过它保存一些数据,但具体地实现要依赖与具体的CPU以及硬件系统。

2.初始化串口(可选,推荐)

Bootloader应该要初始化以及使能至少一个串口,通过它与控制台联系进行一些debug的工作,甚至与PC通信。

3.启动内核镜像(必需)

根据内核镜像保存的存储介质不同,可以有两种启动方式:Falsh启动以及RAM启动,但是无论是哪种启动方式,下面的系统状态必须得到满足:

(1) CPU寄存器的设置。

(2) Cache和MMU(MemoryManagementUnit)的设置。

7.3Bootloader通用的概念

1. Bootloader所支持的CPU和嵌入式板

通常,每种不同的CPU体系结构都有不同的Bootloader。有些Bootloader也支持多种体系结构的CPU,比如U-Boot就同时支持ARM体系结构和MIPS等体系结构。

2. Bootloader的安装媒介

系统加电或复位后,所有的处理器通常都从某个预先安排的地址上取指令。比如,ARM在复位时从地址0x0取指。嵌入式系统中通常都有某种类型的固态存储设备(比如:ROM、EEPROM或Flash等)被映射到这个预先安排的地址上。通常Bootloader程序被固化在开发板上的地址是0x00000000,因此在系统加电后,处理器将首先执行Bootloader程序,Bootloader是最先被系统执行的程序。固态存储设备的典型空间分配结构,如图7-1所示。图7-1固态存储设备的空间分配结构

3. Bootloader的控制方式

主机和目标机之间一般通过串口建立连接,Bootloader软件在执行时通常会通过串口来进行通信,比如:输出打印信息到串口,从串口读取用户控制字符,也可以通过JTAG等其他接口进行通信。

4. Bootloader的操作模式

大多数Bootloader都包含启动加载模式(BootLoading)和下载模式(DownLoading)两种不同的操作模式。

5. Bootloader与主机通信

Bootloader与主机通信通常有两种方式:

(1)串口通信。

(2)通过以太网通信。

7.4Bootloader的主要任务与框架结构

1. Bootloader的stage1

1)基本的硬件初始化

(1)屏蔽所有的中断。

(2)设置CPU的速度和时钟频率。

(3) RAM初始化。

(4)初始化LED(可据具体的嵌入式板来选择)。

(5)关闭CPU内部指令/数据cache。

2)为加载stage2准备RAM空间

(1)先保存memorypage一开始两个字的内容。

(2)向这两个字中写入任意的数字。比如:向第一个字写入0x55(01010101),第二个字写入0xaa(10101010)。

(3)然后,立即将这两个字的内容读回。显然,读到的内容应该分别是0x55和0xaa。如果不是,则说明这个memorypage所占据的地址范围不是一段有效的RAM空间。

(4)恢复这两个字的原始内容。测试完毕。

3)拷贝stage2到RAM中

拷贝时要确定和注意两点:

① stage2的可执行映像在固态存储设备的存放起始地址和终止地址;

② RAM空间的起始地址。

4)设置堆栈指针sp

堆栈指针sp的设置是为了执行C语言代码做好准备。通常可以把sp的值设置为(stage2_end-4),也即安排的那个1MB的RAM空间的最顶端(堆栈向下生长)。此外,在设置堆栈指针sp之前,也可以关闭LED,以提示用户代码执行准备跳转到stage2。

5)跳转到stage2的C入口点

在上述一切都就绪后,就可以跳转到Bootloader的stage2去执行了。比如,在ARM系统中,这可以通过修改PC寄存器为合适的地址来实现。如:

ldrpc_start_armboot

2. Bootloader的stage2

Bootloader的stage2的代码通常用C语言来实现,以便于实现更复杂的功能和取得更好的代码可读性和可移植性。但是与普通C语言应用程序不同的是,在编译和链接Bootloader这样的程序时,不能使用glibc库中的任何支持函数。本阶段的主要任务如下:

(1)初始化本阶段要使用到的硬件设备。

(2)检测系统的内存映射(memorymap)。

(3)加载内核映像和根文件系统映像。

(4)设置内核的启动参数。

(5)调用内核。

7.5vivi

7.5.1vivi简介

vivi是由韩国Mizi公司开发的一种Bootloader,适合于ARM9处理器,支持S3c2410处理器。vivi具有结构清晰、功能丰富的特点。7.5.2vivi的软件结构分析

vivi的软件结构从总体上可分为四个层次:vivi配置、vivi编译、stage1和stage2。另外,vivi还提供了测试程序和工具,并且有简明的文档。图7-2vivi从配置到最后生成的总体流程图

1. vivi配置原理

以makemenuconfig为例说明vivi配置过程。

执行makemenuconfig,会执行主Makefile中:

menuconfig:include/version.h

$(MAKE)-Cscripts/lxdialogall

$(CONFIG_SHELL)scripts/Menuconfigarch/config.in在makemenuconfig的时候,会打印出如下的内容:

2. vivi编译原理

vivi编译流程是由Makefile来决定的。Makefile从总体上讲可分三个部分:定义变量、编译规则和配置规则。

1)主Makefile分析

(1)定义变量。

版本号:在生成的vivi中,开头的版本号是由下面的变量来定义的。

VERSION=0

PATCHLEVEL=1

SUBLEVEL=4

VIVI:这里设置输出版本信息的格式,VIVIRELEASE=0.1.4。

VIVIRELEASE=$(VERSION).$(PATCHLEVEL).$

(SUBLEVEL)

(2)编译规则。

all依赖目标do-it-all,伪目标:all,可参看第3章Makefile小节内容。

all:do-it-all

wildcard函数功能:列出当前目录下所有符合模式“PATTERN”格式的文件名。返回值:空格分割的、存在当前目录下的所有符合模式“PATTERN”的文件名。

2)子Makefile分析

在实际的vivi的源码还有很多其他的Makefile,在vivi/

下的Makefile称为主Makefile,在其他一些目录下,都有独立的Makefile,称之为子Makefile。总的工作是由主Makefile来调度的,那么这些子Makefile怎么来完成工作?它是由一个非常重要的文件:Rules.make来管理的,它是文件编译所需要共同遵守的规则文件。如drivers/ 下的一个Makefile:

subdir-y:=serial

subdir-$(CONFIG_MTD)+=mtd

include$(TOPDIR)/Rules.make7.5.3vivi启动原理

与大多数Bootloader一样,vivi的运行过程也分为两个阶段:

第一阶段的运行代码在vivi/arch/s3c2410/head.s中定义,大小不超过4kB,它是从Flash启动系统的引导代码,它包括对S3C2410基本硬件的初始化,从NANDFlash上复制整个VIVI代码到RAM并跳转到第二阶段执行,其主要步骤如图7-3所示。图7-3vivi的第一阶段主要步骤第二阶段C语言代码是从init/main.c的main函数开始执行,是在RAM中运行的,其主要步骤如图7-4所示。图7-4vivi的第二阶段主要步骤

1. vivi的第一阶段

1)禁止看门狗

上电后,WATCHDOG默认是开着的,代码如下:

movr1,#0x53000000;WTCON寄存器地址是0x53000000,清0

movr2,#0x0

strr2,[r1]

2)禁止中断

vivi中没用到中断,所以要关中断,代码如下:

movr1,#INT_CTL_BASE

movr2,#0xffffffff

str r2,[r1,#oINTMSK];掩码关闭所有中断

ldr r2,=0x7ff

str r2,[r1,#oINTSUBMSK]

3)设置CPU的速度和时钟频率

初始化时钟:

movr1,#CLK_CTL_BASE

mvnr2,#0xff000000

strr2,[r1,#oLOCKTIME]

4)初始化内存控制寄存器

5)设置串口

6)将vivi的所有代码从Flash中拷贝到RAM中

7)跳转到main()函数

图7-5执行vivistage1后内存的划分情况

2. vivi的第二阶段

第二阶段的入口就是init/main.c,按照源代码的组织流程,根据模块化划分的原则,此阶段可分为8个功能模块。

1)打印版本信息

2)开发板初始化

3)内存映射和内存管理单元的初始化

mem_map_init();

mmu_init();

这两个函数都在 /arch/s3c2410/mmu.c文件中。图7-6创建页表后内存的划分情况

4)初始化堆栈

heap_init()。(定义在\vivi\lib\heap.c文件中)

intheap_init(void)

{

returnmmalloc_init((unsignedchar*)(HEAP_BASE),

HEAP_SIZE);

}图7-7初始化堆栈后内存的划分情况

5)初始化mtd设备

6)初始化私有数据

init_priv_data()函数在\vivi\lib\priv_data\rw.c文件中。图7-8初始化私有数据后内存的划分情况

7)初始化内置命令

misc()和init_builtin_cmds()。

8)启动内核

boot_or_vivi(),此函数根据情况通过“vivi_shellvivi_

shell()”启动一个shell(如果配置了CONFIG_SERIAL_TERM)

进入与用户进行交互的界面,或者直接启动linux内核。图7-9vivi启动内核后内存的划分情况

7.6vivi移植实例(移植vivi到博创2410)

vivi的移植方法步骤:

(1)对vivi进行移植修改;

(2)对vivi进行配置、编译;

(3)烧写vivi;

(4)测试vivi。7.6.1对vivi进行移植修改

1.修改vivi/Makefile

1)修改交叉编译库和头文件

(1)修改编译器路径。

将:CROSS_COMPILE=/usr/local/arm/2.95.3/bin/arm-linux-

修改为:CROSS_COMPILE=符合本机的路径

本机CROSS_COMPILE的路径为:

 CROSS_COMPILE=/opt/host/armv4l/bin/armv4l-unknown-linux-

(2)修改编译器库文件路径。

将:ARM_GCC_LIBS=/usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3

修改为:ARM_GCC_LIBS=符合本机的路径

本机ARM_GCC_LIBS的路径为:

 ARM_GCC_LIBS=/opt/host/armv4l/bin/gcc-lib/armv4l-unknown-linux/2.95.2

2) Linux内核包含文件

将:LINUX_INCLUDE_DIR=/usr/local/arm/2.95.3/include

修改Linux头文件所在路径:LINUX_INCLUDE_DIR=符合本机的

本机LINUX_INCLUDE_DIR的路径为:

 LINUX_INCLUDE_DIR=/opt/host/armv4l/include

2.修改vivi中与硬件相关的部分

与具体运行在哪一个处理器平台上相关的文件都存放在vivi/arch/目录下,本系统使用S3C2410x处理器,对应的目录为s3c2410。其中,head.s文件是vivi启动配置代码,加电复位运行的代码就是从这里开始的。

3.支持NandFlash启动的修改(vivi/arch/s3c2410

/smdk.c)

1)修改NandFlash分区

系统存储器使用64MB的NandFlash,因此vivi要从NandFlash启动。NandFlash只适合用来存放数据,不能够直接在其上执行程序指令。

2)修改默认参数

xmodem_timeout需要调整到30000000,不然在使用下载时很容易出现下载失败的信息,如:“Retry0:NAKonsector”;

"boot_delay"o为下载模式(DownLoading)下的时间延时,在这段时间里,如果开发人员不输入任何vivi中的命令,则vivi将自动引导内核。本系统修改为:0x1000000。

3)修改启动命令

在intdefault_nb_params=ARRAY_SIZE(default_vivi_

parameters)下添加:

charlinux_cmd[]="noinitrdroot=/dev/mtdblock3init=/linuxrcconsole=ttySAC0,115200rootfstype=cramfsdevfs=mountmem=64M";启动命令:7.6.2对vivi进行配置与编译

进入vivi目录执行“makeclean”,在编译之前将vivi里所有的“.o”和“.o.flag”文件删除。输入“makemenuconfig”进入配置界面,如图7-10所示。图7-10vivi配置界面输入“make”对vivi进行编译,make没有错误,编译后在当前目录下会生成vivi的二进制代码文件vivi,如图7-11所示,这样就可将其烧写进开发板中,验证是否能将内核引导起来。图7-11vivi编译结果7.6.3烧写vivi

开发板上已经存在vivi时,可以用串口烧写;开发板上不存在vivi时,用jtag口烧写。

1.串口下载vivi

1)格式化flash

打开超级终端,先按住PC机键盘的BackSpace键,然后启动2410-S,进入vivi,按照以下命令格式化flash,重新分区,如图7-12所示。

vivi>bonpart0128k192k2240k6336k:m65536k回车图7-12格式化flash

2)烧写vivi

这时已格式化flash,运行的是SDRAM中的vivi。注意如果这时重启或断电会丢失所有数据,否则必须用Jtag重新烧写vivi。

vivi>loadflashvivix回车

点击超级终端任务栏上“传送”下拉菜单中的“发送文件”,选择协议为Xmodem,选择镜像文件vivi,点击“发送”,如图7-13所示,10秒左右vivi就烧写到flash中了。图7-13串口烧写vivi

2. Jtag口烧写

把并口线插到PC机的并口,并把并口和Jtag相连,Jtag和博创开发板的14针Jtag口相连。

运行Jtag烧写文件sjf2410-s.exe命令如下:

sjf2410

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论