BIOS/UEFI一定运行在多核CPU中 APIC ID 为0的Core上吗?

编者按 : 鉴于笔者水平有限,行文若有不当之处,还望诸位海涵并不吝指正。

目录

是为序

AP和BP

EFI_MP_SERVICES_PROTOCOL

结语

参考资料


是为序

书接上文 : CPU的Core和Uncore? P Core & E core ?-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_36914987/article/details/136042925?spm=1001.2014.3001.5501

笔者在前面讲到了 Intel Xeon 系列多核CPU的 Core 和 Uncore 架构。

那,这便引出了一个问题。什么问题呢?

这个问题便是:多核CPU里面的 Core 都是一模一样的吗?

可能大部分同学的回答会是:应该是一模一样,的,吧...

但,实则非也。

笔者认为:多核CPU里面的物理Core应该是一样的,但它们的身份或者担任的角色却不一样。

那,要不咱细说?

好,笔者今天就与大家一起唠唠多核CPU里面的Core们,看看这些小家伙们在功能上究竟有啥不一样的。

AP和BP

对于多核CPU来说,CPU里的每个Core都有唯一一个 Local APIC ID 来标识该物理Core。APIC(Advanced Programmable Interrupt Controller) ,即高级可编程中断控制器。当系统或外部设备产生中断时,便可以将中断信息传送给特定 Local APIC ID 的 Core 来处理。

UEFI 的实现 EDK II 中对一个逻辑CPU(也就是Core) 进行了如下抽象。对于 IA32 和 X64 处理器架构来说,ProcessorId 就是上面的 Local APIC ID,而且只有低8位有效,符合x84架构CPU的兼容性。

/// Structure that describes information about a logical CPU. 
typedef struct { 
/// The unique processor ID determined by system hardware. For IA32 and X64, 
/// the processor ID is the same as the Local APIC ID. Only the lower 8 bits 
/// are used, and higher bits are reserved. U
  INT64 ProcessorId; 
  
  //... 
} EFI_PROCESSOR_INFORMATION;

关于一些 Local APIC ID 的细节,诸位可以参考这篇文章:计算机中断体系一:历史和原理 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/26464793

关于 APIC ID,这里有几点需要注意下:

  1. 不能假设 APIC ID 0 存在。
  2. 不能假设 APIC ID 是连续编号的。

接下来,笔者以下图作为例子进行说明,CPU 0 (Socket 0) 是一个标准的多核CPU。其中,APIC ID 从0开始,依次连续编号,而 CPU 1 里则没有 APIC ID 0,而是从1开始编号,并且APIC ID 也并不连续。

那,除了中断处理相关,CPU Core 的 APIC ID 号还有其它什么用处吗?

有!

先说用处:BIOS/UEFI 可通过 APIC ID,从AP中选择一个Core(BSP),来执行BIOS/UEFI。

多核CPU里面的Core,可分为两类:

  • AP: Application Processor,应用处理器。
  • BP: BootStrap Processor,也叫做BSP,启动处理器,用来启动BIOS/UEFI。

还是上面的 EFI_PROCESSOR_INFORMATION, 其中的 StatusFlag 成员标识了该 Core 是 AP 还是 BP,以及该 Core 是开启状态,还是关闭状态。

/// Structure that describes information about a logical CPU. 
typedef struct { 
    UINT64 ProcessorId; 
    
   /// Flags indicating if the processor is BSP or AP, if the processor is enabled 
   /// or disabled, and if the processor is healthy. 
   /// BSP ENABLED HEALTH Description 
   /// === ======= ====== =================================================== 
   /// 0 0 0 Unhealthy Disabled AP. 
   /// 0 0 1 Healthy Disabled AP. 
   /// 0 1 0 Unhealthy Enabled AP. 
   /// 0 1 1 Healthy Enabled AP. 
   /// 1 0 0 Invalid. The BSP can never be in the disabled state. 
   /// 1 0 1 Invalid. The BSP can never be in the disabled state. 
   /// 1 1 0 Unhealthy Enabled BSP. 
   /// 1 1 1 Healthy Enabled BSP.
 
   UINT32 StatusFlag; 

   //... 
} EFI_PROCESSOR_INFORMATION;

