diff --git a/articles/20220319-riscv-uefi.md b/articles/20220319-riscv-uefi.md new file mode 100644 index 0000000000000000000000000000000000000000..95e980ef876274fc820e59d7bb3b807619a9be60 --- /dev/null +++ b/articles/20220319-riscv-uefi.md @@ -0,0 +1,103 @@ +> Author: Jacob Wang +> Wechat: BAME001 +> Date: 2022/03/19 +> Project: https://gitee.com/tinylab/riscv-linux +> +> Note:UEFI 的学习持续中,期望和更多爱好者沟通交流学习 + +# RISC-V 相关 UEFI Patch +通过查询 UEFI 关键字,UEFI 相关 patch 有一个 +``` +RISC-V: Add page table dump support for uefi +``` +相关代码链接是 +`https://patchwork.kernel.org/project/linux-riscv/patch/20200917223716.2300238-8-atish.patra@wdc.com/` + +该 patch 实现了将 UEFI 运行时服务的相关页表可以通过 `/sys/kernel/debug/efi_page_tables` 的方式透出。 + +`/sys/kernel/debug` 是内核调试的一种方法 ,调试内核的方法很多,debugfs 就是其中一种利用虚拟文件系统来调试内核的方法之一, +debugfs 与 profs ,sysfs 类似, 是一种虚拟文件系统。proc 仅用于提供有关进程的信息,sysfs 具有严格的每个文件一个值的规则,而 debugfs 则完全没有规则。 +开发人员可以将他们想要的任何信息放在那里。本文档的主要目的是讲解 UEFI 的相关知识,在这里就不会对页表相关概念做更多展开。 + +关于 UEFI ,接下来会从 UEFI 的概述,UEFI 基本引导流程,UEFI 基于 EDK2 的调试举例三个方面进行展开。 + +# UEFI概述 + +大概 20 多年的发展和积累中,UEFI 的代码量已经很庞大,相关标准白皮书也有很多 + +1999 年:EFI 1.0 推出 +2000 年:EFI 1.02 发布 +2002 年:EFI 1.10 发布 +2006 年:UEFI 2.0 发布 +2007 年:UEFI 2.1 +2008 年:UEFI 2.2 + +对 UEFI 的学习,初学者可能容易陷入各种细节的探究。 +剥离开技术细节,引导软件基本做的就是初始化硬件和提供硬件的软件抽象,并完成引导启动。 +启动阶段搞来搞去基本就三个步骤: + +第一步:Rom 阶段。 +该这个阶段没有内存,没有C语言运行需要的栈空间,开始往往是汇编语言,直接在 ROM 空间上运行。 +在找到临时空间后( Cache As Ram, CAR ),C 语言可以使用,然后开始用 C 语言初始化内存。 + +第二步:Ram 阶段。 +这个阶段有大内存可以使用。开始会初始化芯片组、CPU、主板模块等等核心过程。 + +第三步:引导 OS 阶段。 +枚举设备,发现启动设备,并把启动设备之前需要依赖的节点统统打通。 +移交工作,Windows 或者 Linux 的时代开始。 + +## UEFI 和硬件平台以及操作系统的基本关系 + +![uefi-general](images/riscv_uefi/uefi_general.png) + +EFI 在过程中会提供运行时服务和 EFI 引导时服务; +(引导时服务只在 boot time 可用,runtime service 在引导后面的 OS 后还是可以继续被使用的) + +引导图,文章后面会更详细的进行相关的介绍 +![uefi-boot](images/riscv_uefi/uefi_boot.png) + +## UEFI 的引导流程 + +UEFI 启动过程遵循 UEFI 平台初始化( Platform Initialization )标准,共经历了七个阶段。 + +![uefi-pi](images/riscv_uefi/uefi_pi.png) + +7个阶段分别为 `SEC (Security)`,`PEI (Pre-EFi Initalization)`,`DXE (Driver Execution Environment)`,`BDS (Boot Device Selection)`,`TSL (Transient System Load)`,`RT (Runtime)`,`AL (After Life)`。 +前三个阶段是 UEFI 初始化阶段。 下次介绍一下每个阶段的主要任务; + +SEC 阶段主要完成任务有: +处理系统上电或重启; +创建临时内存; +提供安全信任链的根; +传送系统参数到下一阶段; + +PEI 阶段主要完成任务: +依次进行平台的初始化,如 CPU,内存控制器,I/O 控制器,以及各种平台接口; + +DXE 阶段主要完成任务: +该阶段执行系统初始化工作,为后续 UEFI 和操作系统提供了 UEFI 系统表、启动服务和运行时服务; + +BDS 阶段主要完成任务: +复现每个启动设备,并执行启动策略。 +如果 BDS 启动失败,系统会重新掉用 DXE 派遣器,再次进入寻找启动设备的流程; + +TSL 阶段主要完成任务: +临时系统, 是 UEFI 将系统控制权转移给操作系统前的一个中间状态; + +RT 阶段 +UEFI 各种系统资源被转移,启动服务不能再使用,仅保留运行时服务供操作系统使用; + +AL 阶段 +这个阶段的功能一版有厂商自定义; + +## EDK2 +EDK2 是一个现代、功能丰富的跨平台固件开发环境,适用于 UEFI 相应编译和调试工作。 + +在 Linux 平台上,可以使结合 QEMU+GDB 进行相应调试。 + +调试步骤后面会同样更新到该文档 (TODO) + +## 参考文档 +`https://uefi.org/specifications` +`https://edk2-docs.gitbook.io/edk-ii-build-specification/` diff --git a/articles/images/riscv_uefi/uefi_boot.png b/articles/images/riscv_uefi/uefi_boot.png new file mode 100644 index 0000000000000000000000000000000000000000..5ec7cf0a299a6ed045fc96a885a14e41f4498ce5 Binary files /dev/null and b/articles/images/riscv_uefi/uefi_boot.png differ diff --git a/articles/images/riscv_uefi/uefi_general.png b/articles/images/riscv_uefi/uefi_general.png new file mode 100644 index 0000000000000000000000000000000000000000..5d65887514681040184f11a9d7405ecf9125afe4 Binary files /dev/null and b/articles/images/riscv_uefi/uefi_general.png differ diff --git a/articles/images/riscv_uefi/uefi_pi.png b/articles/images/riscv_uefi/uefi_pi.png new file mode 100644 index 0000000000000000000000000000000000000000..9aca168a2223f30b1da199381243ca4302ff5261 Binary files /dev/null and b/articles/images/riscv_uefi/uefi_pi.png differ