文档库 最新最全的文档下载
当前位置:文档库 › [原创]自己动手编写嵌入式Bootloader之(1)

[原创]自己动手编写嵌入式Bootloader之(1)

[原创]自己动手编写嵌入式Bootloader之(1)
[原创]自己动手编写嵌入式Bootloader之(1)

第一部分:基本功能流程

CPU上电后会从IO空间的某地址取第一条指令。但此时:PLL没有启动,CPU工作频率为外部输入晶振频率,非常低;CPU工作模式、中断设置等不确定;存储空间的各个BANK(包括内存)都没有驱动,内存不能使用。在这种情况下必须在第一条指令处做一些初始化工作,这段初始化程序与操作系统独立分开,称之为bootloader。

实际上,很少有必要自己写一个Bootloader,因为U-Boot已经强大到能够满足各种需要。但是强大必然复杂,一个初学者想要分析U-Boot的源代码,还是有些难度的。出于学习的目的,我写了这个史上最简单的启动加载器,它只包含最基本的功能,却囊括了一个嵌入式Bootloader应该有的核心和精华。我把这个启动加载器命名为S-Boot,是Simple Bootloader的缩写,亦可进一步简称为SB。

使用的实验环境为OK2440开发板,板上处理器为S3C2440A,有64M内存,Nand存储器为K9F1208,64M。网口芯片为CS8900A。我们要实现的功能是:从串口下载Linux内核映像到RAM;从网口下载Linux内核映像到RAM;从RAM启动内核挂载NFS根文件系统。

1. 第一阶段的汇编代码:start.S

一个嵌入式Bootloader最初始部分的代码几乎必须是用汇编语言写成的,因为开发板刚上电后没有准备好C程序运行环境,比如堆栈指针SP没有指到正确的位置。汇编代码应该完成最原始的硬件设备初始化,并准备好C运行环境,这样后面的功能就可以用C语言来写了。

对我们的S-Boot来说,上电后的起始运行代码是start/start.S。

这里,汇编指示符.text表明以下内容属于代码段,.global _start指明_start是全局可访问的符号(Give the symbol external linkage)。按照ARM920T的规定,从地址0x00到0x1C 放置异常向量表,向量表每个条目占四个字节,正好可以放置一条跳转指令,跳转到相应异常的服务程序中去。在S-Boot中没有使用中断,所以除Reset异常外,其它异常的服务程序都可简单地写个死循环。Reset异常是系统上电后自动触发的,所以我们的代码都写在Reset的服务程序里面。

实际上,异常向量表不一定非要位于地址0x00处,CP15协处理器中的c1寄存器的第13位用来控制异常向量表的起始地址。该位为0时,异常向量表位于低地址0x00处;该位为1时,异常向量表位于高地址0xFFFF0000处。我们没有必要改变这个位的值,使用默认的低地址就行了。

代码最初始的任务是设置CPU工作在SVC32模式,关闭所有中断,禁用看门狗。实际上,即使不设置工作模式,CPU在复位之后将自动工作在管理模式。在整个S-Boot运行期间,我们没有使用中断,也没有改变CPU工作模式,它将一直工作在SVC32模式。

MMU、ICache、DCache的打开和关闭都是由CP15协处理器的c1寄存器控制的。实际上在复位之后这三者都是自动关闭的,所以省略了关闭它们的代码。

S3C2440A的PSR寄存器(Program Status Reguster)中每个Bit位的含义如图1所示。Bit4~Bit0为模式位,用来设置CPU工作模式,现在只要知道M[4:0] = 10011 表示SVC32模式就行了。Bit5为状态位,T=0表示工作在ARM状态,T=1表示工作在Thumb状态,默认为0,不需要改变。Bit6为快速中断禁止位,F=1为禁止快速中断,F=0为使能快速中断。Bit7为中断禁止位,I=1为禁止中断,F=0为使能中断。其它Bit位暂时可以不必理会。

mrs 和msr是在PSR寄存器和其它寄存器间传递数据的指令。如:mrs r0,cpsr 把cpsr的值传送到r0中,msr cpsr,r0 把r0的值传送到cpsr中。bic是位清零(Bit Clear)指令,bic r0,r0,#0x1F 意思是把r0的Bit[4:0]位清零(由0x1F指示),然后把结果写入r0中。orr是按位求或指令,orr r0,r0,#0xD3 表示把r0的Bit7,Bit6,Bit4,Bit1,Bit0 置为1,其它位保持不变。

执行完上述操作后,cpsr中的I=1, F=1, T保持不变(默认为0),M[4:0]=10011,意思是禁止IRQ,禁止FIQ,工作在ARM状态,工作在SVC32模式。

禁用看门狗更简单,因为WTCON寄存器的地址为0x53000000,直接向该寄存器写0即可。

到目前为止,CPU工作在外接晶振12MHz频率之下。使用以下代码设置PLL,提升工作频率。

最后的结果是,FCLK=400MHz,HCLK=100MHz,PCLK=50MHz。

设置存储控制器。

这里把所有的代码从Nand拷贝到RAM中,然后跳转到main函数去执行。此后程序便在RAM中运行了。但是到目前为止,前面的程序都是在SteppingStone里运行的。所谓SteppingStone,是指在S3C2440A的内部的4KB的RAM缓存,它总是映射到地址0x00处。硬件加电后会自动将Nand Flash中的前4KB的数据拷贝到Stepping Stone中,然后从地址0x00处开始运行。