下面给出一个基于 Intel Core Gen4 CPU 的系统概览图,方便读者理解AP和BSP的区别。

再者,BP在多CPU的情况下,又可分为两种:

  • NBSP : Node BSP,每个CPU里面的BP。
  • SBSP: System BSP,系统BSP是BIOS/UEFI从每个NBSP里面挑选出来的BP。

最终,BIOS/UEFI的大部分代码就是由这个SBSP来执行的。

根据前面 APIC ID 的两个特点和SBSP的挑选原则,可知SBSP的 APIC ID 并非一定为0 ,但大概率是0。

有同学要问了,上面的“大部分代码”是怎么回事?这里,笔者其实也了解不深,之所以这么写,主要是考虑到行文的准确性。

在这篇文章中:电脑启动时的BIOS程序,多核CPU是怎么决定将哪个核心分配给它的? - 知乎 (zhihu.com)icon-default.png?t=N7T8https://www.zhihu.com/question/638180886/answer/3354659013

老狼提到:多CPU的时候,它们(BSP)都会执行BIOS,再由BIOS来选择最终谁胜出。

对此,笔者是这样理解的,在BIOS/UEFI选择SBSP的时候,会让每个BSP执行一段BIOS/UEFI代码,然后根据执行结果来选出SBSP。所以才说,SBSP执行的是大部分的BIOS/UEFI代码。

那BIOS/UEFI挑选SBSP依据的原则又是什么呢?肯定有很多种,但笔者在这里只说一般情况。一般来说:

BIOS/UEFI选择 Socket 0 上 APIC ID 最小的那个Core,作为SBSP。

这里的Socket 0 指的是主板 (Mother Board, MB) 上的第一个CPU插槽(针对多CPU)。另外,当BIOS/UEFI检测到当前SBSP不能正常工作时,便会重新选择(SwitchBSP)一个BP,将其作为新的SBSP来运行BIOS/UEFI。

好,简单总结一下上面的内容:

  • 多核CPU里面的 Core 可分为 AP 和 BP 两类。
  • 在多核多CPU系统中,由BIOS/UEFI从多个BP中选择一个BP,作为SBSP,来执行后续的大部分BIOS/UEFI代码。
  • CPU里面,Core 的 APIC ID 并不保证一定从0开始,也不保证连续编号。
  • BIOS/UEFI可以切换其运行的SBSP。

下面笔者以一张图对上述内容进行总结。

很多人误以为 BIOS/UEFI一定是在CPU 0 的 APIC ID 0 上执行,笔者只能说在大部分情况下,确实如此,但并不总是这样,比如当某个CPU的 Core 0 被BIOS/UEFI检测到损坏或者不从0开始编号时,BIOS/UEFI 便不会在 APIC ID 0上执行。

到这里,其实笔者已经可以结束本文了。

但部分好奇心比较重,或者 "求甚解"的读者可能会提出一个让笔者措手不及的问题:既然你说UEFI可以废立SBSP,那具体是咋实现的?

哼哼,还好当初笔者也问了自己这样一个问题。

所以,这个问题可难不倒俺。

那,接下来笔者将与诸位,细细道来~

EFI_MP_SERVICES_PROTOCOL

针对多核处理器(Multiple Processor),UEFI提供了一个Protocol——EFI_MP_SERVICES_PROTOCOL

This Protocol provides many services for Multiple Processors. These services can be used for parallel execution in reduing UEFI boot time.

该Protocol提供了一系列函数。UEFI可以通过这些函数实现SBSP的选择、启动关闭AP、切换BSP、并行计算以减少UEFI启动时间等等。

非BIOS工程师的读者,可能对这里的Protocol有点懵。注意,这里的Protocol和计算机网络的Protocol不一样。这里笔者解释一下自己对UEFI Protocol的理解。UEFI中的Protocol其实类似于面向对象编程中的接口,都向外部使用者提供了一系列可供调用的函数接口,即API(Application Programmable Interface)。面向对象采用类来实现接口,而UEFI采用Protocol来实现接口。UEFI Protocol 的实现基于C语言,通过struct的函数指针实现。

