BIOS的BDS阶段解析
1、概述
BDS全称:Boot Dev Select(启动设备选择)
主要功能是加载并连接驱动程序,管理并启动引导项。在引导操作系统之前会初始化设备(USB键盘鼠标,VGA设备等),然后通过Variable功能来控制启动顺序,根据启动策略加载对应的引导项,启动操作系统或应用程序。
BDS主要功能:
• 加载设备驱动程序
• 初始化控制台设备
• 创建引导启动项
• 启动操作系统或应用程序
如果加载启动项失败,系统将重新执行DXE dispatcher 以加载更多的驱动,然后重新尝试加载启动项。
BDS策略通过全局NVRAM变量配置。这些变量可以通过运行时服务的GetVariable()读取,通过SetVariable() 设置。例如,变量BootOrder定义了启动顺序,变量Boot###定义了各个启动项。
用户选中某个启动项(或系统进入默认的启动项)后,OS Loader 启动,系统进入TSL阶段。
2、如何进入BDS阶段
此模块为BDS阶段- BdsEntry生成主入口。 当DxeCore分派此模块时,gEfiBdsArchProtocolGuid将被安装 ,包含BdsEntry接口。 DxeCore完成DXE阶段后,gEfiBdsArchProtocolGuid->BdsEntry将被调用。
通过方法BdsEntry();
- • 构造函数 安装 gEfiBdsArchProtocolGuid Protocol
- • DxeMain.c
- 文件最上面对gBS,gST,gRT全局变量进行初始化
- DxeMain()
//函数结尾调用
gBds->Entry (gBds);
- • BdsDxe.inf
MODULE_TYPE = DXE_DRIVER
ENTRY_POINT = BdsInitialize
3、BdsEntry()
3.1 代码流程
- 设置厂商及版本号
- 校验Variable,如果异常则进行删除
- 获取进度条时间
- 设置默认语言
- 前平台初始化
- 初始化热键服务
- 处理驱动程序
- 连接所有控制台设备
- 后平台初始化
- 获取启动菜单
- 判断是否进入Setup
- 等待按键按下,如果按键按下则,启动对应引导项
- 判断BootNext,如果不为空,则启动对应引导项
- 根据启动顺序依次尝试启动
要想理解BDS的启动流程,主要理解两部分 Connect Controller和Boot
Manger
3.2 Connect Controller
3.2.1 驱动初始化过程
- 硬件相关初始化(大部分在PEI阶段或DXE阶段进行)
- 前平台初始化中添加Driver####并更新DriverOrder
- 根据DriverOrder获取Driver####存储的DriverOption
- 根据DriverOption中的DevicePath进行Connect
- 加载DriverOption中DevicePath对应的Image,并运行该Image
- Disconnect Controller All
- 连接控制台
- Connect Controller All
- 连接控制台
- 后平台相关初始化,如串口等设备进行连接
•gBS->ConnectController()
• 排序
• 连接
将驱动安装到指定的设备控制器
• gBS->DisconnectController
将驱动从指定的设备控制器上卸载
.驱动初始化源码分析
|--> BdsEntry()|--> PlatformBootManagerBeforeConsole() //前平台初始化|--> LoadOptions = EfiBootManagerGetLoadOptions() //获取所有的DeviceOption|--> ProcessLoadOptions(LoadOptions)|--> for EfiBootManagerProcessLoadOption(LoadOptions)|--> EfiBootManagerConnectDevicePath(LoadOption->FilePath) //Connect DevicePath|--> while|--> BmGetNextLoadOptionBuffer(LoadOption->FilePath) //Image|--> gBS->LoadImage()|--> gBS->StartImage()|--> EfiBootManagerDisconnectAll()|--> EfiBootManagerConnectAll()
|--> PlatformBootManagerAfterConsole()
3.2.2 优先级顺序
- Context Override
参数传入的Image Handle - Platform Driver Override
gEfiPlatformDriverOverrideProtocolGuid->GetDriver(ImageHandle) - Driver Family Override
支持gEfiDriverFamilyOverrideProtocolGuid - Bus Specific Driver Override
BusSpecificDriverOverride->GetDriver(ImageHandle) - Driver Binding
其他 - 根据版本号排序
优先级排序源码分析
|--> while |--> if BusSpecificDriverOverride->GetDriver()|--> AddSortedDriverBindingProtocol(TRUE) // 函数内部进行递归|--> for|--> CoreHandleProtocol(DriverBinding)|--> if DriverBinding->ImageHandle == DriverBindingHandle|--> AddSortedDriverBindingProtocol(FALSE)|--> for AddSortedDriverBindingProtocol() // 5 添加剩下所有的|--> for 根据Version对最后添加的进行排序
3.2.3 连接设备控制器
- 在Start或Stop函数中执行Controller相关的一些初始化
- 在ControllerHandle下去安装一些Protocol去实现或管理Controller某些特定功能或数据
- Start中通常不会执行硬件初始化的操作
- 硬件相关初始化动作,大部分都是在Pei Phase、Dxe 前期Non EFI Driver Model的Driver, 初始化Processor、Chipset或Platform,当然有些也通过Oprom 或file in an EFI System Partition来进行初始化。
连接设备控制器源码分析
|--> BdsEntry()|--> ProcessLoadOptions()|--> EfiBootManagerDisconnectAll()|--> EfiBootManagerConnectAll()|--> BmConnectAllDriversToAllControllers()|--> gBS->LocateHandleBuffer()|--> for gBS->ConnectController()|--> CoreConnectController()|--> CoreConnectSingleController()|--> 排序|--> for|--> if DriverBinding->Supported() // 返回 Success|--> DriverBinding->Start() // 一般用于安装 Protocol|--> if //判断是否有子控制器|--> CoreConnectController() //递归调用
3.3 Boot Manger
概要:
3.3.1 BootManager运行流程
- 获取BootNext Variable
- 初始化平台恢复引导项
- 添加UEFIShell等引导项
- 获取Setup引导选项
- 添加Hotkey并注册CallBack
- 初始化Hotkey服务
- 删除无效的引导项
- 如果默认进入Setup,则启动该引导项
- 等待按键按下
- 如果有按键按下则启动按键对应引导选项
- 如果BootNext引导项存在,则启动该引导项
- 根据BootOrder获取引导选项
- 按照BootOrder中的顺序依次尝试启动
- 如果平台恢复选项启动,最后尝试启动平台恢复对应的启动引导选项
3.3.2 启动项与Hotkey
BdsEntry()
- 获取引导项
- 添加Key####
- 获取所有的Key####
- 将Key####中内容加入mBmHotkeyList链表
- 为Key####创建Callback
- 等待按键按下
- 启动 mBmHotkeyBootOption
BmHotkeyCallback() - 获取当前按键对应引导项
- 引导项保存至 mBmHotkeyBootOption
|--> BdsEntry()|--> PlatformBootManagerBeforeConsole() //前平台初始化|--> PlatformRegisterOptionsAndKeys() |--> EfiBootManagerGetBootManagerMenu() //获取Setup启动项 |--> EfiBootManagerAddKeyOptionVariable() //添加key#### Variable|--> EfiBootManagerStartHotkeyService() |--> BmGetKeyOptions()|--> for BmProcessKeyOption()|--> BmGenerateKeyShiftState()|--> InsertTailList(mBmHotkeyList)|--> BmRegisterHotkeyNotify()|-->RegisterKeyNotify(BmHotkeyCallback) //注册callback|--> BdsWait()|--> while |--> PlatformBootManagerWaitCallback() //显示|--> BdsReadKeys() |--> EfiBootManagerHotkeyBoot() |--> EfiBootManagerBoot(&mBmHotkeyBootOption)|--> BmHotkeyCallback()|--> EfiBootManagerVariableToLoadOption(Hotkey->BootOption, &mBmHotkeyBootOption)
3.3.3 如何添加引导项
添加 UEFI Shell 启动选项
- 根据gUefiShellFileGuid获取设备节点信息
- 创建新DevicePath,指向该节点
- 添加至Boot#### Variable,需要DevicePath和描述符,返回对应的Number
- 根据Number设置 Key#### Variable
- 根据Key####中的Opation注册Callback函数
- Callback中根据Number获取的BootOption并记录在全局变量中
- 如果有按键按下则启动全局变量中的BootOption选项
添加 FileSystem 启动选项
- 获取所有的 BlockIo Protocol 对应的 Handle
- 依次获取 BlockIo Protocol
- 跳过逻辑分区
- 跳过 Fixed Block IO 和 可移动设备(USB,移动硬盘)
- 获取当前BlockHandle对应的设备路径类型
//ACPI boot type
#define BDS_EFI_ACPI_FLOPPY_BOOT 0x0201
//Message boot type
#define BDS_EFI_MESSAGE_ATAPI_BOOT 0x0301 // Type 03; Sub-Type 01
#define BDS_EFI_MESSAGE_SCSI_BOOT 0x0302 // Type 03; Sub-Type 02
#define BDS_EFI_MESSAGE_USB_DEVICE_BOOT 0x0305 // Type 03; Sub-Type 05
#define BDS_EFI_MESSAGE_SATA_BOOT 0x0312 // Type 03; Sub-Type 18
#define BDS_EFI_MESSAGE_MAC_BOOT 0x030b // Type 03; Sub-Type 11
#define BDS_EFI_MESSAGE_MISC_BOOT 0x03FF
//Media boot type
#define BDS_EFI_MEDIA_HD_BOOT 0x0401 // Type 04; Sub-Type 01
#define BDS_EFI_MEDIA_CDROM_BOOT 0x0402 // Type 04; Sub-Type 02
//BBS boot type
#define BDS_LEGACY_BBS_BOOT 0x0501 // Type 05; Sub-Type 01
#define BDS_EFI_UNSUPPORT 0xFFFF
- 初始化BootOption并加入BootOptions数组
- 获取所有的SimpleFileSystemProtocol对应的Handle
- 依次获取 SimpleFileSystemProtocol对应的IO设备
- 如果文件系统中可以搜索到.\EFI\BOOT\boot.efi 文件系统启动设备,加入BdsBootOptionList启动项
- 搜索包含PXE启动项的文件系统,加入到BdsBootOptionLis链表
- 核实是否有shell启动项,加入链表
添加 Network 启动选项
- 将连接地址全部转换为小写字母
- 判断是否是http或https的地址
- 初始化节点信息
- 创建device path, 指向该节点
- 根据链接地址更新节点信息
- 重新创建device path,指向该节点
- 根据device path等相关信息初始化 load option
- 将load option 加入 Boot#### Variable
3.3.4 如何启动引导项
引导流程
- 搜索该选项是否存在
- 设置BootCurrent
- gBS->LocateDevicePath(Handle)
- gBS->ConnectController(Handle)
- FileBuffer = BmGetNextLoadOptionBuffer(BootOption->FilePath) //获取引导文件
- gBS->LoadImage() //加载Image
- gBS->SetWatchdogTimer() //开启看门狗
- gBS->StartImage() //启动Image
- gBS->SetWatchdogTimer() //关闭看门狗
- gRT->SetVariable() //删除BootCurrent Variable
BIOS的BDS阶段解析相关推荐
- datax源码解析-JobContainer的初始化阶段解析
datax源码解析-JobContainer的初始化阶段解析 写在前面 此次源码分析的版本是3.0.因为插件是datax重要的组成部分,源码分析过程中会涉及到插件部分的源码,为了保持一致性,插件都已大 ...
- 【app运营】3阶段解析O2O产品的APP该如何运营推广?
o2o,现在依然是在风口上,传统企业也好,互联网企业也好,还有许多创业者都想在此分一杯羹,但是实际上好多都已经折戟.经常听到这家公司.那家公司创始人拿着一个idea加商业计划书就拿到天使轮投资了,自己 ...
- UEFI.源码分析.DXE阶段的执行
源码EDK2 : Tianocore UEFI源码分析系列第一篇,DXE阶段的初始化与执行流程 源码结构 MdeModulePkg/ Core/ Dxe/ Dispatcher/ DXE调度器 Dxe ...
- BIOS/UEFI基础——Protocol介绍
简要说明 Protocol是UEFI中的一个重要概念(事实上<UEFI SPEC>中有超过70%的内容都是在讲Protocol),下面简单说明下: 1. 首先,非常重要的一点,Protoc ...
- BIOS、UEFI、Boot Loader都是些什么
BIOS.UEFI.Boot Loader都是些什么 文章目录 BIOS.UEFI.Boot Loader都是些什么 什么是BIOS 基本的输入输出是什么 自检程序"检"了什么 系 ...
- BIOS/UEFI基础——FDF文件
综述 FDF的全称是Flash Description File. 它是构成BIOS二进制的描述符,即FDF文件描述了BIOS二进制的组成结构. 本文的目的就是介绍FDF文件内部的组成以及它们是如何完 ...
- BIOS追code之DXE phase
DXE Phase Overview DXE Core DXE Dispatcher EFI System Table DXE Driver - Non-Driver Model DXE Driver ...
- Bios工程师手边事—IGD VBIOS
现代社会,是计算机技术高速发展的时代.计算机的发展,总是以人们生活的方便为目的.早期的计算机要想看到计算机的计算结果,要根据打孔的卡片来计算输出结果.而现在想看计算机的输出,就方便多了,一台显示器,男 ...
- UEFI BIOS和 传统BIOS 启动模式对比
传统BIOS开机流程 从你按下主机机壳上的电源键,到进入作业系统的期间,储存於主机板上那颗EEPROM(电气可抹除暨可程式化唯读记忆体)裡的BIOS便会开始执行以下的工作: 1. 初始化: 当电脑打开 ...
最新文章
- 只要可能,就缓存数据和页输出
- 其他算法-两大随机采样方法简介
- 如何创建一张表mysql_如何创建一张规范的MySQL表
- 2008年浙江大学计算机及软件工程研究生机试真题
- xwpftablecell设置字体样式_HTML的文字样式
- oracle回滚段空间满了,Oracle回滚段表空间文件丢损怎样处理?
- stone 的 log4j配置详解
- frida需要Java基础吗_Android Hook工具之Frida 基础使用
- c# 通用类扩展方法 备注
- 机器学习基础(二十二)—— decision tree
- 华为鸿蒙系统英语报纸_“鸿蒙”系统的英文名叫这个!华为注册的这些《山海经》神兽都该怎么翻译?...
- System.IO.Directory.Delete 方法的使用
- 怎么用计算机里的坦克大战,FC经典90坦克大战电脑版
- 马悦凌:从初级护士到“民间奇医”[7]
- list之按照中文拼音首字母排序
- USRP X310使用的准备工作--Linux进行FPGA image烧录
- 本地html图片载入很慢,打开网页时图片加载很慢怎么办?网页图片打开慢的解决方法...
- nuke11安装教程 nuke11破解教程
- mysql如何收费,mysql收费吗
- 探索测试-大富翁KYM练习笔记