如果代码足够小(小于4KB)的话,那只在SteppingStone中运行,加载Linux内核到内存即可。但通常代码肯定会大于4KB。所以Bootloader一般分为两部分,Stage1的代码在SteppingStone中运行,它会把Stage2的代码拷贝到RAM中,并跳转到RAM中执行;Stage2的代码在RAM中执行,它可以完成加载内核及其它任何复杂的功能。因为Stage2的起始位置不好确定,为了方便,我们把所有的代码都拷贝到RAM中了。

C 函数nand_read有三个参数,第一个参数为目的地起始地址,第二个参数为源起始地址,第三个参数为要复制的数据长度,以字节为单位。根据ATPCS 函数调用规则,三个参数分别用寄存器r0,r1,r2来传递。我们在内存的0x33000000处存放Bootloader,复制长度根据编译生成的S- Boot.bin映像文件大小,向上取512字节的整数倍。

这里先来规划一下内存空间的分配。RAM的地址范围是从0x30000000到0x34000000共64MByte。把S-Boot和Kernel放在高地址处,S-Boot从0x33000000开始,预留8MByte 的空间,内核从0x33800000开始,可供使用的空间也是8MByte。因栈空间是向下生长的,我们在S-Boot下面预留4096Byte的空闲区域,然后向下为栈空间,故栈指针SP初始化为0x32FFF000。其实留不留空闲区域是无所谓的,这里只是为了把二者更明显地区分开。我们只设置SVC模式下的SP,不使用CPU的其它工作模式,所以也没必要设置其它模式下的栈指针。另外,程序中不使用动态内存分配,故而也不必分配堆空间。

2. nand读操作

在编译连接时,我们把上述start.S 代码放在生成的二进制映像文件的最开始位置,因而也被烧写到Nand Flash 的最起始位置,因而会被自动拷贝到SteppingStone 里运行。start.S 要完成的任务之一,是把S-Boot的所有代码从Nand Flash拷贝到内存中,这里需要对NAND 的读操作,因此对NAND的初始化和读操作要在第一阶段写好。

以开发板上使用的K9F1208为例,每个页(page)为512Byte数据和16Byte校验,每个块(Block)为32个页,即16KByte数据和512Byte校验。

Nand Flash只用8根线与CPU的DATA0-7连接,位宽为8位,不管是数据、地址或控制字都通过这8根线传递,如果读写数据的话每次只能传输一个字节数据。Nand Flash的操作通过NFCONF、NFCMD、NFADDR、NFDATA、NFSTAT和NFECC六个寄存器来完成。在

S3C2440A数据手册第218页可以看到读写Nand Flash的操作时序:1. 通过NFCONF寄存器配置Nand Flash;2.写Nand Flash命令到NFCMD寄存器;3.写Nand Flash地址到NFADDR寄存器;4. 在读写数据时,通过NFSTAT寄存器获得Nand Flash的状态信息。应该在读操作前或写操作后检查R/nB信号(Ready/Busy信号)。

初始化NAND Flash:S3C2440的NFCONF寄存器用来设置时序参数TACLS、TWRPH0、TWRPH1,设置数据位宽;还有一些只读位。TACLS、TWRPH0、TWRPH1这三个参数控制的是Nand Flash信号线CLE/ALE与写控制信号nWE的时序关系。

注意,寄存器值转换成实际的时钟周期值时,TACLS不需加1,而TWRPH0和TWRPH1需要加1。比如NFCONF寄存器中设置TACLS=1,TWRPH0=3,TWRPH1=0,意思是时序图中TACLS=1个HCLK时钟,TWRPH0=4个HCLK时钟,TWRPH1=1个HCLK时钟。

读操作:读操作也是以页(512Byte)为单位进行的。在初始上电时,器件进入缺省的“读方式1模式”。在这一模式下,页读操作通过将0x00写入指令寄存器,接着写入3个地址(1个列地址和2个行地址)来启动。一旦页读指令被器件锁存,下面的页读操作就不需要再重复写入页读指令了。写入页读指令和地址后,处理器可以通过对信号线R//B 的分析来判断页读操作是否完成。如果信号为低电平,表示器件正忙;如果信号为高电平,表示器件内部操作完成,要读取的数据被送入了数据寄存器。外部控制器可以再以50ns为周期的连续/RE脉冲信号的控制下,从IO口依次读出数据。连续页读操作中,输出的数据是从指定的列地址开始,直到该页最后一个列地址的数据为止。

缺点:没有使用ECC校验和纠错;没有使用坏块检查;

3. main 函数

串口初始化,以便能够向用户输出一些信息;网口初始化,以便能够从主机下载内核映像;输出一些菜单,以便用户选择执行所需要的功能。比如,用户可以选择从串口或网口下载内核映像到RAM中某个地址,然后运行这个内核。关于下载内核映像的实现,在后文会详细介绍。这里只看当内核映像已经存在于RAM中时,怎样才能把这个内核启动起来。

4. 启动参数的传递

启动Linux内核之前需要设置好一些必要的启动参数,这些参数以TAG列表的形式传递给内核。所谓TAG列表,就是多个TAG在内存空间中按顺序排列。每个TAG,其实都是一个结构体,每个结构体中又包含了一个头部结构体和一个内容结构体称。头部结构体指明了本TAG的类型、占用空间大小;所谓TAG的类型,就是一个宏定义,用一个确定的整数来识别该标记。内容

结构体包含了该TAG的具体内容。

下面以具体的例子做说明。

在atag.h中就有:

这些都是TAG的类型,注意这些整数跟地址没有关系,只是一个用来识别标记类型的符号而已。

每个Tag都用结构体表示,包含TagHeader 头结构体以及随后的参数值数据结构。如 ATAG_CORE:

