# BIOS 阶段划分
SEC
:Security
(安全) : 处理平台重
事件,创造一个临时的内存
区 (此时内存还未初始化
),在系统中作为一个可信的 root,传递信息到PEI
PEI
:pre-efi initialization
(预 EFI 初始化):初始化
一些永久的内存
HOBS (hand-off BLocks
) 中内存,以及在 HOBS 里面的FV
(firmware volume) 位置,传递控制权到DXE
阶段DXE
:driver execution environment
(驱动程序执行环境) :重点
关注,服务器上硬件驱动的执行环境
,与后期外设
的使用,有极大的关系BDS
:boot device select
(引导设备选择) 初始化console设备
;加载设备驱动;尝试加载和执行启动项
。RT
:run time service
(运行时服务) :此时与bootloader
关系紧密
AL
:after life
(transition from the os back to the environment
)of system
# 与 BMC
通信
# 基础了解
# 平台管理
- 平台管理 (
platform managemet)
: 平台管理表示一系列的监视
和控制
功能,操作的对象
是系统硬件
,比如监视系统的温度
,电压
,风扇
,电源
等,并做响应的
调节工作,以保证系统处于健康状态
。若系统不正常
,通过复位方式
重启
BMC
:Baseboard Management Controller)
: 把上面的功能集成到一个控制器
上,称为基板管理控制器
,BMC
是一个独立的系统,它不依赖系统上的其它硬件
(如CPU
,内存
),也不依赖于BIOS
,OS
等,但BMC
可以与BIOS
和OS
交互。BMC 本身也是一个带外处理器
(一般都是 ARM 处理器) 的小系统,单独用来处理某些工作,其中重点还是平台管理
BMC
通过不同的接口
与系统
中其它组件连接
,LPC
,I2C
,SMBUS
,Serial
等基本接口
IPMI
, 它是与BMC
匹配的接口
,所有BMC
都需要实现这种接口
# IPMI
IPMI
全称Intelligent Platform Management Interface
智能平台管理接口
,IPM
是对平台管理
概念的具体规范
,该规范定义了平台管理
的软硬件架构,交互指令
,事件格式
,数据记录
,能力集
等,而BMC
是IPMI
中的一个核心
部分,属于IPMI
硬件架构。
# BIOS 通信
BIOS
与BMC
之间的通信,主要使用IPMI
。共有两个
阶段PEI
和DXE
(包括DXE
后面的),用的是不同的IPMI
函数 (重点注意
)虽然后使用
IPMI
,但使用两个
通道分别是KCS
,BT
,一般使用KCS
通道。
BMC不会
主动与 BIOS 通信,BIOS 会发送IPMI命
令给BMC
,BMC
如果成功接收
的话,就会有个返回信息
给BIOS
。
# 如果 BMC
与 BIOS
产生了通信故障
- 确认
BIOS
是否发送了IPMI命令
给BMC
, 可以查看BMC
返回的completion code
; - 确认
BMC
是否收到了BIOS
发送的IPMI命令
- 如果
BIOS
发送了IPMI命令
,但是BMC未接收
:可能是BMC
的IPMI进程
正处于忙碌状态
,所以丢掉
了这条IPMI命
令 (BIOS 如果发送失败,可以尝试多次
发送;另外可以稍微调高KCS通道
的延时
);当然,也有可能是 BMC 的IPMI进程
挂了 - (极少见)
一条IPMI
命令通常设计2个底层
实现函数,SendDataToBmcPort()
和ReceiveBmcDataFormPort()
。接收时,BIOS 从KCS
的I/O端口
读取数据
,读完后,会检测KCS寄存器
中OBF状态寄存器
,如果BMC没有写
数据,就会计数-1
,延时5ms
,然后重试,当BMC
一直不写数据时,计数到0
, 就认为BMC有故障
,返回Device Error
;
# ACPI
Advanced Configuration and Power Interface
简称ACPI
,高级配置
与电源接口
,提供操作系统应用程序管理所有电源管理接口。对于 BIOS 而言,
ACPI
最直观的就是电源功耗
,从而影响CPU性能
,
# OS Loader
操作系统加载器:
引导
加载程序
OS loader
可以通过BS(Boot Services)
和RT
使用UEFI
提供的服务,并且将计算机的资源
转移到自己手
中,此过程称为TSL(Transient System Loader)
。在此阶段结束之后,OS Loader
会调用ExitBootServices()函数
,结束BS
并且回收BS占用的资
源,然后BIOS
会进入RT阶段
,然后OS loader
会加载操作系统内核
,逐渐进入 OS,此过程称为TSL
(Transient System Load
)在
BDS
阶段,BIOS
会选择可启动项
,按照设置的顺序
,逐一
尝试,经过校验之后
,加载OS Loader
BIOS
(BDS
阶段)---->OS Loader
---->OS
引导区位于
FAT32
格式分区。一般 FAT32 位于磁盘的最开始,大小 1MB 左右。
UEFI 会把
FAT32的格式
都当做启动磁盘都添加到启动菜单
中在启动盘
UEFI/Boot/BootX64.efi
中加载
# 硬盘启动盘文件也都位于此
EFI/Boot/BootX64.efi# 32 位系统无需 + X64
# UEFI
UEFI
(Unified Extensible Firmware Interface
, 统一可扩展固件接口) 提供给操作系统
的接口包括启动服务
(Boot Service
,BS
) 和运行时
服务 (Runtime Service
,RT
) 以及隐藏
在BS之后
的丰富的Protocol
(协议),BS
和RT
以表
的形式 (C 语言中的结构体
) 存在。UEFI 的实现分为两部分
平台初始化
固件
- 操作系统接口
# 组成
OS Loader
可以通过BS
和RT
使用UEFI
提供的服务,将计算机资源逐渐转移到自己手中,这个过程为TSL
(Transient System Load)
当
OS Loader
完全掌握
了计算机资源时,BS
也就完成
了它的使命
。OS Loader
调用ExitBootServices()
结束BS
并回收BS
占用的资源,之后计算机系统进入UEFI Runtime
阶段
# BS 提供的服务 (TSL 阶段)
UEFI
提供给操作系统的接口
,包括启动服务
(Boot Services
,BS
)
事件
服务:事件时异步
操作的基础,有了事件
的支持,才能够在UEFI系统内
执行并发操作
内存
管理:提供内存的分配与释放,管理系统内存映射Protocol
管理:提供了安装与卸载
Protocol 的服务,注册通知函数的服务Protocol使用类
服务:Protocol
的打开与关闭,查找支持Protocol控制
,例打开设备上PciloProtocol
, 用PciIo->Io.Read()
服务读取设备上的寄存器
驱动管理
:包括用于将驱动安装到控制器的connect服务
,以及将驱动从控制器上卸载的disconnect服务
。若启动时,需要网络服务,通过 loadImage 将驱动加载到内存,通过connect
服务将驱动安装到设备Image管理
:加载,卸载,启动和退出 UEFI 应用程序或驱动ExitBootServices
:用于结束启动服务
# RT 提供的服务
UEFI 提供给操作系统的
运行时
服务
时间
服务:读取 / 设定系统时间,- 读取
UEFI系统变量
:读取 / 设置系统变量,例如BootOrder
用于指定启动项顺序
,通过系统变量保存系统配置 虚拟内存
服务: 将物理地址
转换为虚拟地址
- 其它服务:包含
重启系统的ResetSystem
, 获取系统提供的下一个单调单增值
。
# UEFI 启动过程
# SEC 阶段
Security Phase
, 当 CPU 收到ResetVector
信号后,开始执行第一行
代码, 平台初始化的第一个阶段,安全阶段,最早
运行的固件代码,此模块相当部分
使用汇编
语言开发。电脑的开机或者重启,
本质
上是给 CPU 发送了一个ResetVector
信号。由于
没有初始化内
存,会临时使用CPU
的缓存,内嵌在 CPU 中,初始化好的,SEC 作为整个系统执行的起点,可能遇到各种异常,就需要设置
IDT
,有了中断描述符表接受异常,就能让系统遭遇意外情况时,不至于崩溃,为 PEI 阶段设置临时内存的基地址和长度
并传给 PEI,同时将 PEI 代码的入口点,将控制权移交过去,并且处理临时内存。
# 位于 EDK2 如下目录
UefiCpuPkg/ResetVector/Vtf0
# SEC 阶段任务
- 接受并处理系统
启动
和重启
信号,以及运行过程中的严重异常
信号初始
化临时存储区域
,启动系统需要的一些临时RAM
,空间资源仍然稀缺
- 作为
可信系统
根传递给下一个阶段PEI
# Reset Vector
- 进入
固件入口
- …..
# PEI 阶段
PEI :
Pre-EFI Initialization
资源
十分有限
,PEI后期
进行内存初始化
- 为
DXE
准备执行环境,将需要传递的信息组成HOB
列表,将控制权移交到DXE
手中
PEI Foundation
: 负责接受SEC
发送的交换数据,并扮演模块分发
的角色PEIMs-EFI Initlization Modules
是模块化的,PEI
阶段的 4 档事情就是交给PEIMs
完成,完成后就来到了DXE阶段
。
对
系统的初始化
,找出系统中所有的PEIM
,并根据PEIM
之间的依赖关系按照顺序执行PEIM
,
# PEI 入口函数
- 系统当前的状态,判断
系统健康状况
- 可启用
固件的地址
和大小
- 临时
RAM区域
的地址
和大小
栈
的地址
和大小
# PEI 执行流程
在
PEI
阶段,PEIM
,PPI
,HOM
组成了 PEI 阶段,PEI 阶段的module
可理解为Driver
就是PEIM
,PEI阶段
就是由一个一个的 PEIM 组成的;PPI
是PEIM
之间相互调用的接口,由唯一的GUID
(全局统一标识符
) 引导,内部也包含一些接口
,HOB 相当于信件在 PEI 阶段创建,会记录当前系统的信息,可以自定义HOB
,然后在DXE阶段读出
PEIM
:PEI Module
,会被编译成efi binary
在一套的
BIOS code
编译完之后,进入到build目录
就可以找到PEIM
具体的efi
PPIs
:PEIM-to-PEIM Interfaces
,PEIMs 被调用通过PPI
,Interface
。调用函数必须通过 PPI 接口
- PPI 名称:
GUID
(128-bits)PPIs
结构体,PPI 就是一个结构体,可能包含的功能,数据。- PEIM 会把 PPI 注册到
PEI Foundation
。 (PEI Foundation
管理着庞大的PPI
数据库)
Core Services
包含后面 phase 用到的各种 Services。在 PEI 阶段 get 当前计算机启动的 boot Mode 有直接定义的 PEI Service 函数,在 DXE 以及后面的阶段要通过 HOB 方式通过get HOB LIS
T 然后拆解信息进行ge
启动boot Mode
Core Dispatcher
负责派发个PEIMs
, 将PEIM
按照既定的顺序Load
并执行,Dependency
顺序,就是inf
文件里面的depx
, 满足条件可执行- 各
PEIM Entry
可能使用其它PEIM
和PPI
PEI Core
最后会找到DXE
获得之前phase Data
是从 HOB 里拿到,PEI Core 会创建 HOB,PEI 和 DXE 都可以使用HOB的Data
函数:
InstallPPI
安装 PPI 到PEI foundation
,Protocol install
安装完毕后放到Handle Database
里LocatePPI()
:根据 PPI 名称GUID
从PEI foundation
找Interface
NotifyPPI()
: PPI 里的function
不会在派发时就执行,通知系统此 PPI 会在某个 PPI 被安装时才执行
# Install PPI
/** | |
Install PPI services. It is implementation of EFI_PEI_SERVICE.InstallPpi. | |
这是个 service,PEI foundation 提供的。 通过 GUID 安装。目的是让别人调用。 | |
@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. | |
标准格式,入口第一人参数是铁定的 EFI_PEI_SERVICES 指针 | |
@param PpiList Pointer to PPI array that want to be installed. | |
第二个参数是 PPI List, LIST 里包括 Flag、GUID 和函数 参考.h 里的 EFI_PEI_PPI_DESCRIPTOR 定义 | |
@retval EFI_SUCCESS if all PPIs in PpiList are successfully installed. | |
@retval EFI_INVALID_PARAMETER if PpiList is NULL pointer | |
if any PPI in PpiList is not valid | |
@retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI | |
**/ | |
EFI_STATUS | |
EFIAPI | |
PeiInstallPpi ( | |
IN CONST EFI_PEI_SERVICES **PeiServices, | |
IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList | |
); |
# HOB
HOB(
Hand-Off Blocks
):传输信息的载体,PEI
和DXE
联系薄弱,DXE
需要知到PEI初始化
的硬件内存等数据,HOB
作为桥梁
。
HOB
实际就是一个链表
,当我们找到 hoblist 的头,那么整个链表的数据都能得到,GetHobList()
获取hoblist
的指针
,
- 第
一个HOB
总是PHIT==Phase Handoff GetHobList(),
里面是boot mode
- 其它
HOB
可能出现在List任意位置
,最重要的是System Memory HOB & Firmware Volumes
,HOB
列表总是会以END_OF_HOB_LIST
结束
# 添加新的 HOB
/** | |
Add a new HOB to the HOB List. | |
@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. | |
@param Type Type of the new HOB. | |
@param Length Length of the new HOB to allocate. | |
@param Hob Pointer to the new HOB. | |
@return EFI_SUCCESS Success to create HOB. | |
@retval EFI_INVALID_PARAMETER if Hob is NULL | |
@retval EFI_NOT_AVAILABLE_YET if HobList is still not available. | |
@retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
PeiCreateHob ( | |
IN CONST EFI_PEI_SERVICES **PeiServices, | |
IN UINT16 Type, // 对于自定义的 HOB 一般使用 EFI_HOB_GUID_TYPE | |
IN UINT16 Length, | |
IN OUT VOID **Hob | |
); |
# DXE 阶段
Driver Execution Environment
驱动执行环境,主要任务是把基本驱动程序加载起来,建立两者之间的联系。执行
大部分系统初始化
的工作,此阶段内存已经完全
被初始化
,
DXE内核
:复杂 DEX 基础服务和执行流程DXE派遣器
:负责调度执行EXE驱动
,初始化系统设备
typedef EFI_STATUS(EFIAPI *EFI_IMAGE_ENTRY_POINT) | |
( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) |
驱动
之间通过Protocol
进行通信。
Protocol
特殊结构体保存着对应的GUID
,利用系统BootServices
的OpenProtocol
,并根据GUID
打开对应的Protocol
,进而使用对应的服务
。当所有的driver
执行完毕
,系统完成初始化
,
# DXE Core
DxeMain()
是 DXE 阶段执行的主函数
,同时以参数形式
接受 PEI 阶段的HOB表
- 创建
EFI System Table
在随后的DXE Drive
r 中逐步完善 table- 生成
Boot Services / Run Time Services / DXE Services
- 调用
Dispatcher
,所有的DXE Driver
在这个函数中被检测
并执行
Driver
执行完毕之后,执行特殊的DXE Driver
进而进入 BDS 阶段
# DXE Dispatcher
- 去
BIOS
芯片中搜寻DXE Driver
- 检测并按照相应的顺序执行所有的
DXE Driver
, 在每个driver
的inf
文件的driver
依赖条件都成立时,该 driver 才被执行
# BDS 阶段
全程:
Boot Device Select
U 盘就是寻找具有
FAT32分区
的设备执行启动策略 BDS 三大任务:
console初始化
,Driver初始化
,BootDeviceSelect
:用户选择BDS加载
启动选项里的OS loader
,最后移交真正的控制权
给OS loader
,由 OS Loader 将
- 初始化控制台设备:查看系统有
多少
加载必要的设备驱动:启动所有检测到的设备,加载driver
- 根据系统设置加载和执行启动项 (若加载失败,系统将重新执行
DXE dispatcher
以加载更多的驱动
,然后重新尝试加载启动项
)
# BDS Steps
- 初始化
语言
和字符串
数据库 - 获得
当前启动模式
- 基于
启动模式
建立设备清单
- 连接
设备
- 检测
input output
设备 - 执行
内存测试
- 进程
引导选项
# TSL 阶段
Transient System Load
: 操作系统OS Loader
执行的第一阶段
,首先作为UEFI
程序运行,之后 TSL 退出,系统进入Run Time
阶段。OS loader 的主战场,TSL 是正式操作系统加载前的预备阶段,需要 Loader 找到并加载 OS
# RT 阶段
Run Time
: 系统控制权从UEFI
内核转交到OS Loader
手中,UEFI 资源回收到 OS Loader。在 OS Loader 中 OS 获取系统控制权。
# AL 阶段
After Life
如果系统 / 软件遇到灾难性错误,系统固件需要提供错误处理和灾难性恢复机制,此机制运行在AL
(After Life) 阶段。由
常驻UEFI
驱动组成,计算机关机
休眠睡眠
重启过程中的系统信息都会在这一阶段保存
。
# 源码部分基础
# 源码类型定义
typedef unsigned __int64 UINT64; | |
typedef __int64 INT64; | |
typedef unsigned __int32 UINT32; | |
typedef __int32 INT32; | |
typedef unsigned short UINT16; | |
typedef unsigned short CHAR16; | |
typedef short INT16; | |
typedef unsigned char BOOLEAN; | |
typedef unsigned char UINT8; | |
typedef char CHAR8; | |
typedef signed char INT8; |
# 一些硬件补充
# Hardware Monitor
读出所有计算进访问
传感器
的测试值
- 不同地点的
temperature
读数CPU and system temperature
智能风扇
控制:风扇转速侦测和风扇控制输出电压监控
# 分时复用
是采用
一物理链接
的不同时段来传输不同的信号
,能达到多路复用
的目的。通过事件上交叉
发送每一路信号的一部分来实现一条电路传送多路信号。将整个传输时间分割为
互不重叠
的时间间隔,又称为时隙
- 同步分时复用(
STDM
,Synchronous Time Division Multiplexing
):采用固定间隙
分配方式,即将传输信号按特定长度连续地划分特定
的时间段或者一个周期
- 异步分时复用(ATDM,
Asynchronous Time Division Multiplexing
):根据用户市级需要动态分配资源的分时复用记数。
# PCI
- 局部总线:局部总线是在
ISA
和CPU总线
之间添加一级总
线或管理层
。这样可将一些高速外设如图形卡
,硬件控制器等从 ISA 总线上卸下而通过局部总线直接挂接在 CPU 总线上,使之余高速能与 CPU 总线相匹配。- PCI (Peripheral Component Interconnect) :
Intel 1991
年推出的用于定义局部总线
的标准。PCI
不同于 ISA 总线,PCI 数据地址总线于数据总线是分时复用。以方便可以节省接插件的管脚数,另一方便便于实现数据传输。
# USB
USB总线
提供中低速率
外围设备的扩充能力,像键盘,鼠标,遥感,喇叭,麦克风等设备,只要是 USB 接口设计,就可以以热拔插
(Hot Plug
) 的方式,直接跟计算机连接或拆除 (离线),计算机与OS会自动检测
并启用 / 禁用该设备,达到真正的即插即用。新近的
BIOS
直接提供了USB设备驱动
与读写
功能,比如开始就可以使用USB键盘
,鼠标
以及USB软盘
,硬盘甚至USB CD-ROM
来开机。
# ACPI
高级配置和电源管理接口:
Advance Configuration and Power Management Interface
. 早先 ACPI 将电源管理几乎全部分配给了BIOS控制
,限制了操作系统
在控制电脑。系统可能进入极地功耗
消耗状态,这些就是可利用多数桌面型电脑上睡眠和休眠设置节电方式:
- 显示屏
自动断电
- 系统把当前信息存储在
内存
中,只有内存等几个关键部件通电,即挂起到内存挂起到硬盘
,计算机自动关机
,关机千将当前数据存储在硬盘上。
# 中断向量表
中断向量表
在内存
中保存,其中放着256个中断源
所对应的中断处理程序入口
# 英语
Keyboard Power On
: 键盘开机Wake on LAN
: 网卡遥控开机- 调制解调器 / 传真机来电开机(
Modem Ring On
) - CPU 过热防护:
CPU Overheat Protection
- 超频功能:
Overclocking
# 参考资料
- 什么是 BMC
- gxh1992 博客
- 《UEFI 原理与编程》
- PEI 阶段扩展
- DXE
- 图表化呈现