bootloader概述

bootloader概述
bootloader概述

对于嵌入式系统工作过一段时间的人来说,Bootloader应该是一个不算陌生的概念。

对于linux的系统来说,从软件角度通常分成4层:

●Bootloader

●Linux内核

●文件系统

●用户应用程序

1. Bootloader概念

Bootloader是处理从系统开机初始化硬件开始直到启动操作系统内核这段过程的一段程序,是系统中最早运行的程序,和硬件有很大的相关性。

从CPU的角度来说,上电后并非立刻就可以运行操作系统的,系统的相关硬件必须初始化(CPU工作模式的设置,内存初始化,关中断,关闭MMU/Cache等等等等),根据当前硬件条件判定当前是启动模式还是下载模式,然后走相应的功能分支。

所以一句话概括bootloader的工作——初始化系统的软硬件环境,使之满足操作系统的运行条件。当把一切软硬件环境都配置好之后,系统的

控制权才会交给OS的内核,这个时候Bootloader就功成身退了。

由于涉及到针对底层硬件的操作,所以很多代码会用汇编语言编写,也需要对系统硬件的工作有一个正确的完整的认识,这样对工程师的要求自然就高了。同时,Bootloader的可移植性就不会太好。

Bootloader有单阶段的也有多阶段的,目前比较多的是采用2个阶段,stage1和stage2。stage1一般都由汇编码编写,stage2一般由C语言编写.

大多数Bootloader都包含两种不同的操作模式:

●启动加载模式:这种模式也称自主模式,在这个模式下bootloader 从某个存储设备上加载操作系统到RAM,用户不需要介入这个过程

●下载模式:这种模式下bootloader将通过串口/USB/网络等等手段从主机下载文件,写入存储设备。

现在的Android智能机就是一个很典型的例子,平时开机用户不需要介入,属于正常的启动加载模式,当用户刷机时显然就变成了下载模式。

2. 常见的Bootloader

●U-boot

这是现在使用最多的bootloader之一,是sourceforge上的一个开源项

目。支持ARM,MIPS,PowerPC,x86等处理器,同时支持linux,VxWorks,NetBSD, QNX等操作系统。

●PPCBoot

这是德国DENX小组开发的用于多种嵌入式CPU的Bootloader引导程序。目前支持ARM,MIPS,PowerPC等处理器。

●RedBoot

Redhat公司随ECOS发布的一个开源项目。可以通过串口和以太网口与GDB进行通信和调试应用程序。

●ARMBoot

这也是sourceforge上的一个开源项目,设计只针对ARM的处理器结构,所以在ARM内核的平台上移植比较方便。

●Blob

赫赫有名的一款强大的bootloader。

●Vivi

韩国mizi公司开发的bootloader,适用于ARM9的处理器。

3. Bootloader启动流程

由于结构上Bootloader由两部分组成,所以启动过程也就分成2个阶段,stage1和stage2。

stage1阶段:

●硬件设备初始化

准备好基本的硬件环境。

●关中断

Bootloader中没必要响应任何中断,中断是设备驱动管理所需要考虑的内容。

●设置CPU的速率和时钟频率

一般系统的节拍是由晶振来提供的,这里CPU的速率和时钟频率并非可以任意设置,是需要和系统的配置相匹配的。

如果在匹配的情况下,时钟设置的高一些,系统运行速度可以变快一点。实验中发现下载Image可以变快。

不过这个参数如果不使用主板供应商提供的,而是自行设置,那么需要多多测试,有些参数设置后会导致不稳定,有时下载会正常,有时会出错。

●RAM初始化

我们使用的RAM,实际上都是通过一个控制器连接到系统上的,所以必须针对控制器的寄存器进行一些设置

●初始化LED

这个就如同PC主板上一样,很多板子都会设计一些灯,不同的错误可以有不同的灯亮起来,可以用于调试,传递简单的一些信息

●关闭MMU,指令/数据Cache

因为bootloader中是使用的都是实地址,所以需要关闭MMU。因为需要装载Kernel的镜像,镜像的数据必须回写到RAM,所以必须关闭数据Cache。

至于指令Cache,资料上说可以不必关闭,我实际遇到过系统出错的情况,关闭指令Cache就好了,原因并没有分析出来,所以推荐还是关闭。

●为加载stage2准备RAM空间

因为stage2往往是用C语言来写的,所以需要准备C语言运行时,这里需要准备的RAM空间就不能仅仅是stage2的大小了,必须加上必要的堆栈大小。另外,最好考虑使用memory page的倍数。

这里还需要保证准备的RAM空间是确实可用的,常见的测试算法如下:1.先保存memory page 一开始两个字的内容。

2.向这两个字中写入任意的数字。比如:向第一个字写入0x55,第2 个字写入0xaa。

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

4.再向这两个字中写入任意的数字。比如:向第一个字写入0xaa,第2 个字中写入0x55。

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

6.恢复这两个字的原始内容。测试完毕。

但这种算法即使通过也不见得没问题,我曾经遇到过一次系统内存回卷的情况,后一半的内存复写了前一半的内存,这样的算法对检查这样的错误是无能为力的,只能具体情况具体分析。

●复制stage2到RAM空间中

拷贝时要确定两点:(1)stage2 的可执行映象在固态存储设备的存放起始地址和终止地址;(2) RAM 空间的起始地址。

●设置堆栈

通常我们可以把sp 的值设置为(stage2_end-4),也即在RAM 空间的最顶端(堆栈向下生长)

执行完之后内存布局情况应该如下图所示:

●跳转到stage2的C入口

修改PC指针即可。

stage2阶段:

●初始化本阶段要用到的硬件设备

这里面内容就更加丰富了,随着现在bootloader为了实现各种需求,需要初始化更多的相关硬件。

初始化至少一个串口,以便于和终端通信。还需要初始化计时器等等的。

●检测系统内存映射

所谓内存映射就是指在整个4GB 物理地址空间中有哪些地址范围被

分配用来寻址系统的RAM 单元。

虽然CPU 通常预留出一大段足够的地址空间给系统RAM,但是在搭建具体的嵌入式系统时却不一定会实现CPU 预留的全部RAM 地址空间。也就是说,具体的嵌入式系统往往只把CPU 预留的全部RAM 地址空间中的一部分映射到RAM 单元上,而让剩下的那部分预留RAM 地址空间处于未使用状态。由于上述这个事实,因此BootLoader 的stage2 必须在它想干点什么(比如,将存储在flash 上的内核映像读到RAM 空间中) 之前检测整个系统的内存映射情况,也即它必须知道CPU 预留的全部RAM 地址空间中的哪些被真正映射到RAM 地址单元,哪些是处于"unused" 状态的。

可以用如下数据结构来描述RAM 地址空间中的一段连续(continuous)的地址范围:

typedef structmemory_area_struct {

u32 start; /* the base address of thememory region */

u32 size; /* the byte number of the memoryregion */

int used;

} memory_area_t;

这段RAM 地址空间中的连续地址范围可以处于两种状态之一:(1)used=1,则说明这段连续的地址范围已被实现,也即真正地被映射到RAM 单元上。

(2)used=0,则说明这段连续的地址范围并未被系统所实现,而是处于未使用状态。