struct Atag {

struct TagHeader stHdr;

struct TagCore stCore;

};

其中包含两个结构体。第一个结构体TagHeader含两个整型变量,用以表示本结构体的长度、标记类型;nSzie赋值为头部TagHeader和数据TagCore的大小之和,注意是以字(即4字节)为单位;ulTag 就赋值为先前定义的宏ATAG_CORE。第二个结构体就是实际的数据了。

由于每个Tag都由一个TagHeader加一个数据部分组成,因此通常的做法是使用Struct和Union相结合来定义:

其中涉及到的所有数据结构均可在Linux 内核源码的include/asm/setup.h 头文件找到,我们把这些定义放在Bootloader的头文件atag.h中。

启动参数标记列表以标记ATAG_CORE 开始,以标记ATAG_NONE 结束。每个标记由标识被传递参数的tag_header 结构以及随后的参数值数据结构来组成。数据结构tag 和

tag_header 定义在Linux 内核源码的include/asm/setup.h 头文件中,在我们的S-Boot中对应的头文件为atag.h。

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

向内核传递参数的方法,先在内存中某个起始地址开始,连续存放多个Tag, 组成Tag列表。列表中的每个Tag包括头部TagHeader和数据结构体。按规定,第一个Tag必须是ATAG_CORE,最末一个Tag必须是ATAG_NONE,而且中间必须包含至少一个ATAG_MEM。注意的是末尾的ATAG_NONE只包括头部,没有数据内容。如图所示。

在编程时先定义好起始地址,然后用一个指针,每设置完毕一个Tag的内容就向后移动相应的长度,然后设置下一个Tag内容,以保证各个Tag的连续存放。

下面具体说明几个关键Tag的数据区域内容的设置。struct TagCore结构体已经在前面列出,它包含三个整型变量,ulFlags一般设为零,nPageSize表示分页内存管理中每一页的大小,一般为4096字节,ulRootDev是系统启动的设备号,设为零即可,因为通常在后面的命令行参数Cmdline中覆盖这个设置。Struct TagMem用来描述系统的物理内存地址空间,定义如下:

其中nSzie表示内存的总大小,ulStart为内存的起始物理地址,二者结合告诉内核系统可用的物理内存空间是哪些。Struct TagCmdline结构体的定义就更简单了,只是一个字符数组,初始长度为1,如下所示:

实际上命令行参数不可能只有一个字节,我们通常使用strcpy函数把命令行参数拷贝到cCmdLine地址处,在结尾附加一个字符串结束符’\0’,然后用strlen 函数获得cCmdLine数组的实际长度(包括字符串结束符)。常见的命令行参数如:root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200 mem=65536。我们知道的是,Bootloader以标记列表的形式向内核传递的参数,大概有10种不同类型的Tag,而命令行参数只是其中的一种。其它需要设置的Tag包括ATAG_RAMDISK、ATAG_INITRD等,此处不再详细介绍。

在我们的S-Boot中设置了ATAG_CORE,ATAG_MEM,ATAG_CMDLINE,ATAG_NONE 四项。其中CmdLine 使用的是:

const char *CmdLine = "root=/dev/nfs nfsroot=192.168.1.249:/home/hongwang/mkrootfs/rootfs

ip=192.168.1.252:192.168.1.249:192.168.1.1:255.255.255.0:https://www.wendangku.net/doc/fb8161153.html,:eth0:off console=ttySAC0,115200 init=/linuxrc mem=65536K console=tty1

fbcon=rotate:2";

这里root=/dev/nfs表示使用NFS做根文件系统,注意并不真的存在/dev/nfs这个设备,它只是一个符号而已,告诉内核使用NFS而不是使用真正的设备做根文件系统。

nfsroot=[:][,]

nfsroot=192.168.1.249:/home/hongwang/mkrootfs/rootfs是NFS服务器地址及要挂载的目录。

ip=::::::

ip=192.168.1.252:192.168.1.249:192.168.1.1:255.255.255.0:https://www.wendangku.net/doc/fb8161153.html,:eth0:off

只说明一下autoconf,这一个选项指明开发板使用的自动配置IP地址的方法,有时开发板可以设置成通过DHCP或者BOOTP等协议从服务器获取IP地址。off 或none 表示不使用自动配置,使用指定的静态IP地址信息。

console=ttySAC0,115200 串口控制台

console=tty1 fbcon=rotate:2 液晶屏Framebuffer控制台,如果内核支持,可以在LCD屏幕上显示Linux内核启动过程,起点结束后在LCD屏幕上进入Shell控制台供用户操作。fbcon=rotate:2表示控制台旋转180度,若为1表示旋转90度,3旋转270度,0不旋转。

4. boot kernel zImage

zImage 二进制文件包含两部分内容,起始部分是解压缩程序,后面是压缩的内核。解压缩程序是最先运行的,内核中文件是:arch/arm/boot /compressed/head.S,它负责把压缩的内核解压到0x30008000处。因此zImage可以下载到RAM任意位置处,由解压缩程序负责搬移到正确的运行地址。

所以Bootloader启动Linux内核的方法就是直接跳转到内核的第一条指令处,也就是跳转到内存中存放内核映像的开始地址,内核映像具有自解压功能,会把自己释放到正确的运行地址。Tag列表怎样传给内核呢?使用的方法是把Tag列表的起始地址传给内核。首先,定义一个指向函数的指针:

typedef void (*LINUX_KERNEL_ENTRY)(int, int, UINT32);

LINUX_KERNEL_ENTRY pfExecKernel;

这样pfExecKernel就是一个函数指针,函数具有三个整型变量。然后,让pfExecKernel指向内核映像的起始地址处,这里使用强制类型转换把地址转换成函数指针类型:

