什么是引导加载程序?

引导加载程序(Boot Loader)是计算机系统中的一个软件,它负责在计算机启动时加载操作系统内核,并将控制权交给内核。引导加载程序通常存储在启动设备的引导扇区(Boot Sector)中,如硬盘、固态硬盘、光盘等。它的主要功能包括初始化硬件、加载内核映像、设置内核运行环境等。

GRUB的一个重要特性就是灵活性;GRUB能够识别文件系统和内核可执行文件格式,因此你可以按照自己的喜好加载任意一个操作系统,而不必记录内核在磁盘上的物理位置。因此,你可以通过指定内核文件的名称以及内核所在的驱动器和分区来加载内核。

GRUD2

GRUB得到了扩展以满足许多需求,但很快它就变得明显,其设计无法跟上对其所做的扩展,我们达到了这样的地步:如果不破坏现有功能,就很难进行任何进一步的更改。大约在2002年,Yoshinori K. Okuji开始开发PUPA(GNU GRUB的初步通用编程架构),旨在重新编写GRUB的核心,使其更干净、更安全、更健壮、更强大。PUPA最终被重新命名为GRUB 2,而原始版本的GRUB被重新命名为GRUB Legacy。

multiboot2

Multiboot2 是一种标准化的引导加载协议,它定义了操作系统和引导加载程序之间的接口。这个协议允许引导加载程序,如 GRUB,与操作系统之间进行通信,传递必要的信息,以便操作系统能够正确加载和启动。

Multiboot2 规范的主要目标是简化操作系统的引导过程,使其更加标准化和统一。它包括以下几个关键部分:

  1. 操作系统映像格式:操作系统映像应该包含一个特殊的 Multiboot2 头,这个头包含了操作系统加载和启动所需的信息,如内存布局、引导加载器名称、命令行参数等。

  2. 引导加载程序传递给操作系统的信息格式:这些信息包括内存映射、启动设备、EFI 信息、帧缓冲信息等,它们以标签(tags)的形式组织,每个标签包含特定类型的数据。

  3. 引导加载程序与操作系统的交互:引导加载程序在启动操作系统时,会将 Multiboot2 信息结构的地址传递给操作系统,操作系统可以使用这些信息进行初始化。

  4. 启动模块:对于需要额外模块的操作系统,Multiboot2 规范提供了一种方法来告知操作系统这些模块的加载方式。

Multiboot2 规范的确切定义包括了操作系统映像格式、引导加载程序在启动操作系统时机器的状态,以及传递给操作系统的信息格式。这些定义使得操作系统开发者可以更容易地创建与多种引导加载程序兼容的操作系统映像。

Multiboot2 头通常位于操作系统映像的前 32768 字节内,并且必须是 4 字节对齐的。它包含了如 magic、architecture、header_length 和 checksum 等字段,以及一系列的标签(tags),这些标签描述了操作系统需要的额外信息。

总的来说,Multiboot2 是一个为自由操作系统社区设计的规范,旨在简化引导加载程序和操作系统之间的交互,使得操作系统的引导更加灵活和可靠。它被设计为与现有的操作系统和引导加载程序兼容,同时也支持新的技术和架构。

SBI

SBI(Supervisor Binary Interface)是 RISC-V 架构中的一个重要概念,它是定义在 Supervisor Mode 下的二进制接口标准。SBI 允许在 Supervisor Mode 或 Virtual Supervisor Mode 下运行的软件能够调用在 Machine Mode 下运行的固件(如操作系统的引导加载程序或 hypervisor)所提供的服务。这些服务可能包括时间管理、中断处理、内存管理等。

SBI 的主要作用是为 RISC-V 的 S 模式软件提供一个标准的接口,使其能够在不同的 RISC-V 平台上进行移植,而不必担心底层硬件的具体实现细节。SBI 定义了一系列的函数调用和错误码,以及如何使用这些调用的规范。

在 RISC-V 的上下文中,SBI 通常与以下概念相关联:

  • S-Mode(Supervisor Mode):这是 RISC-V 特权级别之一,用于操作系统内核的执行。
  • M-Mode(Machine Mode):这是 RISC-V 的最高特权级别,通常由固件或引导加载程序执行。
  • Hart:硬件线程的抽象,每个 Hart 都可以独立执行指令。

SBI 规范定义了如何从 S 模式发起调用(通过 ECALL 指令)到 M 模式,并由 M 模式下的固件处理这些调用。这些调用可以是同步的,也可以是异步的。

OpenSBI 是一个开源的 SBI 实现,它提供了 SBI 规范中定义的接口和服务。OpenSBI 可以在不同的 RISC-V 硬件平台上运行,为操作系统或其他运行在 S 模式的软件提供支持。