基于上述memory_area_t 数据结构,整个CPU 预留的RAM 地址空间可以用一个memory_area_t 类型的数组来表示,如下所示:memory_area_tmemory_map[NUM_MEM_AREAS] = {

[0 ... (NUM_MEM_AREAS - 1)] = {

.start = 0,

.size = 0,

.used = 0

},

};

●加载内核映像和根文件系统映像

这里包括两个方面:(1)内核映像所占用的内存范围;(2)根文件系统

所占用的内存范围。在规划内存占用的布局时,主要考虑基地址和映像的大小两个方面。

对于内核映像,一般将其拷贝到从(MEM_START+0x8000) 这个基地址开始的大约1MB大小的内存范围内(嵌入式Linux 的内核一般都不操过1MB)。为什么要把从MEM_START 到MEM_START+0x8000 这段32KB 大小的内存空出来呢?这是因为Linux 内核要在这段内存中放置一些全局数据结构,如:启动参数和内核页表等信息。

而对于根文件系统映像,则一般将其拷贝到

MEM_START+0x0010,0000 开始的地方。如果用Ramdisk 作为根文件系统映像,则其解压后的大小一般是1MB。

●为内核设置启动参数

应该说,在将内核映像和根文件系统映像拷贝到RAM 空间中后,就可以准备启动Linux 内核了。但是在调用内核之前,应该作一步准备工作,即:设置Linux 内核的启动参数。

Linux2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。启动参数标记列表以标记ATAG_CORE 开始,以标记ATAG_NONE 结束。每个标记由标识被传递参数的tag_header 结构以及随后的参数值数据结构来组成。数据结构tag 和tag_header 定义在Linux 内核源码的include/asm/setup.h头文件中:

/* The list endswith an ATAG_NONE node. */

#define ATAG_NONE 0x00000000

struct tag_header {

u32 size; /* 注意,这里size是字数为单位的*/

u32 tag;

};

……

struct tag {

struct tag_header hdr;

union {

struct tag_core core;

struct tag_mem32 mem;

struct tag_videotext videotext;

struct tag_ramdisk ramdisk;

struct tag_initrd initrd;

struct tag_serialnr serialnr;

struct tag_revision revision;

struct tag_videolfb videolfb;

struct tag_cmdline cmdline;

/*

* Acorn specific

*/

struct tag_acorn acorn;

/*

* DC21285 specific

*/

struct tag_memclk memclk;

} u;

};

在嵌入式Linux系统中,通常需要由Boot Loader 设置的常见启动参数有:ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、

ATAG_RAMDISK、ATAG_INITRD等。

比如,设置ATAG_CORE 的代码如下:

params = (struct tag *)BOOT_PARAMS;

params->hdr.tag = ATAG_CORE;

params->hdr.size = tag_size(tag_core);

params->u.core.flags = 0;

params->u.core.pagesize = 0;

params->u.core.rootdev = 0;

params = tag_next(params);

其中,BOOT_PARAMS 表示内核启动参数在内存中的起始基地址,指针params 是一个struct tag 类型的指针。宏tag_next() 将以指向当前标记的指针为参数,计算紧临当前标记的下一个标记的起始地址。注意,内核的根文件系统所在的设备ID就是在这里设置的。

下面是设置内存映射情况的示例代码:

for(i = 0; i

if(memory_map[i].used) {

params->hdr.tag =ATAG_MEM;

params->hdr.size =tag_size(tag_mem32);

params->u.mem.start =memory_map[i].start;

params->u.mem.size =memory_map[i].size;

params = tag_next(params);

}

}

可以看出,在memory_map[]数组中,每一个有效的内存段都对应一个ATAG_MEM 参数标记。

Linux 内核在启动时可以以命令行参数的形式来接收信息,利用这一点我们可以向内核提供那些内核不能自己检测的硬件参数信息,或者重载(override)内核自己检测到的信息。比如,我们用这样一个命令行参数字符串"console=ttyS0,115200n8"来通知内核以ttyS0 作为控制台,且串口采用"115200bps、无奇偶校验、8位数据位"这样的设置。下面是一段设置调用内核命令行参数字符串的示例代码:

char *p;

/* eat leading white space */

for(p = commandline; *p == ' '; p++)

;

/* skip non-existent command lines so thekernel will still

* use its default command line.

*/

if(*p == '\0')

return;

params->hdr.tag = ATAG_CMDLINE;

params->hdr.size =

(sizeof(struct tag_header) + strlen(p) + 1 +4) >> 2;

strcpy(params->u.cmdline.cmdline, p);

params = tag_next(params);

请注意在上述代码中,设置tag_header 的大小时,必须包括字符串的终止符'\0',此外还要将字节数向上圆整4个字节,因为tag_header 结构中的size 成员表示的是字数。

下面是设置ATAG_INITRD 的示例代码,它告诉内核在RAM 中的什么地方可以找到initrd 映象(压缩格式)以及它的大小:

params->hdr.tag = ATAG_INITRD2;

params->hdr.size = tag_size(tag_initrd);

params->u.initrd.start =RAMDISK_RAM_BASE;

params->u.initrd.size = INITRD_LEN;

params = tag_next(params);

下面是设置ATAG_RAMDISK 的示例代码,它告诉内核解压后的Ramdisk 有多大(单位是KB):

params->hdr.tag= ATAG_RAMDISK;

params->hdr.size= tag_size(tag_ramdisk);

params->u.ramdisk.start= 0;

params->u.ramdisk.size= RAMDISK_SIZE; /* 请注意,单位是KB */ params->u.ramdisk.flags= 1; /* automatically load ramdisk */ params =tag_next(params);

最后,设置ATAG_NONE 标记,结束整个启动参数列表:

static voidsetup_end_tag(void)

{

params->hdr.tag = ATAG_NONE;

params->hdr.size = 0;

}

●调用内核

Bootloader调用linux内核的方法是直接跳转到内核的第一条指令处,也即跳转到MEM_START+0x8000地址处。

在跳转时,下列条件要满足:

1.CPU 寄存器的设置:

R0=0;

R1=机器类型ID;关于MachineType Number,可以参见

linux/arch/arm/tools/mach-types。

R2=启动参数标记列表在RAM 中起始基地址;

2.CPU 模式:

必须禁止中断(IRQs和FIQs);

CPU 必须SVC 模式;

3.Cache 和MMU 的设置:

MMU 必须关闭;

指令Cache 可以打开也可以关闭;

数据Cache 必须关闭;

如果用C 语言,示例代码如下:

void(*theKernel)(int zero, int arch, u32 params_addr) =

(void (*)(int, int,u32))KERNEL_RAM_BASE;

……

theKernel(0,ARCH_NUMBER, (u32) kernel_params_start);

注意,theKernel()函数调用应该永远不返回的。如果这个调用返回,则说明出错。

U-Boot全称是Universal Bootloader,也是一款开源项目。从名字就可以看出该项目雄心勃勃,希望这个bootloader能够适用于所有的主流CPU。下载地址:ftp://ftp.denx.de/pub/u-boot/

1. 目录结构

/archArchitecture specific files

/armFiles generic to ARM architecture

/cpu CPU specific files

/arm720t Files specific to ARM 720 CPUs

/arm920t Files specific to ARM 920 CPUs

/at91Files specific to Atmel AT91RM9200 CPU

/imxFiles specific to Freescale MC9328 i.MX CPUs

