UEFI原理 · 2023年7月20日 0

CSM原理学习

CSM原理学习,只看了一部分感觉有用的协议。

CSM工作原理

CSM(Compatibility Support Module)可使EFI具备兼容传统BIOS的能力。它负责将EFI下面的相关信息转换成传统BIOS下的信息,并提供在操作系统引导和运行过程中所需的传统BIOS中断服务。此外CSM还使传统Option ROM可以在EFI环境下运行。

CSM利用Framework完成硬件平台初始化、设备枚举及系统启动路径的选择。EIF中添加了CSM组件——EFI兼容模块(EfiCompatibility),以支持传统操作系统和传统的Option ROMs。

EfiCompatibility模块、IBV提供的Compatibility 16 BIOS模块、Compatibility 16 SMM模块一起构成了整个CSM。

下图为CSM工作原理组成图:

image-20230720151740177

EFI执行过程中,在BDS阶段之前只完成少部分的系统初始化和配置,不显示和执行Option ROM。只有到了BDS阶段,根据以下三种信息确定是否需要调用CSM模块

  • 目标操作系统

由于传统操作系统(non-EFI-aware)需要调用传统BIOS提供的中断服务。在EFI BIOS中必须调用CSM模块以支持传统操作系统以及在引导传统操作系统过程中需要执行的传统Option ROM。

  • 选择启动的设备

如果一个OS启动设备本身依赖于传统Option ROM,不管目标操作系统是传统操作系统还是EFI原生的操作系统,都需要调用CSM模块。

  • 设备的初始化策略

如果系统的启动策略是初始化所有的设备,只有其中有一个非引导设备(non-boot device)涉及到传统Option ROM,都必须执行CSM模块以支持该设备。

CSM架构

CSM模块使得EFI BIOS具备了加载引导传统操作系统和执行传统Option ROM的能力。它主要包括以下五个组件:

  • EFI兼容模块(EfiCompatibility, 简称CSM32)
  • 传统BIOS兼容模块(Compatibility 16 BIOS,简称CSM16)
  • 传统SMM驱动兼容模块(Compatibility 16 SMM)
  • 保护模式/实模式切换模块(Thunk and Reverse Thunk)
  • 传统Option ROM

EFI兼容模块(CSM32)

EFI兼容模块运行在32位保护模式下,和EFI本身进行交互,调用执行由CSM16提供的16位实模式下的函数接口及传统BIOS中断服务。CSM32模块由Framework提供,主要包括以下四种类型的EFI驱动:

  • 硬件平台无关的驱动
  • 平台无关的传统组件驱动,如传统的8259可编程中断控制器驱动
  • 芯片组相关的驱动,如ICH7
  • 硬件平台相关驱动,如PCI中断路由驱动

CSM32主要由以下几个协议组成:

  • Legacy BIOS protocol: 是CSM中最主要的协议,与硬件平台无关。
  • Legacy BIOS Platform protocol: 与平台相关,Chipset相同但硬件平台不同,该协议内部驱动实现会有差异。
  • Legacy Region Protocol:与Chipset相关,用于对内存区域0xc0000-0xfffff的读写控制。
  • Legacy 8259 Protocol:和硬件平台、chipset都无关,可以在32位保护模式或者16位实模式下对8259可编程中断控制器进行控制、实现中断屏蔽、电平触发或边沿触发工作模式编程。
  • Legacy Interrupt protocol:依赖与具体的chipset,用于给PCI设备分配中断路由。

除上面几个协议提供的功能之外,EFI兼容模块还包括许多模拟传统中断服务的驱动,如UGA设备中断INT 10,键盘中断INT 16以及块设备的I/O访问中断服务。

一些Option ROM运行时需要使用INT 10,因此UGA驱动需要运行在VGA模式以支持INT 10。该驱动将EFI下的控制台输出数据转化为对应的VGA格式。该驱动基于以下假设:所有的INT 10中断服务功能都已实现,也就是说Option ROM可以直接访问VGA所有寄存器及显存。UGA设备支持VGA模式并且根据要求UGA和VGA两种模式可以相互切换。