pfExecKernel = (LINUX_KERNEL_ENTRY)pKernelStartAddr;

最后,以三个参数调用pfExecKernel函数:

pfExecKernel(0, MACH_ID, ATAG_BASE);

其中第一个参数默认为零,可以不必理会。第二个参数是机器ID号,不同的CPU有不同的号码与之对应,可以在内核源代码的linux/arch/arm/tools/mach-types 文件中查到,

S3C2440 对应的MACH_ID 为362。第三个参数ATAG_BASE就是上文讲到的Tag列表的首地址。

这个函数调用的作用其实就是设置r0=0,r1=机器ID,r2=TAG首地址,然后跳到

arch/arm/boot/compressed/head.S文件中的第一条指令处。

既然可以把TAG首地址传递给内核,那么TAG LIST就可以放在RAM中的任何位置了,只要不与其它有用内容冲突即可。但是事实却并不是想象的这样。实验发现,第三个参数传递进去的TAG首地址似乎没有起到作用,因为启动时总是找不到正确的启动参数。后来发现内核有个默认的TAG首地址0x30000100,它总是到0x30000100去寻找启动参数,而不理会我们传进来的第三个参数。所以,S-Boot中把TAG首地址就设置为0x30000100。

5. 小结

综上所述,包含最基本功能的S-Boot运行流程已经很清楚了。下图对此作了一个总结。

阐述对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也能够支持多种结构的嵌入式系统。通常它们能够自动从存储介质上启动,都能够引导操作系统启动,并且大部分都可以支持串口和以太网接口。

嵌入式Linux之我行——u-boot-2009_08在2440上的移植详解(六) - Bootloader移植篇 - hbhuanggang

嵌入式Linux之我行——u-boot-2009.08在2440上的移植 详解(六) 嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验, 二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。 ?共享资源,欢迎转载:https://www.wendangku.net/doc/fb8161153.html, 一、移植环境 ?主机:VMWare--Fedora 9 ?开发板:Mini2440--64MB Nand,Kernel:2.6.30.4 ?编译器:arm-linux-gcc-4.3.2.tgz ?u-boot:u-boot-2009.08.tar.bz2 二、移植步骤 上接:u-boot-2009.08在2440上的移植详解(五) 10)u-boot利用tftp服务下载内核和利用nfs服务挂载nfs文件系统。 知识点: 1.tftp服务的安装与配置及测试; 2.nfs服务的安装与配置及测试; 3.u-boot到kernel的参数传递(重点)。 我们知道使用tftp下载内核和使用nfs挂载文件系统的好处是,当我们重新编译内核或文件系 统后不用重新把这些镜像文件再烧录到flash上,而是把这些镜像文件放到开发主机的tftp或nfs 服务的主目录下,通过网络来加载他们,不用频繁的往flash上烧,这样一可以保护flash的使用 寿命,二可以方便的调试内核或文件系统,提高开发效率。可见,让u-boot实现这个功能是一件很有意义的事情。 实现这样的功能很简单,网上也有很多资料。但有很多细节的东西如果稍不注意就导致失败,这里就结合本人实现的过程进行讲述和一些问题的分析。 ?tftp服务的安装与配置及测试 要使用tftp服务及测试它要安装两个软件包,一个就是tftp服务器,另外一个就是tftp客户端,这里安装客户端只是用于在主机本地测试tftp服务器是否正常运行的,来确保u-boot能够访 问tftp服务(u-boot中已有tftp客户端的功能,其实在前面几篇中都已经使用了tftp下载内核或 文件系统到开发板上,如果那里都做到了,这里就可以直接跳过)。 首先使用rpm命令查看你的主机上是否已经安装了tftp服务器和客户端,如果没有安装就去下 载这两个软件包进行安装或者可以使用yum命令进行在线安装,yum会自动的去搜索适合你主机平 台的最新软件包进行下载安装,如果主机已经安装了,则会提示软件包已经安装了最新的版本。如 下图所示:

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或调用其中一个片上引导加载例程。

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 的内容也被自动清

三级嵌入式系统

三级嵌入式系统学习总结 一第一章 1.嵌入式系统概论 嵌入式系统中的软件一般都固化在只读存储器中,用户不能随意更改其中的程序功能。 嵌入式系统的逻辑组成:1)处理器2)存储器3)I/O设备与I/O接口4)数据总线5)软件 嵌入式处理芯片有四种类型:1)微处理器2)数字信号处理器3)微控制器(单片机)4)片上系统 微控制器MCU的低端产品并不会因为高端产品的出现而衰落 在32位MCU中,绝大多数使用RAM内核 EDA:电子设计自动化 IP核可以分为三种:软核、硬核、固核 2.嵌入式系统与数字媒体 计算机中常用的最广泛的西文字符及其编码是ASCII字符集和ASCII码,即美国标准信息交换码,共有128个字符,一个字符占一个字节。 我国目前广泛使用的汉字编码国家标准有GB2312和GB18030 GB2312只有6763个汉字,不够用 GB18030字符集与国际标准UCS/Unicode字符集基本兼容。GB18030采用不等长的编码方法,单字节编码表示ASCII码,双字节编码表示汉字,与GB2312保持向下兼容,四字节编码表示其他字符 Unicode最新版本是6.3。UCS/Unicode在计算机中具体实现时采用不同的编码方案,最常用的是UTF-8和UTF-16,UTF-8采用的是单字节可变长编码;UTF-16采用的是双字节可变长编码 文本的类型可以分为简单文本、丰富格式文本、超文本 图像的数据量=图像水平分辨率*图像垂直分辨率*像素深度/8(像素深度指的是每个像素用多少个二进制数来表示) 数字视频的数据量非常大,在进行传输时必须进行压缩,压缩编码标准是国际标准化组织(ISO)制定的,其名称为MPEG。 无线局域网采用的协议主要是IEEE 802.11(俗称WIFI) 3.数字通信与计算机网络 微波是一种300MHz-300GHz的电磁波 计算机网络的组成:1)计算机等智能电子设备2)数据通信链路3)通信协议4)网络软件 以太局域网: 1)发送数据设备必须把要传输的数据分成小块(帧)进行传输,一次只能传输1帧; 2)局域网中的每一个终端都有自己唯一的标识,称为物理地址或MAC地址,在发送的每一帧数据中,必须包含自己的MAC地址和接收终端的MAC地址 3)IP协议定义了主机的概念,所有主机及使用一种统一格式的地址标识,称为IP地址。4)以太局域网大多是由集线器或者交换机组网 计算机网络的类型:1)局域网2)城域网2)广域网 IP地址分为A、B、C三类。 IP是由四段数字组成,共32位,8位一段。 A类IP段0.0.0.0 到127.255.255.255 (0段和127段不使用)