在 Linux 内核中,SBI 调用通常通过 ecall 指令发起,并将调用的参数和返回值通过寄存器传递。Linux 内核会根据不同的 SBI 版本(如 SBI 0.1 或 SBI 0.2)来调用不同的服务。

总的来说,SBI 是 RISC-V 架构中用于实现操作系统和硬件之间交互的关键接口,而 OpenSBI 是这个接口的一个具体实现。通过 SBI,操作系统可以在不同的 RISC-V 硬件上以统一的方式访问硬件服务。

RISC-V 模式

在 RISC-V 架构中,提到的三种模式是 Machine Mode、Supervisor Mode 和 User Mode。这些模式定义了不同的特权级别,控制了软件对硬件资源的访问权限。以下是对这三种模式的详细解释:

1. Machine Mode (M-Mode)

  • 最高特权级别:Machine Mode 是 RISC-V 架构中最高的特权级别,通常由操作系统内核或引导程序使用。
  • 硬件控制:在 Machine Mode 下,软件可以直接访问所有硬件资源和控制寄存器。
  • 启动和初始化:系统启动时,处理器首先进入 Machine Mode,用于初始化硬件和启动操作系统。
  • 关键操作:包括设置中断向量、配置内存保护、管理电源等。

2. Supervisor Mode (S-Mode)

  • 中等特权级别:Supervisor Mode 是中等特权级别,通常由操作系统内核使用。
  • 虚拟内存管理:在 Supervisor Mode 下,操作系统可以管理虚拟内存、调度进程和处理系统调用。
  • 受限硬件访问:相比 Machine Mode,Supervisor Mode 对硬件资源的访问受到限制,但仍然可以执行许多关键操作。
  • 系统调用:用户模式下的应用程序通过系统调用进入 Supervisor Mode,以请求操作系统服务。

3. User Mode (U-Mode)

  • 最低特权级别:User Mode 是最低的特权级别,通常由用户应用程序使用。
  • 受限操作:在 User Mode 下,软件只能执行受限的操作,不能直接访问硬件资源或关键系统寄存器。
  • 安全性:通过限制用户应用程序的权限,User Mode 提高了系统的安全性,防止恶意软件直接操作硬件。
  • 系统调用接口:用户应用程序通过系统调用接口请求操作系统提供的服务。

Virtual Supervisor Mode (VS-Mode)

  • 虚拟化支持:VS-Mode 是在虚拟化环境中使用的模式,允许虚拟机管理程序(hypervisor)运行多个操作系统实例。
  • 虚拟化特权级别:VS-Mode 提供了一个虚拟化的特权级别,使得每个虚拟机可以像在真实硬件上运行一样管理其资源。
  • 隔离性:通过虚拟化,多个操作系统实例可以在同一物理硬件上运行,而不会互相干扰。

关系和调用

  • Machine Mode 可以调用和管理 Supervisor ModeUser Mode
  • Supervisor Mode 可以调用 User Mode,并处理来自 User Mode 的系统调用。
  • Virtual Supervisor Mode 允许在虚拟化环境中运行多个 Supervisor Mode 实例。

示例

以下是一个简单的示例,展示了不同模式之间的关系:

1
2
3
4
5
1. 系统启动时,处理器进入 Machine Mode,初始化硬件和启动操作系统。
2. 操作系统内核在 Machine Mode 下完成初始化后,切换到 Supervisor Mode。
3. 在 Supervisor Mode 下,操作系统内核管理虚拟内存和调度用户进程。
4. 用户应用程序在 User Mode 下运行,通过系统调用请求操作系统服务。
5. 在虚拟化环境中,虚拟机管理程序在 Machine Mode 下运行多个操作系统实例,每个实例在 Virtual Supervisor Mode 下运行。

通过这些模式,RISC-V 架构实现了对硬件资源的有效管理和保护,提高了系统的安全性和稳定性。

启动流程

opensbi —> uboot —> DragonStub —> kernel

opensbi(sbi: Supervisor Binary Interface, 监管者二进制接口)

  • 一个开源的RISC-V SBI实现,用于在RISC-V平台上启动操作系统
  • 它运行在机器模式(Machine Mode),提供底层硬件抽象和平台无关的服务,如中断处理、时间同步、系统调用等。
  • OpenSBI 是启动过程的第一环,负责初始化硬件和设置执行环境,以便后续的引导加载程序可以运行

uboot

  • U-Boot 是一个开源的引导加载程序,用于初始化系统的硬件组件,并为操作系统的加载做准备。
  • 它通常在 OpenSBI 之后运行,因为此时硬件已经被 OpenSBI 初始化。
  • U-Boot 提供了设备树(Device Tree)的解析、内存测试、网络启动支持、文件系统访问等功能。
  • 在启动流程中,U-Boot 负责定位操作系统的映像文件(如 ELF 文件),并将其加载到内存中