UGA採用USB輸入,VGA/DVI/HDMI接口輸出。通過主機USB接口,將音/視頻信號傳輸到顯示器(VGA/DVI/HDMI等接口)

UGA是由wavlink(睿因)公司於2003年在全球發布的一款通過USB接口轉接顯示器接口的硬體設備,其英文名全稱為USB Graphic Adapter,簡稱USB顯示卡,或USB外置(多功能)顯示卡。UGA採用USB輸入,VGA/DVI/HDMI接口輸出。通過主機USB接口,將音/視頻信號傳輸到顯示器(VGA/DVI/HDMI等接口)。

UGA又稱為UXGA,一種視頻制式。解析度剛好是 VGA的四倍。UXGA 是許多 4:3 的 20″ 和 21″ 螢幕的析度,不過隨著 4:3 螢幕愈來愈少見,要買到這個解析度的螢幕是愈來愈困難了。

Legacy BIOS Module

Legacy BIOS Module是整个CSM的主模块。其主要功能包括:

  • 初始化它本身并加载CSM16模块
  • 确定启动设备
  • 加载CSM32中的其他驱动程序
  • 加载保护模式/实模式切换模块
  • 初始化和CSM16交互的接口
  • 查找、加载和调用板载/非板载的Option ROM
  • 加载引导OS

Legacy BIOS Module分析当前系统的数据,调用EFI APIs来手机CSM16 所需的系统信息,并将这些信息转化为CSM16的数据结构。CSM16利用这些数据结构初始化位于系统内存0x400-0x500的传统BIOS数据区(BDA)、扩展BIOS数据区(EBDA)和CMOS。

Legacy BIOS protocol APIs也会使用这些数据对传统设备和传统资源进行重置。

EFI对硬件设备的枚举、配置是比较简单、低级的,它不会对串口或并口等传统设备分配IRQ(中断请求)。但CSM16要求这些传统设备具备正确的IRQ,因此Legacy BIOS代码需要对这些传统设备进行重新配置来满足要求。

Legacy BIOS protocol有两种实现方式:精简版和完全版。精简版适用于通过传统Option ROM引导EFI原生操作系统的应用。而需要引导传统操作系统的应用,则使用完全版。

Legacy BIOS protocol

Legacy BIOS protocol和Legacy BIOS module的初始化程序构成了整个CSM的基础。

下表为Legacy BIOS protocol的功能函数:

FunctionsDescription
BootUnconventionalDevice()用于从非常规设备引导系统,如PARTIES
CheckPciRom()用于检查PCI设备中是否有传统Option ROM,以及检查该设备是否只有传统Option ROM,而没有EFI Option ROM。并检查传统操作系统启动设备的有效性
CopyLegacyRegion()用于EFI下拷贝数据到函数GetLegacyRegion()指定的区域
FarCall86()使32位保护模式下的程序使用长调来调用16位实模式下的程序。和Int86()函数类似,只是把软中断替换成了长调用。
GetBbsInfo()允许外部驱动访问CSM32中的BBS数据结构。该函数主要被BIOS setup调用
GetLegacyRegion()允许在内存区域0xe0000-0xfffff地址段分配内存
Int86()使32位保护模式程序调用16位软中断程序,如INT 16。该函数通过调用Thunk程序切换到16位实模式,将输入参数指定的数据区载入到CPU寄存器,然后执行相应的软中断。中断程序返回后,使用CPU寄存器的值更新数据区,并切换回32位保护模式。
InstallPciRom()将传统Option ROM装载到内存区域0xc0000-0xfffff
LegacyBoot()用于引导传统OS,实现了CSM的大部分主要功能,由于引导传统OS的一些要求,执行该函数可能会关闭EFI相关功能。该函数最终会调用CSM16模式来执行传统INT 19中断服务,如果从选定的设备启动操作系统失败,CSM16会将控制权返回给该函数,在这种情况下,如果原来的EFI环境是保留的,或者在EFI启动和传统启动方式相互切换时EFI环境可以被恢复,则函数LegacyBoot()会将控制权返回给调用者。
PrepareToBootEfi()主要完成EFI原生操作系统的引导环境准备。执行包括给传统引导设备分配驱动号在内的LegacyBoot()函数的部分功能
ShadowAllLegacyOproms()加载运行所有的传统Option ROMs,运行Option Rom前会卸载设备原有的EFI驱动,因此,如果需要,执行完该函数后必须重新连接EFI驱动到设备上
UpdateKeyboardLedStatus()用于把EFI下的键盘LED状态信息同步到传统BIOS数据区。该函数不对键盘进行操作,而是调用CSM16中涉及键盘LED状态的函数来维护键盘灯的状态信息。