/s3c24x0 Files specific to Samsung S3C24X0 CPUs

/arm925t Files specific to ARM 925 CPUs

/arm926ejsFiles specific to ARM 926 CPUs

/arm1136 Files specific to ARM 1136 CPUs

/ixp Files specific to Intel XScale IXP CPUs

/pxa Files specific to Intel XScale PXA CPUs

/s3c44b0 Files specific to Samsung S3C44B0 CPUs

/sa1100 Files specific to Intel StrongARM SA1100 CPUs

/lib Architecture specific library files

/avr32 Files generic to AVR32 architecture

/cpu CPU specific files

/lib Architecture specific library files

/blackfin Files generic to Analog Devices Blackfin architecture

/cpu CPU specific files

/lib Architecture specific library files

/x86Files generic to x86 architecture

/lib Architecture specific library files

/m68k Files generic to m68k architecture

/cpu CPU specific files

/mcf52x2 Files specific to Freescale ColdFire MCF52x2 CPUs

/mcf5227xFiles specific to Freescale ColdFire MCF5227x CPUs

/mcf532x Files specific to Freescale ColdFire MCF5329 CPUs

/mcf5445xFiles specific to Freescale ColdFire MCF5445x CPUs

/mcf547x_8xFiles specific to Freescale ColdFire MCF547x_8x CPUs /lib Architecture specific library files

/microblaze Files generic to microblaze architecture

/cpu CPU specific files

/lib Architecture specific library files

/mips Files generic to MIPS architecture

/cpu CPU specific files

/mips32 Files specific to MIPS32 CPUs

/xburst Files specific to Ingenic XBurst CPUs

/lib Architecture specific library files

/nds32 Files generic to NDS32 architecture

/cpu CPU specific files

/n1213 Files specific to Andes Technology N1213 CPUs

/lib Architecture specific library files

/nios2 Files generic to Altera NIOS2 architecture

/cpu CPU specific files

/lib Architecture specific library files

/powerpc Files generic to PowerPC architecture

/cpu CPU specific files

/74xx_7xxFiles specific to Freescale MPC74xx and 7xx CPUs

/mpc5xx Files specific to Freescale MPC5xx CPUs

/mpc5xxx Files specific to Freescale MPC5xxx CPUs

/mpc8xx Files specific to Freescale MPC8xx CPUs

/mpc8220 Files specific to Freescale MPC8220 CPUs

/mpc824x Files specific to Freescale MPC824x CPUs

/mpc8260 Files specific to Freescale MPC8260 CPUs

/mpc85xx Files specific to Freescale MPC85xx CPUs

/ppc4xx Files specific to AMCC PowerPC 4xx CPUs

/lib Architecture specific library files

/shFiles generic to SH architecture

/cpu CPU specific files

/sh2 Files specific to sh2 CPUs

/sh3 Files specific to sh3 CPUs

/sh4 Files specific to sh4 CPUs

/lib Architecture specific library files

/sparc Files generic to SPARC architecture

/leon2 Files specific to Gaisler LEON2 SPARC CPU

/leon3 Files specific to Gaisler LEON3 SPARC CPU

/lib Architecture specific library files

/apiMachine/arch independent API for external apps

/board Board dependent files

/common Misc architecture independent functions

/diskCode for disk drive partition handling

