1-芯片启动过程

BIOS启动过程详细解析

1.修改BIOS各步骤的意义

①cpu.h

包含各芯片本身的信息。如core_cm0plus.h, core_cmFunc.h, core_cmInstr.h(KL36)

②mcu.h

为了重定向芯片中的中断信息相关宏常数及宏函数及复位相关函数。

重定向的意义在于

⑴提取共性,最小程度的减少移植其他芯片的代价

⑵为了顾名思义,最大程度提高代码的可读性

③链接文件

主要为了划分各部分功能(动态命令、构件链表、构件函数)所用的区域,实现各个功能的跳转工作。

④启动文件

启动文件的修改主要是将bss段的清零程序删除。删除这段是为了上电复位的时候不清除部分全局变量以达到触碰6次才返回BIOS的效果。

⑤user.h

主要为了重定向各模块的串口、模块号或者对应的原中断处理程序名。

⑥基础构建标准化

主要为了提取共性,实现多芯片的统一。

2.BIOS的启动过程

–> 初始化堆栈

–> 复位程序地址赋给PC寄存器

–> 取出PC寄存器中的地址并执行

–> 将Flash中的data段的数据复制到RAM

–> 调用系统初始化函数进行芯片部分初始化

–> 调用main函数进入BIOS主程序

–> 从BIOS中转向USER区域

mbed操作系统启动过程

(1)芯片上电复位后,芯片内部机制首先从 Flash 的起始地址中,取出第一个表项的内容(即 RAM 最大地址+1),赋给内核堆栈指针寄存器 SP,实际上是使用 MSP,完成堆栈指针初始化。

1
2
3
4
5
.section .FlashConfig, "a"
.long 0xFFFFFFFF
.long 0xFFFFFFFF
.long 0xFFFFFFFF
.long 0xFFFFFFFE

(2)芯片内部机制将第二个表项(即复位处理程序 Reset_Handler 的首地址),赋给内核寄存器 PC(程序计数器)。

(3)芯片内部机制从程序计数器 PC 中取出地址,再从该地址取出机器码,这个机器码就是芯片复位后执行的第一个指令,也就是说,芯片从此开始运行程序了。直观理解就是从“startup_xxx.S”文件中的 Reset_Handler 函数开始程序的运行。

1
2
3
4
5
6
Reset_Handler:
cpsid i
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
cpsie i

(4)将 data 段的数据(已赋值且不为 0 的全局变量和静态变量)从 Flash 中复制到 RAM 中。

1
2
3
4
5
6
7
8
9
10
11
12
13
ldr    r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__

subs r3, r2
ble .LC0

.LC1:
subs r3, 4
ldr r0, [r1,r3]
str r0, [r2,r3]
bgt .LC1
.LC0:

(5)清零未初始化 bss(Block Started by Symbol) 数据段(赋值为 0 或未初始化的全局变量和静态变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define __STARTUP_CLEAR_BSS
#ifdef __STARTUP_CLEAR_BSS
ldr r1, =__bss_start__
ldr r2, =__bss_end__

subs r2, r1
ble .LC3
movs r0, 0

.LC2:
str r0, [r1, r2]
subs r2, 4
bge .LC2

.LC3:
#endif

(6)调用系统初始化函数 SystemInit 进行芯片部分初始化设置(在本样例程序中,完 成系统时钟初始化,即将内核和总线时钟都设置为 48MHZ)。

(7)调用静态构造函数__libc_init_array 完成对 C ++对象的初始化。

(8)最后调用 main 函数进入用户主程序执行。

–> 初始化堆栈

–> 复位程序地址赋给PC寄存器

–> 取出PC寄存器中的地址并执行

–> 将Flash中的data段的数据复制到RAM

–> 清零并初始化BSS段

–> 调用系统初始化函数进行芯片部分初始化

–> (调用__libc_init_array完成对 C ++对象的初始化)

–> 调用main函数进入用户主程序

注意:

1.BIOS的操作中去除了清零并初始化BSS段的操作

2.(__libc_init_array)内为增加操作系统所需要加的操作