在确定了引导设备列表后,用户选择引导设备(或默认设备)。如果引导到传统OS则BDS调用LegacyBoot()函数,如果引导到支持EFI的OS且传统Option ROMs已初始化,则调用PrepareToBootEfi()函数。

Leygacy BIOS Platform Protocol

Leygacy BIOS Platform Protocol可以根据硬件平台的具体配置及OEM要求对CSM进行客制化,其中包含了多个功能函数:

FunctionDescription
GetPlatformHandle()搜索指定实体的所有句柄,并返回按照优先级分类的特定类型的句柄队列。包括VGA设备句柄、IDE控制器句柄、ISA总线控制器句柄以及USB设备句柄等
GetPlatformInfo()用于获取平台特定的二进制目标文件或数据,包括MP table,OEM特定的16位或32位的映像文件,TPM二进制文件等
GetRoutionTable()为中断路由表获取平台相关的PCI中断路由信息
PlatformHooks()执行平台相关的一些操作。如完成扫描Option ROM之前的一些特殊处理,映射物理设备无关的Option ROM(PXE驱动及BIS),以及Option ROM初始化后的一些处理等
PrepareToBoot()完成传统OS的引导
SmmInit()检查EFI固件卷中是否有16位模式下的SMM驱动模块,如有,则使用EFI SMM驱动注册CSM16 SMM模块。
TranslatePirq()将中断信息写到对应的芯片组中断路由寄存器中,同时返回指定设备可用的中断号

Legacy Region Protocol

Legacy Region Protocol与Chipset相关,用于对内存区域0xc0000-0xfffff的读写控制。

FunctionDescription
Decode()完成对芯片组的初始化,使能或禁止对该内存区域的解码
Lock()将指定区域(0xc0000-0xfffff)设为只读(写保护)
BootLock()在引导传统OS之前调用,该函数将指定区域锁定(写保护)以防止误操作其他地址段(aliased addresses)
Unlock()将指定内存区域设为可读写,同时防止误操作其他地址段

Legacy 8259 Protocol

该协议可以在32位保护模式或者16位实模式下对8259可编程中断控制器进行控制、实现中断屏蔽、电平触发或边沿触发工作模式编程。

8259可编程中断控制器(PIC) 是构成 x86 架构的最重要芯片之一。没有它,x86 架构就不是中断驱动的架构。

8259A 是原始IBM PCIBM PC AT中ISA 总线的中断控制器。

8259A的功能是管理硬件中断并将它们发送到适当的系统中断。这使得系统能够响应设备需求而不会损失时间(例如,轮询设备)。

值得注意的是,APIC已经在更现代的系统中取代了 8259 PIC,特别是那些具有多个内核/处理器的系统。

虽然 8259A 接口不再是一个单独的芯片,但仍然由现代x86主板上的平台控制器集线器南桥芯片组提供。

FunctionDescription
SetVectorBase()初始化主/从8259可编程中断控制器的中断向量基址。在EFI环境下,主8259控制器的中断向量基址设为0x1A0(INT 68),从8259控制器的中断向量基址设为0x1C0(INT 70)。在16位实模式下,主8259控制器的中断向量基址设为0x20(INT 08),从8259控制器的中断向量基址设为0x1C0(INT 70)。不同的中断向量基址可以防止中断和CPU异常被覆盖。
GetMask()用来获取EFI环境下或16位实模式下当前主/从8259控制器的中断屏蔽信息及中断触发方式(边沿触发or电平触发)
SetMask()完成在32位EFI环境下或16位传统环境下设置主/从8259控制器的中断屏蔽信息及中断触发方式
SetMode()完成在32位EFI环境下或16位传统环境下设置主/从8259控制器的中断屏蔽信息及中断触发方式。同一模式下,不应多次调用该函数,应使用SetMask()函数
GetVector()完成将某一硬中断号转换为对应的软中断号,如EFI下将IRQ0转换为INT 68,或传统环境下IRQ0 转换为INT 08
EnableIrq()在EFI下使能某一个硬中断,非CSM驱动可以调用
DisableIrq()在EFI下禁用某一个硬中断,非CSM驱动可以调用
GetinterruptLine()读取指定PCI设备的配置空间并返回分配给该设备的中断号
EndOfInterrupt()下发中断结束(EOI)命令给中断控制器

