3

我是引导加载程序开发的新手。我尝试了一些基本的东西,比如打印字符串“Hello World”之类的东西。我想问一些类似的事情,

是否有可能使用 asm/c/c++/mixed 在引导加载程序上分别初始化多核芯片中的内核?(比如,我想单独初始化第一个核心或单独初始化第三个核心)。

如果可能,请分享代码。

4

1 回答 1

3

是否有可能使用 asm/c/c++/mixed 在引导加载程序上分别初始化多核芯片中的内核?

是的,这完全有可能。

如果可能,请分享代码。

仅仅因为它是可能的并不意味着代码存在;即使代码存在,也不意味着它小到可以粘贴到这里。

现实情况是,要正确地做到这一点(在 80x86 上),您需要:

  • 如果您处于实模式(例如 BIOS 的引导加载程序),请切换到保护模式和长模式
  • 解析表(ACPI 的 MADT/APIC 表,或英特尔的 MultiProcessor 规范表,如果没有 ACPI)来确定本地 APIC/s 在哪里,还有多少其他 CPU,这些 CPU 使用哪些 ID。请注意,仅查找这些表(在您可以解析它们之前)可能涉及搜索物理地址空间的区域以查找签名和检查校验和。
  • 建立某种可用于延迟和超时的时间源
  • 查找/分配一些适合 AP CPU 启动蹦床的内存(低于 0x00100000,从页面边界开始)。在某些情况下,这可能比您想象的要复杂(对于 UEFI,不能保证 0x00100000 以下的任何内存都是空闲的,您可能需要exitBootServices()在合适的内存空闲之前调用,并且您可能需要初始化自己的视频输出调用之前的代码,exitBootServices()以便您可以在不再依赖 UEFI 的控制台支持后显示错误消息等)。
  • 初始化 AP 启动蹦床,这通常涉及复制到您找到/分配的内存中,并且可能涉及在蹦床中设置各种值(例如 CPU 应用于堆栈的地址等)。当然,这也意味着在(16 位实模式)汇编中编写代码,并且通常涉及更多代码以切换到保护模式或长模式,因此如果/当 AP CPU 启动蹦床中的代码时,可以将 CPU 提升到它可以执行“正常”代码的状态。
  • 执行 AP CPU 启动序列(包括使用一个 CPU 上的本地 APIC 向另一个 CPU 发送特殊的中断序列,包括时间延迟和超时,以及错误处理)。

当然,所有这些工作量很大,而且大部分工作都是出于多种原因完成的。例如,您可能会找到 APCI(和/或多处理器规范)表并稍后将它们用于 100 种不同的事物,然后您可能会初始化 timer/s 并稍后将它们用于 100 种不同的事物,您可能会初始化物理内存管理器并使用它用于 100 种不同的事情等。这意味着执行这些事情的代码最终会在整个引导过程中传播(一些在引导加载程序中,一些在其他引导代码中,一些在内核中),而且它“几乎永远不会”全部合二为一方便的地方(比如“这是在这个文件中启动其他 CPU 的所有内容”)。

于 2019-06-04T03:41:16.467 回答