嵌入式系统BOOTLOADER的设计与实现

复旦大学 硕士学位论文 嵌入式系统BOOTLOADER的设计与实现 姓名:朱晶 申请学位级别:硕士 专业:计算机应用技术 指导教师:涂时亮 20040427

摘要y- 一 651830 嵌入式系统是把计算机直接嵌入到应用系统中,它融合了计算机软硬件技术,通信技术和半导体微电子技术,嵌入式设备已经越来越多地应用在现代人的工作和生活中,它在当今的应用正变得越来越广泛。BOOTLOADER作为嵌入式系统软件的重要组成部分,对它的研究和实现无疑也具有重要的现实意义。 本文首先对嵌入式系统BOOTLOADER的特点和作用进行了介绍。然后从嵌入式系统的角度对如何实现BOOTLOADER进行了比较全面的分析。 本文对嵌入式系统的硬件初始化,串u驱动及传输协议,网口驱动及传输协议,USB驱动及传输协议,FLASH的驱动等等都做了比较洋细的分析。并结合EV4480丌发板,给出了实现的具体细节。 最后,对已经实现的BOOTLOADER进行了测试和评估,并就今后的改进方向提出了自己的意见。 关键字:嵌入式系统;BOOTLOADER;UCLINUX

Abstract Virtuallyeveryelectronicdevicedesignedandmanufacturedtodayisallembeddedsystem.Briefly,BOOTLOADERisthefirstsoftwareprogramthatrunswhenacomputerstarts.Itisresponsibleforloadingandtransferringcontroltotheoperatingsystemkernelsoftware.ThisessayintroduceshowtodesignBOOTLOADERinanembeddedsystem. FirstthepaperintroducesthefeaturesandthnctionofBOOTLOADER,thenindetailanalyzesBOOTLOADERfromviewofembeddedfield,andbringsupasystemmodelofBOOTLOADER. Inthispaper,italsohaveadetailresearchonsomepartofBOOTLOADER,suchashardwareinitial,UARTdriverandtransferprotocai,lancarddriverandtflp/ipprotocai,USBdriverandtransferprotocal,FLASHdriveretc. Finally,thispaperimplementsandtestsBOOTLOADERinEV4480evaluationboard,thenbringsupsortieadviceontheimprovementinthefuture. Keyword:BOOTLOADER,embeddedsystem,UCLINUX

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.wendangku.net/doc/fb8161153.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分析

?熟悉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程序。

嵌入式BootLoader移植实验三

合肥学院 嵌入式系统设计实验报告 (2013- 2014第二学期) 专业: 实验项目:实验三 BootLoader移植实验 实验时间: 2014 年 5 月 7 实验成员: ___ 指导老师:干开峰 电子信息与电气工程系 2014年4月制

一、实验目的 1、熟悉Bootloader工作原理。 2、了解U-Boot的代码结构。 3、掌握U-Boot移植过程。 二、实验内容 本实验熟悉Bootloader工作原理,了解U-Boot源码结构,基于S3C2440处理器,完成U-Boot移植,并在目标开发板上测试通过。 三、移植环境 u-boot版本:u-boot-2011-03 Linux平台:Fedora 14 交叉编译工具:arm-linux-gcc-4.3.3 arm开发板:micro2440 CPU:S3C2440 SDRAM:64M 1 Nor Flash:2M Nand Flash:256M 网卡:DM9000EP 四、实验过程 1、建立Micro2440配置 (1)按下图所示命令解压u-boot-2011.03-micro2440.tar压缩包 (2)输入命令:gedit boards.cfg打开boards.cfg文件。 在boards.cfg中添加一行:micro2440 arm arm920t - samsung s3c24x0 语句。 (3)创建板级支持文件 输入命令:cp -r board/samsung/smdk2410 board/samsung/micro2440 cd board/samsung/micro2440/ mv smdk2410.c micro2440.c gedit Makefile

Bootloader的概念和作用