Legacy Interrup Protocol

该协议用于对PCI中断的编程控制。

FunctionDescription
GetNumberPirqs()返回chipset支持的所有PIRQ(PCI IRQ)个数
GetLocation()返回支持该协议的PCI设备的位置
ReadPirq()读取指定PIRQ寄存器并返回该寄存器的值
WritePirq()填写数据到指定的PIRQ寄存器

传统BIOS兼容模块(CSM16)

CSM16模块运行在16位实模式下,提供传统BIOS中断服务调用。主要由INT13、INT19、INT15等中断服务程序组成。除中断服务程序外,CSM16还包括和CSM32交互的接口程序。CSM16一般由IBV提供。

CSM16模块可以看成是一个没有POST和Setup配置界面的传统BIOS。CSM16模块设计的目的是希望使CSM16模块在所有平台都通用。它不会配置任何底层硬件,但可以通过传统BIOS的接口来控制一些传统硬件。

CSM16模块包含全部的runtime服务和传统BIOS所需的软中断和硬中断服务程序。模块还必须支持与传统BIOS兼容的BIOS数据区(BDA:BIOS Data Area)、扩展数据区(EBDA:Extend BDA)以及一些中断服务在F000内存段的固定入口地址。另外还提供一些用于EFI和CSM16之间互相通信的16位程序。

BIOS中断服务

下表为CSM16模块提供的传统中断服务:

INTDescription
0x02NMI不可屏蔽中断
0x05屏幕输出
0x08系统时钟中断(IRQ0)
0x09键盘中断(IRQ1)
0x10显卡(显示)服务,由Video OpROM提供
0x11设备检测
0x12基本内存大小检测
0x13磁盘中断服务
0x14串口通讯服务
0x15系统服务
0x16键盘服务
0x17并口打印机服务
0x18系统启动管理服务
0x19系统引导程序服务
0x1A系统时间服务
0x1B程序中断服务
0x1C定时器服务
0x1D显示参数
0x1E软驱控制参数
0x1F字符矩阵
0x40软盘服务
0x41主硬盘控制器参数
0x46从硬盘控制器参数
0x70RTC中断(IRQ8)
0x74PS2鼠标中断(IRQ12)
0x75数字协处理器中断(IRQ13)
0x76主IDE硬盘控制器中断(IRQ14)
0x77从IDE硬盘控制器中断(IRQ15)

传统SMM兼容模块(Compatibility 16 SMM)

Compatibility 16 SMM提供传统的SMM服务,作为EFI SMM驱动的补充,是可选的,由IBV或OEM厂家提供。

保护模式/实模式切换模块(Thunk and Reverse Thunk)

该模块提供了保护模式/实模式相互转换的驱动。CSM32通过Thunk程序从EFI 32位保护模式切换到传统的16位实模式,CSM16通过ReverseThunk从16位实模式切换回32位保护模式。该模块由Framework提供。

传统Option ROM(Legacy Option ROM)

传统Option ROM虽然不被包含在CSM模块之中,但从整个BIOS系统层面来看,它是一个非常重要的组件,它和CSM模块联合工作,共同完成了传统OS的加载引导。

Option ROM一般由设备厂家提供,有两种方式:一种是集成打包到EFI firmware里面,另一种是放在对应设备的ROM里。

参考

*Intel*® *Platform Innovation Framework for UEFI*

*Compatibility Support Module Specification*

《Beyond BIOS》