最近在专研UEFI,发现有段时间没发帖子了... 所以讲一下Windows初始化的过程。 环境:Windows 2004 x64 个人见解,有不对的可以私信我,QQ:1045551070 个人博客:http://blog.leanote.com/archives/only_the_brave
如上所述,我们主要将视线放到BDS、TSL、RT阶段。
BootMgr的入口函数:
软件调试第二版 深入解析windows操作系统第六版 UEFI原理与编程https://www.n4r1b.com/posts/
随着计算机的发展, 传统的BIOS引导已经过时, 关于UEFI引导的安全对抗已经展开。
从如下流程图我们可以看出UEFI中MBR和VBR不再存在, 而是UEFI自己负责加载bootmgr, 这也意味着更加安全和迅速。
随着计算机的发展, 传统的BIOS引导已经过时, 关于UEFI引导的安全对抗已经展开。
从如下流程图我们可以看出UEFI中MBR和VBR不再存在, 而是UEFI自己负责加载bootmgr, 这也意味着更加安全和迅速。
与传统的BIOS引导相反, UEFI规范覆盖了硬件初始化开始到操作系统启动前的每一个步骤, 该规范主要分七个步骤,如下:
1.
安全性阶段(SEC):初始化临时缓存区, 即将Cpu的Cache设置为no
-
eviction模式, 并将整理的参数传递给BFV中找出的PEI入口函数。(在SEC阶段执行的代码是从SPI闪存运行)
2.
Pre
-
EFI 初始化阶段(PEI):配置内存控制器,初始化芯片组,并处理S3恢复过程。在此阶段执行的代码在临时内存中运行,直到初始化内存控制器为止。随后从DXE IPL PPI的Entry服务中找到DXE Image的入口函数并调用。
3.
驱动执行环境阶段(DXE):初始化系统管理模式(SMM) 和 DXE服务(Protocol)以及BS和RT服务。初始化完毕后DXE通过 EFI_BDS_ARCH_PROTOCOL找到BDS并调用入口函数。
4.
引导设备选择阶段(BDS):通过枚举可能包含UEFI兼容引导程序的PCI总线上的外围设备,来发现可以从中引导OS的硬件设备(Os loader)。
5.
临时系统加载阶段(TSL):操作系统加载器(Os loader)执行的第一阶段, 这个阶段是为Os loader准备执行环境,直至启动服务调用ExitBootServices(),系统将进入RT阶段。
6.
运行时阶段(RT):此时系统的控制权已由UEFI内核转交给Os loader手中, 随着Os loader的运行,最终会进入内核入口KiSystemStartup函数,将控制权完全交给OS。
7.
AL阶段:在RT阶段系统遇到灾难性错误会来到这(不做详细描述)。
与传统的BIOS引导相反, UEFI规范覆盖了硬件初始化开始到操作系统启动前的每一个步骤, 该规范主要分七个步骤,如下:
1.
安全性阶段(SEC):初始化临时缓存区, 即将Cpu的Cache设置为no
-
eviction模式, 并将整理的参数传递给BFV中找出的PEI入口函数。(在SEC阶段执行的代码是从SPI闪存运行)
2.
Pre
-
EFI 初始化阶段(PEI):配置内存控制器,初始化芯片组,并处理S3恢复过程。在此阶段执行的代码在临时内存中运行,直到初始化内存控制器为止。随后从DXE IPL PPI的Entry服务中找到DXE Image的入口函数并调用。
3.
驱动执行环境阶段(DXE):初始化系统管理模式(SMM) 和 DXE服务(Protocol)以及BS和RT服务。初始化完毕后DXE通过 EFI_BDS_ARCH_PROTOCOL找到BDS并调用入口函数。
4.
引导设备选择阶段(BDS):通过枚举可能包含UEFI兼容引导程序的PCI总线上的外围设备,来发现可以从中引导OS的硬件设备(Os loader)。
5.
临时系统加载阶段(TSL):操作系统加载器(Os loader)执行的第一阶段, 这个阶段是为Os loader准备执行环境,直至启动服务调用ExitBootServices(),系统将进入RT阶段。
6.
运行时阶段(RT):此时系统的控制权已由UEFI内核转交给Os loader手中, 随着Os loader的运行,最终会进入内核入口KiSystemStartup函数,将控制权完全交给OS。
7.
AL阶段:在RT阶段系统遇到灾难性错误会来到这(不做详细描述)。
在BDS后,SPI储存的UEFI固件代码已完成工作, 随后UEFI固件启动管理器先查询NVRAM UEFI变量以找到ESP,并找到OS特定的启动管理器bootmgfw.efi调用它入口函数(DXE 驱动)。
在BDS后,SPI储存的UEFI固件代码已完成工作, 随后UEFI固件启动管理器先查询NVRAM UEFI变量以找到ESP,并找到OS特定的启动管理器bootmgfw.efi调用它入口函数(DXE 驱动)。
EFI_STATUS __fastcall EfiEntry(
EFI_HANDLE ImageHandle,
/
/
程序内存映像的句柄
EFI_SYSTEM_TABLE
*
SystemTable
/
/
系统表指针
)
{
int
unKnow;
__int64
*
BootParameters;
unsigned
int
Status;
BootParameters
=
EfiInitCreateInputParametersEx(
ImageHandle,
SystemTable,
unKnow);
/
/
将EfiEntry参数转换为bootmgfw所期望的应用程序参数格式
if
( BootParameters )
Status
=
BmMain(BootParameters);
/
/
调用Windows引导管理器入口点
else
Status
=
0xC000000D
;
/
/
STATUS_INVALID_PARAMETER
return
EfiGetEfiStatusCode(Status);
/
/
将NT状态代码转换为EFI代码
}
EFI_STATUS __fastcall EfiEntry(
EFI_HANDLE ImageHandle,
/
/
程序内存映像的句柄
EFI_SYSTEM_TABLE
*
SystemTable
/
/
系统表指针
)
{
int
unKnow;
__int64
*
BootParameters;
unsigned
int
Status;
BootParameters
=
EfiInitCreateInputParametersEx(
ImageHandle,
SystemTable,
unKnow);
/
/
将EfiEntry参数转换为bootmgfw所期望的应用程序参数格式
if
( BootParameters )
Status
=
BmMain(BootParameters);
/
/
调用Windows引导管理器入口点
else
Status
=
0xC000000D
;
/
/
STATUS_INVALID_PARAMETER
return
EfiGetEfiStatusCode(Status);
/
/
将NT状态代码转换为EFI代码
}
该函数首先会调用 EfiInitCreateInputParametersEx 函数, 该函数主要用于将EfiEntry参数转换为bootmgfw.efi所期望的参数格式。
随后调用Windows引导管理器入口点 BmMain 函数。
该函数首先会调用 EfiInitCreateInputParametersEx 函数, 该函数主要用于将EfiEntry参数转换为bootmgfw.efi所期望的参数格式。
随后调用Windows引导管理器入口点 BmMain 函数。
在该函数中调用了 BmFwInitializeBootDirectoryPath 用于初始化启动应用程序(BootDirectory)路径(\EFI\Microsoft\Boot)。
随后BootMgr会读取系统引导配置信(BCD), 如果有多个启动选项,其会调用 BmDisplayGetBootMenuStatus 显示启动菜单,如下图:
在该函数中调用了 BmFwInitializeBootDirectoryPath 用于初始化启动应用程序(BootDirectory)路径(\EFI\Microsoft\Boot)。
随后BootMgr会读取系统引导配置信(BCD), 如果有多个启动选项,其会调用 BmDisplayGetBootMenuStatus 显示启动菜单,如下图:
再然后其会调用 BmpLaunchBootEntry 函数, 启动应用程序(winload.efi)。
当然bootmgfw.efi做的不止这些还有启动策略验证代码完整性以及安全启动组件的初始化,这些就不细说了。
再然后其会调用 BmpLaunchBootEntry 函数, 启动应用程序(winload.efi)。
当然bootmgfw.efi做的不止这些还有启动策略验证代码完整性以及安全启动组件的初始化,这些就不细说了。
在Windows引导管理器(BootMgr)最后阶段, BmpLaunchBootEntry 函数会根据之前BCD的值选择正确的启动项, 如果启用了全卷加密(BitLocker), 则会先解密系统分区,然后才能将控制权转移到winload.efi。
其次会调用 BmTransferExecution 函数,检查启动选项并将执行流传递给BlImgStartBootApplication函数。
再然后 BlImgStartBootApplication 函数中会调用 ImgFwStartBootApplication 函数, 而最终调用 ImgArchStartBootApplication 函数。
在Windows引导管理器(BootMgr)最后阶段, BmpLaunchBootEntry 函数会根据之前BCD的值选择正确的启动项, 如果启用了全卷加密(BitLocker), 则会先解密系统分区,然后才能将控制权转移到winload.efi。
其次会调用 BmTransferExecution 函数,检查启动选项并将执行流传递给BlImgStartBootApplication函数。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课