Bootloader的概念和作用 (1)Bootloader的概念和作用 Bootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序,其作用类似于 PC 机上的 BIOS。在完成对系统的初始化任务之后,它会将非易失性存储器(通常是 Flash或 DOC 等)中的Linux 内核拷贝到 RAM 中去,然后跳转到内核的第一条指令处继续执行,从而启动 Linux 内核。由此可见,bootloader 和 Linux 内核有着密不可分的联系,要想清楚的了解 Linux内核的启动过程,我们必须先得认识 bootloader的执行过程,这样才能对嵌入式系统的整个启过程有清晰的掌握。 (2)Bootloader的执行过程 不同的处理器上电或复位后执行的第一条指令地址并不相同,对于 ARM 处理器来说,该地址为 0x00000000。对于一般的嵌入式系统,通常把 Flash 等非易失性存储器映射到这个地址处,而bootloader就位于该存储器的最前端,所以系统上电或复位后执行的第一段程序便是 bootloader。而因为存储 bootloader的存储器不同,bootloader的执行过程也并不相同,下面将具体分析。 嵌入式系统中广泛采用的非易失性存储器通常是 Flash,而 Flash 又分为 Nor Flash 和Nand Flash 两种。它们之间的不同在于: Nor Flash 支持芯片内执行(XIP, eXecute In Place),这样代码可以在Flash上直接执行而不必拷贝到RAM中去执行。而Nand Flash并

不支持XIP,所以要想执行 Nand Flash 上的代码,必须先将其拷贝到 RAM中去,然后跳到 RAM 中去执行。 实际应用中的 bootloader根据所需功能的不同可以设计得很复杂,除完成基本的初始化系统和调用 Linux 内核等基本任务外,还可以执行很多用户输入的命令,比如设置 Linux 启动参数,给Flash 分区等;也可以设计得很简单,只完成最基本的功能。但为了能达到启动Linux 内核的目的,所有的 bootloader都必须具备以下功能[2] :初始化 RAM处理 因为 Linux 内核一般都会在 RAM 中运行,所以在调用 Linux 内核之前 bootloader 必须设置和初始化 RAM,为调用 Linux内核做好准备。初始化 RAM 的任务包括设置 CPU 的控制寄存器参数,以便能正常使用 RAM 以及检测RAM 大小等。 初始化串口 串口在 Linux 的启动过程中有着非常重要的作用,它是 Linux 内核和用户交互的方式之一。Linux 在启动过程中可以将信息通过串口输出,这样便可清楚的了解 Linux 的启动过程。虽然它并不是bootloader 必须要完成的工作,但是通过串口输出信息是调试bootloader 和Linux 内核的强有力的工具,所以一般的 bootloader 都会在执行过程中初始化一个串口做为调试端口。 检测处理器类型

ARM7的Bootloader和分散加载文件笔记

Boot Loader概述 简单地说,在操作系统内核运行之前,通过一小程序,可以初始化硬件设备、建立内存空间的映射图等,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核配置好相应的环境,也可以下载文件到系统板上的SDRAM,对Flash进行擦除与编程,这个小程序一般称为Boot Loader。可以说,一个功能完善的Boot Loader已经相当于一个微型的操作系统了。 Boot Loader作为系统复位或上电后首先运行的代码,一般应写入Flash存储器并从起始物理地址0x0开始。Boot Loader是非常依赖于硬件而实现的,而且根据实现的功能不同,其复杂程度也各不相同。一个简单的Boot Loader可以只完成USB口的初始化,而功能完善的Boot Loader可以支持比较复杂的命令集,对系统的软硬件资源进行合理的配置与管理。因此,建立一个通用的Boot Loader 几乎是不可能的。 系统初始化代码直接对ARM微处理器内核及硬件控制器编程,多采用汇编语言编程,初始化代码一般应包括如下典型任务: 1.定义程序入口点; 2.设置异常和中断向量表; 3.初始化存储设备; 4.初始化堆栈指针寄存器; 5.初始化用户执行环境; 6.呼叫主应用程序。 1.1 定义程序入口 初始化代码必须定义整个程序的入口点。通过伪指令Entry指定编译器保留该段代码,同时配合链接器的设置,确定整个程序的入口点。 1.2 设置异常和中断向量表 1.3初始化存储设备 1. 存储器类型和时序的配置 2.存储器的地址分配与地址重映射 一种典型的存储器地址重映射过程描述如下:当系统上电或复位以后,PC指针指向0x0,程序从0x0地址开始执行,因此,为了能正确读取代码,要求此时Flash (或其它类型的ROM)的起始地址为0x0。但Flash(或其它类型的ROM)的访问速度大大低于RAM,每次产生异常后,都要从Flash(或其它类型的ROM)的异常向量表调转到相应的处理程序,会影响异常的响应速度,因此,系统便提供一种灵活的地址重映射方法,在系统完成必要地初始化以后,将RAM安排到0x0 地址处,而将原来位于0x0处的Flash(或其它类型的ROM)安排到其他的地方上去,加快异常的响应速度。

BootLoader 的概念与功能

U-Boot之一:BootLoader 的概念与功能 一般情况下嵌入式Linux 系统中的软件主要分为以下几部分: 1) 引导加载程序:其中包括内部ROM 中的固化启动代码和BootLoader 两部分。内部固化ROM 是厂家在芯片生产时候固化的,作用基本上是引导BootLoader。有的芯片比较复杂,比如Omap3 在flash 中没有代码的时候有许多启动方式:USB、UART 或以太网等等。而S3C24x0 则很简单,只有Norboot 和Nandboot。 2) Linux kernel 和drivers。 3) 文件系统。包括根文件系统和建立于Flash 内存设备之上的文件系统(EXT4、UBI、CRAMFS 等等)。它是提供管理系统的各种配置文件以及系统执行用户应用程序的良好运行环境及载体。 4) 应用程序。用户自定义的应用程序,存放于文件系统之中。 在Flash 存储器中,他们的分布一般如下: 但是以上只是大部分情况下的分布,也有一些可能根文件系统是initramfs,被一起压缩到了内核映像里,或者没有Bootloader 参数区,等等。 1.2 在嵌入式Linux 中BootLoader 的必要性 Linux 内核的启动除了内核映像必须在主存的适当位置,CPU 还必须具备一定的条件:

但是在CPU 刚上电启动的时候,一般连内存控制器都没有初始化过,根本无法在主存中运行程序,更不可能处在Linux 内核启动环境中。为了初始化CPU 及其他外设,使得Linux 内核可以在系统主存中运行,并让系统符合Linux 内核启动的必备条件,必须要有一个先于内核运行的程序,他就是所谓的引导加载程序(Boot Loader)。 而BootLoader 并不是Linux 才需要,而是几乎所有运行操作系统的设备都需要。我们的PC 的BOIS 就是Boot Loader 的一部分(只是前期引导,后面一般还有外存中的各种BootLoader),对于Linux PC 来说,Boot Loader = BIOS + GRUB/LILO。 1.3 Boot Loader 的功能和选择 综上所述:BootLoader 是在操作系统内核启动之前运行的一段小程序。通过这段程序,我们可以初始化硬件设备,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境,最后从别处(Flash、以太网、UART)载入内核映像到主存并跳到入口地址。 由于BootLoader 需要直接操作硬件,所以它严重依赖于硬件,而且依据所引导的操作系统的不同,也有不同的选择。对于嵌入式世界中更是如此。就S3C24x0 而言,如果是引导Linux,一般选用韩国的mizi 公司设计的vivi 或者DENX 软件工程中心的Das U-boot,如果是引导Win CE,就选用Eboot。如果是开发StrongARM 构架下的LART,就可选用由Jan-Derk Bakker 和Erik Mouw 发布的Blob(Boot Loader Object)。如果是要引导eCos 系统,可 以选用同是RedHat公司开发的Redboot。 所以在嵌入式世界中建立一个通用的BootLoader 几乎是不可能的,而可能的是让一个Boot Loader 代码支持多种不同的构架和操作系统,并让她有很好的可移植性。U-boot 就是支持多平台多操作系统的一个杰出代表。这也是U-boot 的优势所在,因为如果在开发 S3C2440 时熟悉了U-boot,再转到别的平台的时候,就可以很快地完成这个平台下U-boot 的移植。而且U-boot 的代码结构越来越合理,对于新功能的添加也十分容易。

嵌入式操作系统bootloader

嵌入式系统的Boot Loader 在专用的嵌入式板子上运行GNU/Linux 系统已变得越来越流行。一个嵌入式Linux 系统从软件的角度看通常可以分为四个层次: 引导加载程序:包括固化在固件(firmware)中的boot 代码(可选)和Boot Loader 两大部分。Linux内核:特定于嵌入式板子的定制内核及内核的启动参数。 文件系统:包括根文件系统和建立于Flash 内存设备之上的文件系统。通常用RAM-Disk 来作为根文件系统。 用户应用程序:特定于用户的应用程序 引导加载程序是系统加电后运行的第一段软件代码,例如PC 机的引导加载程序,包括:BIOS(其本质就是一段固件程序)和位于硬盘MBR 中的OS Boot Loader,比如LILO、GRUB 等。BIOS的主要任务是进行硬件检测和资源分配;将MBR中的OS Boot Loader读到系统的RAM 中;将控制权交给OS Boot Loader。Boot Loader 的主要运行任务是将内核映象从硬盘上读到RAM 中和跳转到内核的入口点去运行,也即启动操作系统。 在嵌入式系统中通常并没有像BIOS 那样的固件程序(注:有的嵌入式CPU 也会内嵌一段短小的启动程序),整个系统的加载启动任务完全由Boot Loader 完成。如在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000 处开始执行,而在这个地址处安排的通常就是系统的Boot Loader 程序。 Boot Loader 是在操作系统内核运行之前运行的第一段小程序,负责初始化硬件设备和建立内存空间的映射图,将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。加载操作系统内核映象到RAM中,并将系统的控制权传递给它。 在嵌入式世界里建立一个通用的Boot Loader 几乎是不可能的,Boot Loader 对硬件的依赖性非常强,特别是在嵌入式系统世界中尽管如此,仍可对Boot Loader 归纳出一些通用的概念,以指导用户特定的Boot Loader 设计与实现。 Boot Loader依赖于CPU 的体系结构和具体的嵌入式板级设备的配置。不同的CPU体系结构都有不同的Boot Loader,有些Boot Loader 也支持多种CPU体系结构,例如U-Boot 同时支持ARM和MIPS体系结构。对于两块不同的嵌入式板,即使它们基于同一种CPU,要想让运行在一块板子上的Boot Loader也能运行在另一块板子上,通常也都需要修改Boot Loader源程序。 系统加电或复位后,所有的CPU 通常都从某个由CPU 制造商预先安排的地址上取指令。比如,基于ARM7TDMI core 的CPU 在复位时通常都从地址0x00000000 取它的第一条指令。基于CPU 构建的嵌入式系统通常都有某种类型的固态存储设备被映射到该预先安排的地址上。比如:ROM、EEPROM 或FLASH 等。 烧写boot loader程序一般通过jtag烧写,需要jtag连接器和PC端的烧写程序。主机和目标机之间一般通过串口建立连接,Boot Loader 在执行时常通过串口来进行I/O,比如输出打印信息到串口、从串口读取用户控制字符等。最常用的串口通信软件有Linux下的minicom和Windows附件中的超级终端。 Boot Loader的启动过程可以是单阶段(Single Stage)或多阶段(Multi-Stage)。一些只需完成很简单功能的boot loader可能是单阶段的。通常多阶段的Boot Loader 能提供更为复杂的功能,以及更好的可移植性。从固态存储设备上启动的Boot Loader 大多都是 2 阶段的启动过程,也即启动过程可以分为stage1 和stage2 两部分。 大多数Boot Loader 包含两种不同的操作模式,启动加载(Boot loading)模式和下载(Downloading)模式。这种区别仅对于开发人员才有意义,从最终用户的角度看,Boot Loader 的作用就是加载操作系统,并不存在上述两种模式的区别。

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上的一个开源项

