第10章 Bootloader 设计基础
- 格式:ppt
- 大小:233.00 KB
- 文档页数:33
嵌入式系统中Bootloader 的设计与实现马学文1,朱名日1,2,程小辉1 (1. 桂林工学院电子与计算机系,桂林541004;2.中南大学信息物理工程学院,长沙410083)—97—作者所承研的项目中硬件平台是基于ARM7TDMIRISC 内核的三星公司S3C4510B 微处理器,采用的嵌入式Linux 系统为uCLinux。
系统有64MB SDRAM, 其地址从0x 0800.0000 ~0x0bff.ffff, 还有32MB Flash, 其地址从0x0c00.0000~0x0dff.ffff。
32MB Flash 具体规划如下:从0x0c00.0000 开始的第1 个1MB 放Bootloader,从0x0c10.0000开始的2MB放Linux kernel, 从0x0c30.0000开始的余下部分都给rootdisk。
64MB SDRAM 启动后的具体程序分布示意图如图2 所示。
图2 64MB SDRAM 的程序分布示意图Bootloader 一般有几个文件组成。
先是START.s,也是唯一的一个汇编程序,其余的都是C 语言写成的,START.s主要用来初始化堆栈:_start:ldr r1,=StackInit /* r1 是参数字符串的地址*/ldr sp,[r1]int main().equ StackInitValue,_end_data+0x1000/* 在连结脚本中指定4K __end_data*/StackInit:.long StackInitValue.global JumpToKernelJumpToKernel: /*拷贝内核的代码*/mov pc, r0 /*获得Kernel 地址*/.global JumpToKernel0x /*用来扩展内核*/JumpToKernel0x: /*拷贝获得的扩展内核*/mov r8, r0mov r0, r1mov r1, r2mov r2, r3mov r3, r4mov pc, r8.section“.data.boot”.section“.bss.boot”其中main 函数的C 语言实现过程如下:int main(){U32 *pSource, *pDestin, count;U8 countDown, bootOption;U32 delayCount;U32 fileSize, i;char c;char *pCmdLine;char *pMem;init(); /*初始化Flash 控制器和CPU 时钟*/EUARTinit(); /*串口初始化*/EUARTputString("\n\n Linux Bootloader\n"); /*打印信息*/ EUARTputString((U8 *)cmdLine); /*command_line 支持, 用于定制内核*/EUARTputString("\n\n");用command_line 可以给内核传一些参数,自己定制内核的行为。
bootloader的编写
编写一个bootloader是一个复杂的任务,需要了解计算机架构
和操作系统的启动过程。
以下是编写一个简单的x86 bootloader的基本步骤:
1. 确定引导扇区的位置:在硬盘的第一个扇区(通常是0号扇区)创建一个引导扇区。
这个扇区需要包含一个主引导记录(Master Boot Record,MBR),以便计算机可以正确地引导。
2. 编写MBR代码:MBR是引导扇区中的第一扇区,它包含
了启动计算机所需的你的代码。
MBR的大小为512字节,所
以你的代码必须小于或等于512字节。
3. 使用汇编语言:编写x86汇编语言代码来实现MBR的功能。
你需要了解x86指令集和寄存器的使用。
确保你的代码具有正确的引导标志,并设置正确的启动设备。
4. 编写启动代码:启动代码是你的汇编代码的一部分,它是在MBR中执行的。
启动代码负责加载进一步的代码和操作系统。
这段代码通常位于MBR的末尾,并将控制转移到加载的代码。
5. 加载操作系统:启动代码负责从硬盘上加载操作系统的剩余部分,然后将控制权交给操作系统。
需要注意的是,编写一个完整的、功能完备的bootloader涉及
到更多的细节和复杂性,包括读取硬盘、文件系统的支持、加
载器链等。
上述步骤仅为编写一个最基本的x86 bootloader提供了一个概览。
详解汽车Bootloader设计BootLoader(下文简称Boot)也称为引导程序,其主要用于软件更新。
这就带来一个问题,ECU的软件更新方式有很多,比如通过JTAG 调试更新软件,为什么要Boot呢?由于ECU软件中难免会有BUG存在,以及要满足整车OTA需求,必须可以在不开盖的情况下更新软件。
而ECU控制器对外的接口通常只有总线、电源和控制IO等。
出于最大化复用接口(减少线束的重量和成本)考虑,通常采用基于UDS的Boot,而最常用的总线为CAN。
为什么不用JTAG口呢?主要是ECU 装车后,直接通过烧录器或者仿真器更新软件的很不方便,难以实现远程更新,另外由于JTAG口的权限很高,可以任意修改内部程序,安全风险很大。
01BootLoader的设计需求Boot除了正常满足更新软件需求外,还需满足以下需求。
1、安全需求Boot和APP应该放在不同的内存区域,防止相互干扰。
Boot中不应集成Flash Driver,避免程序在正常运行时非法修改FLash,导致软件异常,通常在刷写App或者标定数据时,先将Flash Driver下载至芯片的RAM中。
另外,在Boot执行App或者标定数据更新时,应该具有多重安全检查机制,确保刷入正确的软件。
首先在执行刷写流程之前,上位机对需要更新的软件包进行检查,通常包括两项,其一是在生成软件包时,开发人员会在特定位置增加一个与上位机约定的特定的ID,当上位机加载软件包时,会去检查软件包中存储的ID是否与上位机中相同,如果不同,则终止刷写,这样可以防止刷入其他ECU的软件包。
其二是在生成软件包时,会对特定地址区域进CRC计算,通常采用CRC32,并将该CRC值存储在特定的地址,通常是程序的末尾,在上位机加载软件包时,按照相同的CRC算法进行计算,并与软件包中存入的进行比较,如果相同则进行下面的流程。
这也是俗称的完整性检查。
在以上确认软件包本身没有问题后,开始准备将软件刷入到车内的ECU中,在此之前需要对当前车辆的刷写条件进行检查,其中主要包括当前是否有车速,档位是否在P档,蓄电池电压是否过低,对于新能源车而言,还需检查高压继电器是否闭合等。
讲解BOOTLOADER(启动代码)的运行机制,代码功能与实现方法。
1.为什么要编写启动代码启动代码是系统上电或复位以后运行的第一段代码,他的作用是在用户程序运行之前对系统硬件及软件环境进行必要的初始化并在最后使程序跳到用户程序.在此之前系统的所有硬件都是不好用的,初始化代码直接对ARM处理器内核及硬件控制器进行编程,所执行的操作与具体的目标系统紧密相关。
2.两种启动方式以及其中的区别根据代码存放位置,以及地址启动位置的区别,ARM支持两种方式的启动:Nor FLASH和 Nand FLASH2.1Nor FLASH启动代码运行方式从Nor FLASH启动时,与nGCS0相连的Nor FLASH就被映射到了nGCS0片选的空间,其地址被映射为0x00000000;因为Nor FLASH支持系统运行,所以不必考虑程序的搬移,只需保证系统上电后或者复位时代码从0开始即可。
2.2Nand FLASH启动代码运行方式从Nand FLASH启动时,芯片内部自带一块容量为 4K的BootSRAM会被映射到nGCS0片选的空间,起始地址被映射为0x00000000,因此,编写的启动代码要保证在0开始的地址处。
系统上电后,BootSRAM没有任何代码,ARM芯片通过硬件机制将Nand FLASH前4K的内容拷贝到其中,然后在BootSRAM中运行这4K的代码(0地址处),此种情况下要保证启动代码放在Nand FLASH的0地址处,启动代码要小于4K(只要RAM 初始化,搬移程序小于4K即可)。
所有程序编译链接后代码量小于4K时,程序不用考虑从 Nand FLASH搬移到SDRAM的问题,因为所有程序在启动时已全部在BootSRAM中,运行即可。
所有程序编译链接后代码量大于4K时,启动代码不只要有初始化内容,还要有一段搬移代码,将全部程序从Nand FLASH搬移到SDRAM,也就是系统启动时需要两次搬运,第一次将前4K搬移到BootSRAM,第二次将所有代码搬移到SDRAM中,其中第一次无需人工干预,硬件机制自动实现,第二次需要程序员编写代码实现。
一、BootLoader是怎么下载应用程序的?应用程序的写入可通过S19文件。
S19文件为飞思卡尔推荐使用的标准文件传送格式,是一段直接烧写进芯片的ASCII码格式:记录类型、记录长度、存储地址、代码数据和校验码5个部分组成每一行总是以S开头,后一位跟着的数据表示改行记录的类型。
S0:说明性信息,非程序数据S1:程序数据,且地址为16位S2: 程序数据,且地址为24位S9:整个S19文件的结束行浅谈BootLoader中的Flash与RAM划分:二、为什么要划分出一块RAM区?对P-Flash擦除与写入操作的时候,不允许同时对其进行读取,故此,对Flash的擦除、写入以及CAN终端信号的处理代码,应复制到RAM中运行。
怎么做?(在飞思卡尔XET256中,这一功能可通过关键字RELOCATE_TO实现。
)因此在划分Flash的同时也应对RAM进行划分,以实现这一功能。
(定义RAM的关键字为READ_WRITE)这样做后得到什么样的结果?划分出一个与P-Flash大小相等的一块RAM区三、关于BootLoader中的地址分配问题飞思卡尔16位单片机复位后总是从优先级最高的中断向量地址0xFFFE处取第一条执行指令。
因此,BootLoader 可执行代码的首地址应安排在此处,以保证上电后BootLoader最先执行。
这可以通过在prm文件中定义VECTOT 0 实现,即将VECTOR 0 定义为Bootloader程序的入口地址。
而应用程序也同样希望对VECTOR 0 定义,以实现在单片机上电后直接执行应用程序的目的。
由于存在这一中断资源冲突,因此,BootLoader在刷写时需要对应用程序的中断向量表进行重新分配。
四、通信协议BootLoader的通信协议的目的是什么?实现BootLoader于上位机之间的命令和状态传输怎么做?在标准的CAN协议基础上,定义一套简单的通信协议。
该协议中所使用的命令和状态均以报文ID表示,即每一个ID代表一个特定的命令或状态。
bootloader的编写[Bootloader的编写]引言:在计算机系统中,所有软件程序的启动都需要从硬件开始,即从计算机的引导加载程序(bootloader)开始。
Bootloader是计算机系统中的第一个程序,它位于计算机的非易失性内存(ROM或闪存)中,负责将操作系统加载到计算机的内存中并进行初始化。
本文将一步一步回答关于Bootloader的编写的问题,帮助读者了解Bootloader的基本原理和编写过程。
一、什么是Bootloader?Bootloader是指位于计算机系统启动过程中的第一个可执行程序,它负责初始化硬件设备、加载操作系统并将控制权交给操作系统。
在引导加载过程中,计算机会首先执行Bootloader程序,然后再按照一定的规则将操作系统加载到内存中并启动它。
二、为什么需要编写Bootloader?编写Bootloader的目的是为了在计算机系统启动时对硬件进行初始化,并将操作系统加载到内存中。
Bootloader起到了桥梁的作用,将硬件和操作系统连接起来。
此外,编写Bootloader还可以添加一些自定义功能,如双重引导、数据恢复等。
三、Bootloader的基本原理是什么?Bootloader编写的基本原理包括以下几个方面:1. 硬件初始化:Bootloader首先需要对计算机的硬件设备进行初始化,包括处理器、内存、外设等。
这些初始化工作是确保计算机能够正常启动的基础。
2. 加载操作系统:Bootloader需要加载操作系统的二进制映像文件(通常是内核文件)到内存中。
这需要通过读取硬盘或其他存储设备上的引导块或分区来完成。
3. 进入操作系统:一旦操作系统加载到内存中,Bootloader将控制权交给操作系统,让其接管计算机的控制。
四、如何编写Bootloader?编写Bootloader的过程可以分为以下几个步骤:1. 了解目标硬件:首先需要了解目标计算机的硬件平台和体系结构,包括处理器类型、内存布局、外设接口等。
bootloader详细介绍Bootloader对于计算机系统来说,从开机上电到操作系统启动需要⼀个引导过程。
嵌⼊式Linux系统同样离不开引导程序,这个引导程序就叫作Bootloader。
6.1.1 Bootloader介绍Bootloader是在操作系统运⾏之前执⾏的⼀段⼩程序。
通过这段⼩程序,我们可以初始化硬件设备、建⽴内存空间的映射表,从⽽建⽴适当的系统软硬件环境,为最终调⽤操作系统内核做好准备。
对于嵌⼊式系统,Bootloader是基于特定硬件平台来实现的。
因此,⼏乎不可能为所有的嵌⼊式系统建⽴⼀个通⽤的Bootloader,不同的处理器架构都有不同的Bootloader。
Bootloader不但依赖于CPU的体系结构,⽽且依赖于嵌⼊式系统板级设备的配置。
对于2块不同的嵌⼊式板⽽⾔,即使它们使⽤同⼀种处理器,要想让运⾏在⼀块板⼦上的Bootloader程序也能运⾏在另⼀块板⼦上,⼀般也都需要修改Bootloader 的源程序。
反过来,⼤部分Bootloader仍然具有很多共性,某些Bootloader也能够⽀持多种体系结构的嵌⼊式系统。
例如,U-Boot就同时⽀持PowerPC、ARM、MIPS和X86等体系结构,⽀持的板⼦有上百种。
通常,它们都能够⾃动从存储介质上启动,都能够引导操作系统启动,并且⼤部分都可以⽀持串⼝和以太⽹接⼝。
本章将对各种Bootloader总结分类,分析它们的共同特点。
以U-Boot为例,详细讨论Bootloader的设计与实现。
6.1.2 Bootloader的启动Linux系统是通过Bootloader引导启动的。
⼀上电,就要执⾏Bootloader来初始化系统。
可以通过第4章的Linux启动过程框图回顾⼀下。
系统加电或复位后,所有CPU都会从某个地址开始执⾏,这是由处理器设计决定的。
⽐如,X86的复位向量在⾼地址端,ARM处理器在复位时从地址0x00000000取第⼀条指令。