具体来说,我们来看 EDK II 下面的 MdePkg\Include\Protocol\MpService.h。这个 MpService.h 中声明了一个结构体:_EFI_MP_SERVICES_PROTOCOL,具体实现如下:

// EFI_MP_SERVICES_PROTOCOL declaration 
struct _EFI_MP_SERVICES_PROTOCOL { 
    EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors; // 获取系统中包含Core的数量 
    EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo; // 获取特定Core的信息 
    EFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs; // 启动所有的AP 
    EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP; // 启动特定AP 
    EFI_MP_SERVICES_SWITCH_BSP SwitchBSP; // 切换BSP 
    EFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP; // 开启关闭AP 
    EFI_MP_SERVICES_WHOAMI WhoAmI;    // 查询当前UEFI运行Core的信息 };

相信读者已经注意到了,我们可以通过调用该Protocol中的成员——SwitchBSP, 来实现BSP的切换。SwitchBSP 是一个 EFI_MP_SERVICES_SWITCH_BSP 类型的函数指针。那,让我们来看看这个函数指针,其声明如下,共有三个参数。

// This service switches the requested AP to be the BSP from that point onward. // This service changes the BSP for all purposes. This call can only be performed // by the current BSP. 
typedef EFI_STATUS (EFIAPI *EFI_MP_SERVICES_SWITCH_BSP)( 
    IN EFI_MP_SERVICES_PROTOCOL *This, // 相当于类的 This 指针 
    IN UINTN ProcessorNumber, // 即将被指定成为BSP的AP 
    IN BOOLEAN EnableOldBSP // TRUE: 旧的BSP重新变成AP,并运行;FALSE: 关闭该Core 
);

UEFI 通过调用 SwitchBSP 函数,就可以切换 SBSP 啦。

各位同学,你们现在明白了吗?

结语

本文简单介绍了多核CPU的AP和BP,UEFI运行在哪个BP上,以及UEFI如何切换BP。其实,关于这方面的相关内容还有很多,本文只讲述了其中很小的一部分,其它的内容包括但不限于:

  • Core相关的知识,比如 Package、Die、Thread等。
  • UEFI基本是单线程执行的,也就是说在UEFI启动过程中,基本上是BP太忙,AP太闲。故而如何更好地实现AP的并行化执行,值得研究。
  • Local APIC ID 的相关内容。

好,本文的分享就到此次结束啦,各位同学,觉得本文还不错的话,记得点个赞哦~

【往期好文】

CISC&RISC? CPU架构有哪些? x86 & ARM?-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_36914987/article/details/136038004?spm=1001.2014.3001.5501

CPU的Core和Uncore? P Core & E core ?-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_36914987/article/details/136042925?spm=1001.2014.3001.5501

参考资料

  • 28
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
BIOS(Basic Input/Output System)和UEFI(Unified Extensible Firmware Interface)是计算机系统用于启动和初始化硬件设备的软件接口。HII(Human Interface Infrastructure)是UEFI的一个基本框架,它提供了一种标准化的方式来创建和管理图形用户界面(GUI)。下面是对BIOS/UEFI和HII的基本概述: 1. BIOSBIOS是一种早期的固件接口,在过去的计算机系统广泛使用。它负责在计算机启动时初始化硬件设备,并加载操作系统。BIOS通常使用基于文本的用户界面(TUI),通过键盘输入来进行配置和设置。 2. UEFIUEFIBIOS的后继者,它提供了更先进的系统启动和硬件初始化功能。UEFI支持更大的硬盘容量、更快的启动速度和更丰富的扩展性。与BIOS相比,UEFI使用图形用户界面(GUI)来提供更直观和易用的界面。 3. HII:HII是UEFI规范定义的一个基本框架,它提供了一套标准化的API和工具,用于创建、管理和显示UEFI图形用户界面。HII使得开发人员可以轻松地设计和定制UEFI界面,以满足用户的需求。HII还支持多语言和可扩展的用户界面,提供了更好的用户体验。 总而言之,BIOS/UEFI是计算机系统用于启动和初始化硬件设备的软件接口,而HII是UEFI的一个基本框架,用于创建和管理图形用户界面。它们共同为计算机提供了更快、更稳定和更易用的启动和配置功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rob月初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值