一 . 导言:
关于 PC 机,其开机后的初始化处理器装备、硬件初始化等操作是由 BIOS ( Basic Input /Output System )完结的,但关于嵌入式体系来说,出于经济性、价格方面的考虑一般不装备 BIOS ,因而咱们有必要自行编写完结这些作业的程序,这便是所需求的开机程序。而在嵌入式体系中,一般并没有像 BIOS 那样的固件程序,发动时用于完结初始化操作的这段代码被称为 Bootloader 程序,因而整个体系的加载发动使命就完全由 Bootloader 来完结。简略地说,经过这段程序,能够初始化硬件设备、树立内存空间的映射图(有的 CPU 没有内存映射功用如 S3C44B0 ),从而将体系的软硬件环境设定在一个适宜的状况,以便为终究调用操作体系内核、运转用户运用程序预备好正确的环境。 Bootloader 依赖于实践的硬件和运用环境,因而要为嵌入式体系树立一个通用、规范的 Bootloader 是十分困难的。 Bootloader 也依赖于具体的嵌入式板级设备的装备,这也便是说,关于两块不同的嵌入式主板而言,即便它们是依据同一 CPU 而构建,要想让运转在一块板子上的 Bootloader 程序也能运转在另一块板子上,一般都需求修正 Bootloader 的源程序。
二 . 发动流程
体系加电复位后,简直一切的 CPU 都从由复位地址上取指令。比方,依据 ARM7TDMI内核的CPU 在复位时一般都从地址 0x00000000 处取它的第一条指令。而以微处理器为中心的嵌入式体系一般都有某种类型的固态存储设备(比方 EEPROM 、 FLASH 等)被映射到这个预先设置好的地址上。因而在体系加电复位后,处理器将首要履行存放在复位地址处的程序。经过集成开发环境能够将 Bootloader 定位在复位地址开端的存储空间内,因而 Bootloader 是体系加电后、操作体系内核或用户运用程序运转之前,首要有必要运转的一段程序代码。关于嵌入式体系来说,有的运用操作体系,也有的不运用操作体系,比方功用简略仅包含运用程序的体系,但在体系发动时都有必要履行Bootloader ,为体系运转预备好软硬件运转环境。
体系的发动一般有两种方法,一种是能够直接从Flash发动,另一种是能够将紧缩的内存映像文件从 Flash (为节约Flash 资源、进步速度)中仿制、解压到RAM ,再从RAM 发动。当电源翻开时,一般的体系会去履行ROM(运用较多的是Flash)里边的发动代码。这些代码是用汇编言语编写的,其首要效果在于初始化CPU 和板上的必备硬件如内存、中止操控器等。有时候用户还有必要依据自己板子的硬件资源状况做恰当的调整与修正。
体系发动代码完结根本软硬件环境初始化后,关于有操作体系的状况下,发动操作体系、发动内存办理、使命调度、加载驱动程序等,最终履行运用程序或等候用户指令;关于没有操作体系的体系直接履行运用程序或等候用户指令。
发动代码是用来初始化电路以及用来为高档言语写的软件做好运转前预备的一小段汇编言语,在商业实时操作体系中,发动代码部分一般被称为板级支撑包,英文缩写为 BSP 。它的首要功用便是:电路初始化和为高档言语编写的软件运转做预备。体系发动流程如图 1 所示,首要的进程如下:
1. 发动代码的第一步是设置中止和反常向量。
2. 完结体系发动一切必要的最小装备,某些处理器芯片包含一个或几个大局寄存器,这些寄存器有必要在体系发动的开端进行装备。
3. 设置看门狗,用户规划的部分外围电路假如有必要在体系发动时初始化,就能够放在这一步。
4. 装备体系所运用的存储器,包含 Flash , SRAM 和 DRAM 等,并为他们分配地址空间。假如体系运用了 DRAM 或其它外设,就需求设置相关的寄存器,以确认其改写频率,数据总线宽度等信息,初始化存储器体系。有些芯片可经过寄存器编程初始化存储器体系,而关于较杂乱体系一般集成有 MMU 来办理内存空间。
5. 为处理器的每个作业形式设置栈指针, ARM 处理器有多种作业形式,每种作业形式都需求设置独自的栈空间。
6. 变量初始化,这儿的变量指的是在软件中界说的现已赋好初值的大局变量,发动进程中需求将这部分变量从只读区域,也便是 Flash 拷贝到读写区域中,由于这部分变量的值在软件运转时有或许从头赋值。还有一种变量不需求处理,便是现已赋好初值的静态大局变量,这部分变量在软件运转进程中不会改动,因而能够直接固化在只读的 Flash 或 EEPROM 中。
7. 数据区预备,关于软件中一切未赋初值的大局变量,发动进程中需求将这部分变量所在区域悉数清零。
8. 最终一步是调用高档言语进口函数,比方 main 函数等。
三 . 程序剖析
下面依据实践经过测验的代码具体叙述体系的发动进程。
.text /* 将此操作符开端的代码编译到代码段或代码段子段中 */
/* 集成开发环境( IDE )能够经过链接脚本文件将下面的句子定位在零开端地址,体系上电后 CPU 从此处开端履行 */
ENTRY:
b ResetHandler /* 跳至 ResetHandler ,此句被定位在零开端地址 */
/* 除用户形式外的其他 6 种形式称为特权形式。特权操作形式首要处理反常和监控调用(有时称为软件中止),它们能够自在的拜访体系资源和改动形式。特权形式中除体系形式以外的 5 种形式又称为反常形式,下面的代码用于出现反常时 CPU 就会依据以下的句子主动跳转到对应的反常处理程序处 */
b HandlerUndef /* handlerUndef */
b HandlerSWI /* SWI interrupt handler */
b HandlerPabort /* handlerPAbort */
b HandlerDabort /* handlerDAbort */
b . /* handlerReserved */
b HandlerIRQ
b HandlerFIQ
…
…
ResetHandler: /* 上电后跳转到此处开端履行 */
Ldr r0,=WTCON /* 制止看门狗 */
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK /* 屏蔽一切中止请求 */
ldr r1,=0x07ffffff
str r1,[r0]
/* 设置时钟操控寄存器 */
ldr r0,=LOCKTIME