ARM7TDMI-S在嵌入式系统中的Bootloader代码设计

ARM7TDMI-S在嵌入式系统中的 Bootloader代码设计 摘要:ARM7TDMI-S是ARM公司设计的一款32位精简指令集处 理器内核,LPC210X系列是飞利浦半导体公司生产的基于ARM7TDMI-S 内核的芯片。在嵌入式系统设计中,针对嵌入式处理器和操作系统的Boot loader代码的设计是一个难点。本文根据用LPC2106进行嵌入式系统设计的实际经验,总结出基于ARM7TDMI- S内核的嵌入式处理器芯片的Bootloader代码设计的一般流程;给出LPC2106芯片在基于uC/OS-II操作系统的嵌入式应用中,BootLoader程序的详细设计流程及其中的一些关键技术和代码。 关键词:ARM7TDMI-S嵌入式系统BootLoader代码LPC2106PC/0S-II 引言 芯片的Bootloader代码(即启动代码)就是芯片复位后进入 操作系统之前执行的一段代码,主要是为运行操作系统提供基本的运行环境,如初始化CPU堆栈、初始化存储器系统等。Bootloader 代码与CPU芯片的内核结构、具体芯片和使用的操作系统等因素有关。其功能有点类似于PC机的BIOS (BasicInput/OutputSystem,基本输入输出系统)程序,但是由于嵌入式系统的软硬件都要比PC机的简单,所以它的Bootloader 代

码要比BIOS程序简单得多。 嵌入式系统被定义为:以应用中为心,以计算机技术为基 础,软件硬件可裁剪,适用于系统对功能、可靠性、成本、何种、功耗有严格要求的专用计算机系统。嵌入式系统的核心部件是嵌入式处理器。随着嵌入式系统在人们日常生活中的广泛运用,嵌入式处理器得到前所未有的飞速发展。基于ARM核的嵌入式处理器芯片种类繁多。由于ARM公司只设计内核的不生产具体的芯片,即便是基于同一种内核,不同厂家生产的芯片差别很大,因此不易编写出统一的Boot loader代码。ARM公司针对这一问题而采取的策略是,不提供完事的Bootloader代码(ARM公司的开发工具ADS提供了一些功能代码),Bootloader代码不足的部分由芯片厂商提供或者由用户自己编写。飞利浦公司没有提供LPC210x系列的Bootloader代码,所以用户只能自己编写Bootloader 代码。 1ARM7TDMI-S 和LPC210x ARM7TDMI-S是目前比较低端的ARM核一ARM核不是芯片,它与其它部件如RAM、ROM、片内外设组合在一起才构成实际的芯片。ARM7是用于对成本和功耗都非常敏感的消费应用的低价位、低功耗的32位核。其主要特点如下:冯.诺依曼结构、3段流水线、0. 9MIPS/MHZ;非常低的功耗;嵌入式ICE-RT (InCircuitEmu 1 ation-RealTime,实时在线仿真)逻辑。 LPC2104/2105/2106基于一个支持实时仿真和跟踪的ARM7TDMI-S 内核,并带有128KB的高速Flash存储器,128位宽度的存储器接口

bootloader启动流程

MSM8909+Android5.1.1启动流程概述 PBL:APPS PBL(ApplicationPrimary Boot Loader),主引导加载程序 RPM:ResourcePower Manager,资源电源管理器 RPM(ResourcePower Manager)是高通MSM平台另外加的一块芯片,虽然与AP芯片打包在一起,但其是一个独立的ARM Core。之所以加这个东西,就是要控制整个电源相关的shared resources,比如ldo,clock。负责与SMP,MPM交互进入睡眠或者唤醒整个系统。 L2 TCM:Tightly-CoupledMemory,紧耦合内存 Some ARM SoC:s have a so-called TCM(Tightly-Coupled Memory). This is usually just a few (4-64) KiB of RAM insidethe ARM processor. Due to being embedded inside the CPU TheTCM has a Harvard-architecture, so there is an ITCM (instruction TCM) and aDTCM (data TCM). The DTCM can not contain any instructions, but the ITCM canactually contain data. CDT: Configuration Data Table,包含CDB0: platform info信息和CDB1: DDR配置参数。TZ: PIL:Peripheralimage loader MBA:Modem Boot Authenticator,调制解调器引导认证 HLOS:High-leveloperation system,高级操作系统 Pronto image: SMEM : shared memory RPC : remote procedure call QCSBL : qualcomm second bootloader OEMSBL : oem second bootloader AMSS : Advanced Mobile Subscriber Software SDI : System Debug Image QSEE : Qualcomm Secure Execution Environment TZBSP : TrustZone BSP SBL1:ScondaryBoot Loader Stage1 MSS:MobileSubscriber Software移动用户软件 在ARM的集成开发环境中,只读的代码段和常量被称作RO段(ReadOnly);可读写的全局变量和静态变量被称作RW段(ReadWrite);RW段中要被初始化为零的变量被称为ZI段(ZeroInit)

相关文档
相关文档 最新文档