/docDocumentation (don't expect too much)

/drivers Commonly used device drivers

/examples Example code for standalone applications, etc.

/fsFilesystem code (cramfs, ext2, jffs2, etc.)

/include Header Files

/libFiles generic to all architectures

/libfdt Library files to support flattened device trees

/lzma Library files to support LZMA decompression

/lzoLibrary files to support LZO decompression

/netNetworking code

/postPower On Self Test

/rtcReal Time Clock drivers

/tools Tools to build S-Record or U-Boot images, etc.

2. 启动过程

作为一个Bootloader,无论兼容了多少种硬件,增加了多少种实用的功能。最基本的启动流程仍然会是那些(暂不考虑CP的启动),硬件设备初始化,内存初始化,加载stage2的代码等等等等。

U-Boot的启动也分成stage1和stage2,stage1使用汇编语言编写,stage2使用C语言编写。

2.1 stage1

在arch\arm\cpu\arm920t\start.S文件中

.globl _start

_start: bstart_code

ldrpc, _undefined_instruction

ldrpc, _software_interrupt

ldrpc, _prefetch_abort

ldrpc, _data_abort

ldrpc, _not_used

ldrpc, _irq

ldrpc, _fiq

阐述对BootLoader的理解和分析

` 物理与电子工程学院 《嵌入式系统设计》 设计性实验报告 题目阐述对BootLoader的理解和分析 系别 年级专业 班级学号 学生姓名 指导教师 实验时间

目录 课题要求 ................................................................ 错误!未定义书签。 1.本课题的目的.............................. 错误!未定义书签。 2.运行环境.................................. 错误!未定义书签。正文 . (2) 一.BootLoad简介 (2) 二.系统设计 (5) 三.技术实现问题 (7) 四.总结与体会 (8) 设计性实验报告成绩:指导教师签名: (10)

摘要 在嵌入式系统中,由于不具有自举开发的能力,其BootLoader除了引导操作系统之外,还要担负辅助开发的责任,如与主机通信、与用户交互、更新系统等功能。 虽然嵌入式系统不可能实现通用的BootLoader,但是各系统的BootLoader依然具有一定的相同性,因此,嵌入式系统中常用的BootLoader也都具有可移植性,可以在大部分代码不更改的情况下,根据本系统的情况,通过修改具体硬件相关的代码并进行相应的配置来使用。 关键字:概述,作用,操作模式,分类,基本原理。 正文 一.BootLoad简介 1.1 BootLoader的概述 BootLoader是操作系统和硬件的纽带,它负责初始化硬件,引导操作系统内核,检测各种参数给操作系统内核使用。事实上,一个功能完备的大型BootLoader,就相当于一个小型的操作系统。在嵌入式领域中,操作系统移植的关键在于BootLoader的移植以及操作系统内核与硬件相关部分的移植。Bootloader是在操作系统运行之前执行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射表,从而将系统软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。通常,Bootloader是严重依赖于硬件而实现的,特别是在嵌入式世界里,嵌入式产品型号众多,硬件环境复杂,建立一个通用的Bootloader几乎是不可能的。尽管如此,仍然可以对Bootloader归纳出一些通用的概念来,以指导特定的Bootloader设计与实现。因此,正确进行Linux移植的条件是具备一个与Linux配套、易于使用的Bootloader,它能够正确完成硬件系统的初始化和Linux的引导。 Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。对于两块不同的嵌入式板而言,即使它们使用同一种处理器,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上,一般也都需要修改Bootloader的源程序。反过来,大部分Bootloader仍然具有很多共性,某些Bootloader也能够支持多种结构的嵌入式系统。通常它们能够自动从存储介质上启动,都能够引导操作系统启动,并且大部分都可以支持串口和以太网接口。

BootLoader引导程序

BootLoader引导程序 一、实验目的 1.学会配置linux下的minicom和windows下的超级终端 2.了解bootloader的基本概念和框架结构 3.了解bootloader引导操作系统的过程 4.掌握bootloader程序的编译方法 5.掌握bootloader程序的使用方法 二、实验内容 1. 学习x-loader 作用和编译过程 2.学习uboot作用和编译过程 3.学习bootloader的操作 三、实验设备 PentiumII以上的PC机, LINUX操作系统 四、BOOTLOADER程序说明 完整的系统由x-loader、u-boot、kernel(内核)、rootfs(根文件系统)组成,x-loader 是一级引导程序,其作用是初始化CPU,拷贝u-boot到内存,然后把控制权交给u-boot。当OMAP3530上电时,memory controller(内存控制器)还未初始化,这个任务便由完成的x-loader。初始化外部RAM控制器,把u-boot读到外部RAM,之后把控制入口交给。u-boot 是二级引导程序,其作用主要是引导内核,提供映像更新,同用户进行交互。系统结构图如 下: 1. BootLoader的作用 在嵌入式系统中,BootLoader的作用与PC机上的BIOS类似,其主要作用:(1)初始化硬件设备;(2)建立内存空间的映射图;(3)完成内核的加载,为内核设置启动参数。通过BootLoader可以完成对系统板上的主要部件如CPU、SDRAM、Flash、串行口等进行初始化,也可以下载文件到系统板上,对Flash进行擦除与编程。当运行操作系统时,它会在操作系统内核运行之前运行,通过它,可以分配内存空间的映射,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统准备好正确的环境。 通常,BootLoader 是依赖于硬件而实现的,特别是在嵌入式系统中。因此,在嵌入式系统里建立一个通用的 BootLoader 几乎是不可能的,不同的处理器架构都有不同的

详解bootloader的执行流程与ARM Linux启动过程分析

详解bootloader的执行流程与ARM Linux启动过程分析 ARM Linux启动过程分析是本文要介绍的内容,嵌入式Linux 的可移植性使得我们可以在各种电子产品上看到它的身影。对于不同体系结构的处理器来说Linux的启动过程也有所不同。 本文以S3C2410 ARM处理器为例,详细分析了系统上电后bootloader的执行流程及ARM Linux的启动过程。 1、引言 Linux 最初是由瑞典赫尔辛基大学的学生Linus Torvalds在1991 年开发出来的,之后在GNU的支持下,Linux 获得了巨大的发展。虽然Linux 在桌面PC 机上的普及程度远不及微软的Windows 操作系统,但它的发展速度之快、用户数量的日益增多,也是微软所不能轻视的。而近些年来Linux 在嵌入式领域的迅猛发展,更是给Linux 注入了新的活力。 一个嵌入式Linux 系统从软件角度看可以分为四个部分:引导加载程序(bootloader),Linux 内核,文件系统,应用程序。 其中bootloader是系统启动或复位以后执行的第一段代码,它主要用来初始化处理器及外设,然后调用Linux 内核。 Linux 内核在完成系统的初始化之后需要挂载某个文件系统做为根文件系统(Root Filesystem)。 根文件系统是Linux 系统的核心组成部分,它可以做为Linux 系统中文件和数据的存储区域,通常它还包括系统配置文件和运行应用软件所需要的库。 应用程序可以说是嵌入式系统的“灵魂”,它所实现的功能通常就是设计该嵌入式系统所要达到的目标。如果没有应用程序的支持,任何硬件上设计精良的嵌入式系统都没有实用意义。 从以上分析我们可以看出bootloader 和Linux 内核在嵌入式系统中的关系和作用。Bootloader在运行过程中虽然具有初始化系统和执行用户输入的命令等作用,但它最根本

Stm8s_IAP_Bootloader设计

项目实践2:Bootloader 1.项目介绍 在之前的例程和实践中,我们都是使用st-link调试下载的方式进行程序烧录。大家可能已经认识到这种烧录方式的弊端了。因为这种烧录方式首先必须要有以下几个工具或者软件: 1.烧录工具(不能芯片支持的工具不一样,有ST-Link,JTAG等) 2.已经安装了IDE(IAR或者SVD或者CCS等)或者与烧录工具匹配的烧录软件的电脑 3.烧录前后需要物理上电掉电(不建议ST-Link进行热插拔),即开/关电源. 也许大家会觉得,对于学习而言,这些都能忍受。但是如果真正做成产品,如果还是用这种方式进行升级,那代价就太大。举个例子吧,我之前的工作是开发和维护大功率的UPS(不间断电源),主要客户是一些大型企业,例如银行的数据中心,中国移动网络中心。UPS内 部有许多ARM芯片,DSP芯片。这类应用场合,即便给程序升级,客户也不会让你断电的,而且因为安全性要求,一般MCU,DSP都是在产品内部,根本无法对外开放烧录盒的烧录 接口。所以绝大部分嵌入式产品,都会开发Bootloader程序。 那么什么是Boot Loader呢?一般来说,嵌入式产品的软件都会分为两部分,第一部分 为Bootloader,第二部分为主程序(Main APP),它们存放在flash的不同区域。Bootloader 是上电或者复位以后先执行的,通过它,我们可以初始化硬件设备、建立内存空间的映射图,检测程序的完整性,判断是否需要从Bootloader跳转到APP或者更新APP。而主程序呢,则是真正用来实现产品面向客户的功能的。 通常呢,在Bootloader会实现一种或者一种以上的IAP方式,可能是UART,SPI,CAN 或者Ethernet等。本次例程呢,就是设计一个Bootloader,允许用户用电脑的串口+超级终 端实现烧录功能

F BOOTROM引导模式和程序

28335使用串口烧写程序 串口烧写是一种相对较方便的烧写方式,相对于仿真器或是CAN烧写,相对于仿真器或是USB转CAN的设备,串口是一种非常廉价的烧写方式,而且也不需要安装专业的集成开发环境CCS等,但是不能实现在线调试,因此也只适用于程序基本不用再调整或大批量的场合。 F28335的存储器映射图如下:

BOOTROM 是一块8K X 16的只读存储器,位于地址空间0x3FE000~0x3FFFFF,片内BOOTROM在出厂时固化了引导加载程序以及定点和浮点数据表,片上BOOTROM的存储映射如下图所示: 1.内BOOT ROM数学表: 在BOOT ROM中保留了4K X 16位空间,用以存放浮点和IQ数据公式表,这些数据 公式表有助于改善性能和节省SARAM空间。 向量表: CPU向量表位于ROM存储器0x3FE000~0x3FFFFF段内,如下图所示。复位后,当VMAP=1,ENPIE=0(PIE向量表禁止)时,该向量表激活。

在内部BOOT ROM引导区中能够调用的唯一向量就是位于0x3FFFC0的复位向量。复位向量在出厂时被烧录为直接指向存储在BOOT ROM空间中的InitBoot函数,该函数用于开启引导过程。然后通过通用I/O引脚上的检验判断,决定具体引导模式。引导模式与控制引脚之间的关系如下图所示: Bootloader特性: Bootloader是位于片上引导ROM中的在复位后执行的程序,用于在上电复位后,将程序代码从外部源转移到内部存储器。这允许代码暂时存储在掉电不丢失数据的外部存储器内,然后被转移到高速存储器中执行。 引导ROM中的复位向量将程序执行重定向至InitBoot函数。执行器件初始化之后,bootloader将检查GPIO引脚的状态以确定您需要执行哪种引导模式。这些选项包括:跳转至闪存、跳转至SARAM、跳转至OTP或调用其中一个片上引导加载例程。

单片机自编程及Bootloader设计

单片机自编程及Bootloader设计 Bootloader是在单片机上电启动时执行的一小段程序。也称作固件,通过这段程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用应用程序准备好正确的环境。 Boot代码由MCU启动时执行的指令组成。这里的loader指向MCU的Flash中写入新的应用程序。因此,Bootloader是依赖于特定的硬件而实现的,因此,在众多嵌入式产品中目前还不可能实现通用Bootloader。 Bootloader的最大优点是:在不需要外部编程器的情况下,对嵌入式产品的应用代码进行更新升级。它使得通过局域网或者Intemet远程更新程序成为可能。例如,如果有5 000个基于MCU的电能表应用程序需要更新,电能表制造商的技术人员就可以避免从事对每一个电能表重新编程的巨大工作量,通过使用Bootloader的功能,由控制中心通过电能表抄表系统网络,远程对5 000个电表重新编程。可见,Bootloader功能对于嵌入式系统的广泛应用具有十分重要的意义。 1 78K0/Fx2系列单片机简介 78K0/Fx2系列是带CAN控制器的8位单片机,该系列单片机广泛应用于汽车电子,智能仪表等领域。其内置POC(可编程上电清零电路)/LVI(可编程低电压指示器),单电压自编程闪存,引导交换功能(闪存安全保护),具有低功耗、宽电压范围、超高抗干扰等性能。 78K0系列单片机支持自编程(Self-programming)。所谓自编程,是指用Flash存储器中的驻留的软件或程序对Flash存储器进行擦除/编程的方法。通过单片机的自编程功能,可以设计Bootloader程序,通过串口等通信接口实现对产品重新编程、在线升级的功能。 以μPD78F0881为例。μPD78F0881为78KO/Fx2系列中的一款44管脚单片机,内置32 KB Flash ROM,2 KB RAM,自带2个串行通信接口。其内部Flash结构。为了方便实现擦除和编程,人为地将整个Flash分成若干个block,每个block大小为1 KB。block为自编程库函数中空白检测、擦除、校验的最小单位。blockO从地址0000H开始,程序都从0000H 开始执行。block0~block3共4 KB存储空间为Bootloader程序存储区域。block4~block31为应用程序存储区域。 为了防止Bootloader自身的升级失败,设计了引导交换功能。该功能定义2个簇,即Boot cluster0和Boot cluster1。Boot clustee0为block0~block3的4 KB存储空间,Boot cluster1为block4~block7的4 KB存储空间。因此,实际运用过程中,一般把应用程序的开始定义在2000H,也就是从block8开始。 Flash地址为0000H~FFFFH。7FFFFH~FFFFH存储空间为保留区域以及特殊功能寄存器区域等,用户无法对其进行编程。 2 自编程 2.1 自编程环境 2.1.1 硬件环境 FLMDO引脚是78KO/Fx2系列单片机为Flash编程模式设置的,用于控制MCU进入编程模式。在通常操作情况下,FLMDO引脚下拉到地。要进入自编程模式,必须使FLMDO引脚置成高电平。因此,通过一个普通I/O接口控制FLMD0引脚的电平。。 2.1.2 软件环境 1)使用通用寄存器bank3,自编程库函数,需要调用通用寄存器bank3。因此,在自编程时,不能对通用寄存器bank3操作。

STM32的BOOT概述

STM32的BOOT概述 STM32 三种启动模式对应的存储介质均是芯片内置的,它们是:1)用户 闪存= 芯片内置的Flash。2)SRAM = 芯片内置的RAM 区,就是内存啦。3)系统存储器= 芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP 程序。这个区域的内容在芯片出厂后没有人 能够修改或擦除,即它是一个ROM 区。 在每个STM32 的芯片上都有两个管脚BOOT0 和BOOT1,这两个管脚在芯 片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序,见下表:BOOT1=x BOOT0=0 从用户闪存启动,这是正常的工作模式。 BOOT1=0 BOOT0=1 从系统存储器启动,这种模式启动的程序功能由厂家设置。BOOT1=1 BOOT0=1 从内置SRAM 启动,这种模式可以用于调试。 在系统上电的时候,cpu 首先根据这两个脚来确定是哪种模式的启动,然后 就是把相应模式的起始地址映射到0 地址处,并从0 地址处开始执行。在芯片 出厂时,st 烧写了一个bootloader 到rom 中,也就是system memory。这个bootloader 的主要任务就是通过uart1 下载程序到内置flash 中去。工作流程如下:system memory boot 模式,在执行完成它的任务之后是必须要退出的。这个退出方式是通过一次硬件reset 来实现的。在reset 的时候,必须要配置BOOT[1:0]这两个脚以使cpu 在重启之后进入适当的模式。 要注意的是,一般不使用内置SRAM 启动(BOOT1=1 BOOT0=1),因为SRAM 掉电后数据就丢失。多数情况下SRAM 只是在调试时使用,也可以做其他一些用途。如做故障的局部诊断,写一段小程序加载到SRAM 中诊断板上的 其他电路,或用此方法读写板上的Flash 或EEPROM 等。还可以通过这种方法解除内部Flash 的读写保护,当然解除读写保护的同时Flash 的内容也被自动清

bootloader

Boot Loader的启动流程和开发经验总结 Windows CE最大程度继承了桌面版Windows的丰富功能,但是Windows CE并不是一个通用的安装版操作系统。在形形色色的嵌入式设备世界里,一款CE系统通常只会针对某一种硬 件平台生成。 一般来说,Windows CE的开发过程可以分为:0AL(OEM Abstraction Layer)、驱动、应用程序开发三个步骤。其中,0AL开发最基本的一步是板级支持包(BSP),而BootLoader 设计则在BSP开发中具有极为关键的地位。 1.什么是BootLoader 嵌入式系统的启动代码一般由两部分构成:引导代码和操作系统执行环境的初始化代码。其中引导代码一般也由两部分构成:第一部分是板级、片级初始化代码,主要功能是通过设置寄存器初始化硬件的工作方式,如设置时钟、中断控制寄存器等,完成内存映射、初始化MMU等。第二部分是装载程序,将操作系统和应用程序的映像从只读存储器装载或者拷贝到系统的RAM中并执行。 (1)什么是板级BSP? BSP(Board Support Package)是板级支持包,是介于主板硬件和操作系统之间的一层,主要是为了支持操作系统,使之能够更好的运行于硬件主板。不同的操作系统对应于不同形式的BSP,例如WinCE的BSP和Linux的BSP相对于某CPU来说尽管实现的功能一样,可是写法和接口定义是完全不同的。所以,BSP一定要按照该系统BSP的定义形式来写,这样才能与上 层OS保持正确的接口,良好的支持上层OS。 (2)什么是Boot Loader

在BSP中有一个重要的组成部分就是BootLoader,它是在操作系统内核运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,为调用操作系统内核准备好环境。 一般来说,在嵌入式世界里BootLoader 是严重地依赖于硬件的,因此想建立一个通用的 BootLoader 几乎是不可能的。不同的 CPU 体系结构有不同的BootLoader,而且除了依赖于 CPU的体系结构外,BootLoader还依赖于具体的嵌入式板级设备的配置。这也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种 CPU 结构而构建的,要想让运行在一块板子上的 BootLoader 程序也能运行在另一块板子上,通常也都需要修改 BootLoader 的源程序。 2.BootLoader在PC机与嵌入式的区别比较 (1)引导程序在PC机和嵌入式上的区别 一般来说,在PC的硬件平台上,由于硬件启动根本就不是通过BootLoader(而是通过BIOS),所以BootLoader就不需要对CPU加电后的初始化做任何工作。在桌面系统中,有以下几种设备可以作为启动设备使用:硬盘、USB盘、光盘驱动器、还有网卡的Boot ROM 等。但无论选择了哪一种启动设备,操作系统都会去将该设备起始地址的内容读入内存,BIOS 将控制移交给引导装载程序。如果启动设备是IDE硬盘,这时通常将引导装载程序装入第一个扇区(通常被称做主引导扇区,MBR),然后将内容读入内存再运行。 在嵌入式平台上,引导装载程序是在硬件上执行的第一段代码,通常将引导程序放置在不易丢失的存储器的开始地址或者是系统冷启动时PC寄存器的初始值。在嵌入式系统中,通常并没有像BIOS那样的固件程序,因此整个系统的加载启动任务就完全由BootLoader来完

bootloader分析

Bootloader分析

?熟悉BootLoader的实现原理?认识Bootloader的主要任务?熟悉BootLoader的结构框架?U-boot使用

引言本章详细地介绍了基于嵌入式系统中的OS启动加载程序――Boot Loader的概念、软件设计的主要任务以及结构框架等内容。 一个嵌入式Linux系统从软件的角度看通常可以分为四个层次: ?1.引导加载程序。包括固化在固件(firmware)中的boot代码(可 选),和Boot Loader两大部分。 ?2.Linux内核。特定于嵌入式板子的定制内核以及内核的启动参数。 ?3.文件系统。包括根文件系统和建立于Flash内存设备之上文件 系统。通常用ram disk来作为root fs。 ?4.用户应用程序。特定于用户的应用程序。有时在用户应用程序和 内核层之间可能还会包括一个嵌入式图形用户界面。常用的嵌入式GUI有:MicroWindows和MiniGUI。

?引导加载程序是系统加电后运行的第一段软件代码。回忆一下PC 的体系结构我们可以知道,PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的OS Boot Loader(比如,LILO和GRUB等)一起组成。 ?BIOS在完成硬件检测和资源分配后,将硬盘MBR中的Boot Loader读到系统的RAM中,然后将控制权交给OS Boot Loader。 Boot Loader的主要运行任务就是将内核映象从硬盘上读到RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。 而在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由Boot Loader来完成。 ?比如在一个基于ARM7TDMI core的嵌入式系统中,系统在上电 或复位时通常都从地址0x00000000处开始执行,而在这个地址 处安排的通常就是系统的Boot Loader程序。

tms320c6000系列二次bootloader的设计与实精)

TMS320C6000系列二次Bootloader的设计与实 (精) TMS320C6000系列二次Bootloader的 设计与实现,DSP,二次 Bootloader,Flash存储器,中断向 引言随着DSP(数字信号处理器)系统的广泛应用,其程序规模也随之不断扩大,使用芯片本身自带的Boot-loader通过Flash存储器来引导DSP程序,往往受到程序大小和结构的制约,比如程序很大超过厂商固化boot的范围,再如中断向量表的不同位置对程序boot跳转的影响,等等,因此越来越需要更加灵活的引导方式。系统上电后,由引导程序将DSP的应用程序从该存储器引导到DSP应用板上的高速存储器(如内部SRAM、SDRAM等)中。由于Flash存储器具有 引言 随着DSP(数字信号处理器)系统的广泛应用,其程序规模也随之不断扩大,使用芯片本身自带的Boot-loader通过Flash存储器来引导DSP程序,往往受到程序大小和结构的制约,比如程序很大超过厂商固化boot的范围,再如中断向量表的不同位置对程序boot跳转的影响,等等,因此越来越需要更加灵活的引导方式。 系统上电后,由引导程序将DSP的应用程序从该存储器引导到DSP应用板上的高速存储器(如内部SRAM、SDRAM等)中。由于Flash存储器具有电信号删除功能,且删除速度快,集成度高,因此已成为此种存储器的首选。由于Flash存储器的存取

速度较慢,写入Flash存储器的程序将在系统上电时被DSP装载到快速的存储器中运行,这个过程称为Boot loader。不同的DSP有不同的引导方式。以TI公司TMS320C6000系列芯片为例,自举方式有3种:无自举(No Boot),CPU直接开始执行地址0处的指令;主机自举(Host Boot),系统复位后主机通过CPU的HPI(主程序设计接口)初始化DSP的存储空间;ROM自举(ROM Boot),DMA控制器从CEl 空间复制固定长度程序的地址0处,然后从地址0处开始执行。对于620x/670x DMA,复制64 kB数据从CEl到地址0;而对于621x/671x EDMA,复制1 kB数据从CEl地址开始到地址0。 关于TI公司的C6000芯片二次Bootloader在许多文献都介绍过,包括二次Bootloader的PLL、EMIF的设置和搬移表的设置和Flash存储器的烧写过程,但是对于有中断向量表的二次Bootloader实现的文献很少。本文以TI公司高性能DSP的代表作TMS320C6000系列芯片为例,介绍了一种带中断向量表的二次Bootloader 的新途径,从而为TMS320C6000系列DSP的开发提供了一种新的思路。该方法在实际中得到具体应用,系统运行稳定可靠。 1 二次Bootload的过程 TMS320C6713是TI公司推出的TMS320C67xx系列浮点DSP中最新的一种芯片。TMS320C6713每周期可以执行8条32位指令;支持32/64位数据;具有最高225MHz的运行速度和1800 MIPs(百万次运算每秒)或1350 MFLOPS(百万次浮点运算每秒)的处理能力;同时是有强大的外设支持能力;EMIP(外部存储器接口)可以很方便地与SDRAM、SBSRAM、Flash存储器、SRAM等同步和异步存储器相连,16位EHPI接口可以与各种处理器接口;另外,还有优化的多通道缓存串口和多通道音频串口,这些外部接口使设计人员可以很容易实现自己的应用系统。 在选择ROMBoot方式时,RESET由低变高后,C6713的CPU内核处于复位状态,而C6713的其他部分则开始工作,此时EMIF的CEl空间根据ROM Boot的方式

AN945 EFM8 Factory Bootloader用户指南中文版

AN945:EFM8 Factory Bootloader用户指南 本文档介绍了工厂编程的引导加载程序可用于EFM8设备。除了描述引导程序的功能,本文档还详细介绍了如何使用引导加载程序并更新Bootloader固件源代码或python主机软件,如果需要定制。 关键点 EFM8工厂编程的引导加载程序提供基本的生产编程或现场更新支持。?主机端都提供源代码python工具和bootloader 件来启用自定义。

1介绍 EFM8设备在工厂中使用引导加载程序进行编程。此引导程序启用: 1. 生产编程- 可以在生产环境中对设备进行编程,而无需使用调试接口需要PCB上的接入点和调试适配器。 2. 2.现场更新- 可以在现场的设备上发布更新,无需最终用户访问调试引脚或使用调试适配器硬件。 引导加载程序主要用于具有最小功能集的生产编程,但也可用于现场更新。因为几个EFM8变体可以有2 KB的闪存,引导程序的设计尽可能小。例如,UART和SMBus版本消耗单个512闪存页面,USB版本消耗1.5 KB闪存。另外,bootloader通常位于代码安全页面中,以使引导程序能够写入和擦除锁定的应用程序空间。更多信息在每个设备上的引导加载程序放置位置可以在设备数据手册或参考手册中找到。 22. USB或UART引导加载程序入门 这些步骤假定使用入门套件。使用自定义硬件时,步骤相同。 这些步骤还假设应用笔记zip文件已经下载到PC,或者使用Simplicity访问文件 工作室。应用程序zip文件可以在Silicon Labs网站(https://www.360docs.net/doc/b113848786.html,/8bit-appnotes)上找到。 ?将Bootloader下载到设备 如果引导加载程序尚未在设备上,请使用Simplicity Studio将Bootloader下载到设备,并按以下步骤操作。 日期代码在设备勘误表中列出的日期之后的顶部标记的设备可以支持引导加载程序并可能具有 bootloader预装。在此之前的日期代码的设备将不能与引导程序一起使用。 ?打开Simplicity Studio。 ?将入门工具包连接到PC。 ?将套件开关移动到[AEM]位置。 ?单击Simplicity Studio左窗格中的[Refresh detected hardware]按钮。该套件应显示在[Detected Hardware] 区。 ?单击工具包,然后单击Simplicity Studio的[tool]区域中的[Flash Programmer]图块。 ?单击[Erase]按钮。 ?单击[Browse]按钮,导航到套件设备的预编译引导加载程序十六进制文件,单击[Open],然后单击[Program]。

单片机自编程及Bootloader设计

?Bootloader是在单片机上电启动时执行的一小段程序。也称作固件,通过这段程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用应用程序准备好正确的环境。 Boot代码由MCU启动时执行的指令组成。这里的loader指向MCU的Flash中写入新的应用程序。因此,Bootloader是依赖于特定的硬件而实现的,因此,在众多嵌入式产品中目前还不可能实现通用Bootloader。 Bootloader的最大优点是:在不需要外部编程器的情况下,对嵌入式产品的应用代码进行更新升级。它使得通过局域网或者Intemet远程更新程序成为可能。例如,如果有5 000个基于MCU的电能表应用程序需要更新,电能表制造商的技术人员就可以避免从事对每一个电能表重新编程的巨大工作量,通过使用Bootloader的功能,由控制中心通过电能表抄表系统网络,远程对5 000个电表重新编程。可见,Bootloader功能对于嵌入式系统的广泛应用具有十分重要的意义。 1 78K0/Fx2系列单片机简介 78K0/Fx2系列是带CAN控制器的8位单片机,该系列单片机广泛应用于汽车电子,智能仪表等领域。其内置POC(可编程上电清零电路)/LVI(可编程低电压指示器),单电压自编程闪存,引导交换功能(闪存安全保护),具有低功耗、宽电压范围、超高抗干扰等性能。 78K0系列单片机支持自编程(Self-programming)。所谓自编程,是指用Flash存储器中的驻留的软件或程序对Flash存储器进行擦除/编程的方法。通过单片机的自编程功能,可以设计Bootloader程序,通过串口等通信接口实现对产品重新编程、在线升级的功能。 以μPD78F0881为例。μPD78F0881为78KO/Fx2系列中的一款44管脚单片机,内置32 KB Flash ROM,2 KB RAM,自带2个串行通信接口。其内部Flash结构如图1所示。为了方便实现擦除和编程,人为地将整个Flash分成若干个block,每个block 大小为1 KB。block为自编程库函数中空白检测、擦除、校验的最小单位。blockO从地址0000H开始,程序都从0000H开始执行。block0~block3共4 KB存储空间为 Bootloader程序存储区域。block4~block31为应用程序存储区域。

Linux启动全过程-由bootloader到fs

Linux启动过程 许多人对Linux的启动过程感到很神秘,因为所有的启动信息都在屏幕上一闪而过。其实Linux的启动过程并不象启动信息所显示的那样复杂,它主要分成两个阶段: 1.启动内核。在这个阶段,内核装入内存并在初始化每个设备驱动器时打印信息。 2.执行程序init。装入内核并初始化设备后,运行init程序。init程序处理所有程序的启动, 包括重要系统精灵程序和其它指定在启动时装入的软件。 下面以Red Hat为例简单介绍一下Linux的启动过程。 一、启动内核 首先介绍启动内核部分。电脑启动时,BIOS装载MBR,然后从当前活动分区启动,LILO获得引导过程的控制权后,会显示LILO提示符。此时如果用户不进行任何操作,LILO将在等待制定时间后自动引导默认的操作系统,而如果在此期间按下TAB键,则可以看到一个可引导的操作系统列表,选择相应的操作系统名称就能进入相应的操作系统。当用户选择启动LINUX操作系统时,LILO就会根据事先设置好的信息从ROOT文件系统所在的分区读取LINUX映象,然后装入内核映象并将控制权交给LINUX内核。LINUX内核获得控制权后,以如下步骤继续引导系统: 1. LINUX内核一般是压缩保存的,因此,它首先要进行自身的解压缩。内核映象前面的一些代码完成解压缩。 2. 如果系统中安装有可支持特殊文本模式的、且LINUX可识别的SVGA卡,LINUX会提示用户选择适当的文本显示模式。但如果在内核的编译过程中预先设置了文本模式,则不会提示选择显示模式。该显示模式可通过LILO或RDEV工具程序设置。 3. 内核接下来检测其他的硬件设备,例如硬盘、软盘和网卡等,并对相应的设备驱动程序进行配置。这时,显示器上出现内核运行输出的一些硬件信息。 4. 接下来,内核装载ROOT文件系统。ROOT文件系统的位置可在编译内核时指定,也可通过LILO 或RDEV指定。文件系统的类型可自动检测。如果由于某些原因装载失败,则内核启动失败,最终会终止系统。 二、执行init程序 其次介绍init程序,利用init程序可以方便地定制启动其间装入哪些程序。init的任务是启动新进程和退出时重新启动其它进程。例如,在大多数Linux系统中,启动时最初装入六个虚拟的控制台进程,退出控制台窗口时,进程死亡,然后init启动新的虚拟登录控制台,因而总是提供六个虚拟登陆控控制台进程。控制init程序操作的规则存放在文件/etc/inittab中。Red Hat Linux缺省的inittab文件如下:# #inittab This file describes how the INIT process should set up the system in a certain #run-level. # # #Default runlevel.The runlevels used by RHS are: #0-halt(Do NOT set initdefault to this) #1-Single user mode #2-Multiuser,without NFS(the same as 3,if you do not have networking) #3-Full multiuser mode #4-unused #5-X11 #6-reboot(Do NOT set initdefault to this)

Boot_Loader介绍

Boot Loader Windows CE最大程度继承了桌面版Windows的丰富功能,但是Windows CE并不是一个通用的安装版操作系统。在形形色色的嵌入式设备世界里,一款CE系统通常只会针对某一种硬件平台生成。 一般来说,Windows CE的开发过程可以分为:0AL(OEM Abstraction Layer)、驱动、应用程序开发三个步骤。其中,0AL开发最基本的一步是板级支持包(BSP),而BootLoader 设计则在BSP开发中具有极为关键的地位。 1.什么是BootLoader 嵌入式系统的启动代码一般由两部分构成:引导代码和操作系统执行环境的初始化代码。其中引导代码一般也由两部分构成:第一部分是板级、片级初始化代码,主要功能是通过设置寄存器初始化硬件的工作方式,如设置时钟、中断控制寄存器等,完成内存映射、初始化MMU等。第二部分是装载程序,将操作系统和应用程序的映像从只读存储器装载或者拷贝到系统的RAM中并执行。 (1)什么是板级BSP? BSP(Board Support Package)是板级支持包,是介于主板硬件和操作系统之间的一层,主要是为了支持操作系统,使之能够更好的运行于硬件主板。不同的操作系统对应于不同形式的BSP,例如WinCE的BSP和Linux的BSP相对于某CPU来说尽管实现的功能一样,可是写法和接口定义是完全不同的。所以,BSP一定要按照该系统BSP的定义形式来写,这样才能与上层OS保持正确的接口,良好的支持上层OS。 (2)什么是Boot Loader 在BSP中有一个重要的组成部分就是BootLoader,它是在操作系统内核运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,为调用操作系统内核准备好环境。

stm32f103rb的bootloader软件安全设计方案

STM32F103RB的Bootloader软件安全设计 方案 时间:2009-10-19 12:31:50 来源:单片机与嵌入式系统作者:深圳大学林郭安黄强许文焕 引言 随着嵌入式系统产品的发展,其功能趋向系统化、复杂化,不同场合和具体应用对产品的升级维护提出了更多的需求。厂商针对这一问题普遍采用。Bootloader引导应用程序结构的嵌入式软件,在产品升级和维护过程中只需提供升级程序包由Bootloader在升级模式下更新产品的应用程序,即可快捷地实现产品升级。 一直以来,嵌入式软件的安全和知识产权保护是厂商面对市场竞争着重关心的焦点。嵌入式系统处理器的有限硬件资源和高效率要求使得其难以应用复杂和大运算量的加密算法,对代码的保护更多依赖于硬件,这往往具有很多潜在的安全隐患。本文就.Bootloader引导应用程序结构的软件在STM32F103RB芯片上应用时,遭到篡改攻击后所面临的代码泄漏风险进行研究和验证,并提出了改进Bootloader的安全设计方案,加强代码的安全性。 1 篡改攻击风险研究 1.1 研究的意义 嵌入式系统产品的开发往往成本高、开发周期长,一旦产品中的嵌入式软件被抄袭或盗窃都将给厂商带来巨大的损失。随着嵌入式处理器设计技术的发展,对片内Flash 中的代码保护也日渐完善。芯片在保护状态下,可以完全禁止通过调试接口或SRAM中运行的程序读取Flash内容,但产品阶段保存在Flash中的代码运行时对自身的读取是允许的,如果非法使用者通过特殊手段篡改了Flash中的部分代码为非法读取程序,并使之在Flash 中成功运行,将使产品代码发生部分泄漏,这就是产品面临的篡改攻击风险。针对这一风险的研究在实际应用中显得十分重要。 ST公司推出的STM32系列微处理器采用ARM新一代Cortex-M3内核,其中增强型的STM32F103RB具有72 MHz主频、20 KB片内SRAM、128 KB片内Flash以及丰富的接口资源,可以很好地满足广泛的嵌入式产品的应用需求。较低的芯片价格和简单的开发方式使之应用前景非常广阔,对该芯片上代码的安全研究也具有深远意义。 1.2 风险研究 Bootloader引导应用程序结构的嵌入式软件可以满足产品功能升级和维护的需求,在实际应用中被厂商普遍采用。Bootloader程序是在系统上电复位后在Flash中首先执行的一小段代码,其基本功能模块如图1所示。

基于MC9S12XS128 的BootLoader设计

基于MC9S12XS128 的BootLoader 设计 前言 接触飞思卡尔芯片大概有4个月的时间了,对这款16位寄存器有了一定的了解,但是因为飞思卡尔单片机的资料特别少,bootloader相关资料几乎没有,为此写下这篇设计书,方便大家学习参考交流,其中有不对的地方还请大家批评指正。本设计书主要讲解bootloader的实现过程,需对飞思卡尔16位单片机有一定的基础,了解该系列芯片的开发环境CodeWarrior5.1。 一、BootLoader的基石Prm 文件 我们在用CodeWarrior创建一个工程后会产生很多文件,其中有一个连接用的Prm文件,他的位置如图1.1所示。 图1.1 Codewarrior的Prm文件是用来划分代码段、数据段的,这类似于liunx中的连接脚本文件。程序一开始是进行初始化,然后跳转到main函数执行的,这段代码全部放在了ROM_C000处,而ROM_C000对应的地址是0xC000 到0xFEFF,具体实现代码如图1.2所示。第一部分是指明ROM_C000对的地址,第二部分是指明代码所存放的位置是ROM_C000。 我们知道bootloader和app必须在不同的ROM区域,bootloader接收到上位机发送的程序,先将其存储,后再跳转到app位置执行,所以prm文件可以帮我们实现bootloader与app程序的分离。 具体实现方法如下: 1、将原来的ROM_C000分成两个部分,ROM_BootLoader和ROM_App,因为bootloader代码较小需要保护,所以将其地址设置成0xf000-0xfeff,App的地址设置成0xc000-0xefff,这样这两块的总地址大小正好是原ROM_C000的大小。

bootloader流程

Bootloader 设计分析 3.1 Bootloader 的操作模式 (Operation Mode) 大多数 Bootloader 都包含两种不同的操作模式[2]: (1). 启动加载(Boot loading)模式:也称为“自主”模式。即Bootloader 从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,整个过程并没有用户的介入。 (2).下载(Downloading)模式:在这种模式下,目标机上的Bootloader将通过串口或网络连接等通信手段从主机(Host)下载内核映像和根文件系统映像等,然后保存到目标机上的FLASH 类固态存储设备中。Bootloader的这种模式通常在系统初次安装和更新时被使用,工作于这种模式下的Bootloader通常都会向它的终端用户提供一个简单的命令行接口。 在我们的Bootloader设计中我们同时支持这两种工作模式,采用的方法是:一开始启动时处于正常的启动加载模式,但并不立即启动进入uClinux内核,而是提示延时5秒,等待终端用户如果按下某一特定按键,则切换到下载模式,否则继续启动uCLinux 内核。 3.2 Bootloader 的启动及初始化 基于ARM的芯片多数为复杂的片上系统(SoC),这类复杂系统里的多数硬件模块都是可配置的[3]。因此大多数 Bootloader 都分为 stage1 和 stage2 两大部分。依赖于 CPU 体系结构的代码,通常都放在 stage1 中,而且在这一部分,我们直接对处理器内核和硬件控制器进行编程,因此常常都用汇编语言来实现。而stage2则通常用C语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。 3.2.1 Bootloader的stage1 这部分代码必须首先完成一些基本的硬件初始化,为stage2的执行以及随后的kernel 的执行准备好一些基本的硬件环境[2]。Bootloader的stage1一般通用的内容包括: * 定义程序入口点 * 设置异常向量表 * 初始化存储系统(包括地址重映射) * 初始化有特殊要求的端口,设备 * 初始化用户程序的执行环境

相关文档
最新文档