【UEFI基础】Device Path(一)

1. 什么是Device Path Device Path Protocol

UEFI为什么要提出Device Path的设计

关于Device Path,UEFI SPEC中有如下的描述

2.Device Path Protocol

3.不同类型的Device Path Device

4.Path的组织结构

5.如何解读UEFI Shell下Mapping Table中的Device Path

6.Device Path操作接口

7.Device Path的实际使用

1. 什么是Device Path Device Path Protocol
UEFI为什么要提出Device Path的设计
The primary purpose of a Device Path is to allow an application, such as an OS loader, to determine the physical device that the interfaces are abstracting.
A collection of device paths is usually referred to as a name space.
However, the ACPI name space was designed for usage at operating system runtime and does not fit well in platform firmware or OS loaders. Given this, EFI defines its own name space, called a Device Path.
A Device Path is designed to make maximum leverage of the ACPI name space.

关于Device Path,UEFI SPEC中有如下的描述
A Device Path is constructed and used by the firmware to convey the location of important devices, such as the boot device and console, consistent with the software-visible topology of the system.

A Device Path is used to define the programmatic path to a device.

A Device Path is designed to make maximum leverage of the ACPI name space.

The Device Path also is used to fill in the gaps where ACPI defers to buses with standard enumeration algorithms.

The Device Path is also used to define the location on a medium where a file should be, or where it was loaded from.

A special case of the Device Path can also be used to support the optional booting of legacy operating systems from legacy media.

2. Device Path Protocol
Device Path Protocol是Device Path在UEFI下的另一种,也是最常用的表示。(字符串形式的只是打印出来给人看的)

每一个代表实际物理设备或者逻辑设备的Handle都会安装Device Path Protocol。

Device Path Protocol在UEFI下的通用结构体如下:


/**
  This protocol can be used on any device handle to obtain generic path/location 
  information concerning the physical device or logical device. If the handle does 
  not logically map to a physical device, the handle may not necessarily support 
  the device path protocol. The device path describes the location of the device 
  the handle is for. The size of the Device Path can be determined from the structures 
  that make up the Device Path.
**/
typedef struct {
  UINT8 Type;       ///< 0x01 Hardware Device Path.
                    ///< 0x02 ACPI Device Path.
                    ///< 0x03 Messaging Device Path.
                    ///< 0x04 Media Device Path.
                    ///< 0x05 BIOS Boot Specification Device Path.
                    ///< 0x7F End of Hardware Device Path.
                    
  UINT8 SubType;    ///< Varies by Type
                    ///< 0xFF End Entire Device Path, or
                    ///< 0x01 End This Instance of a Device Path and start a new
                    ///< Device Path.
                    
  UINT8 Length[2];  ///< Specific Device Path data. Type and Sub-Type define
                    ///< type of data. Size of data is included in Length.
                   

3. 不同类型的Device Path Device
目前的UEFI版本(2.6版本)定义了6种Device Path,分别是:

Device Path
Hardware Device Path
ACPI Device Path
Messaging Device Path
Media Device Path
BIOS Boot Specification Device Path
End of Hardware Device Path

需要说明下:

  1. 一个Device Path可能说由多个Device Path组成的,则各个组成部分被称为Device Path Node;

  2. 每个Device Path都由End of Hardware Device Path结尾;

  3. End of Hardware Device Path由两种类型,一种是End of This Instance of a Device Path(Sub-Type是0x01),另一种是End Entire Device Path(Sub-Type是0xFF),前者用在Device Path Node的最后,后者用在整个Device Path的最后:

在UEFI中有指定的函数来判断这两种End of Hardware Device Path:

BOOLEAN
EFIAPI
IsDevicePathEnd (
  IN CONST VOID  *Node
  )
{
  ASSERT (Node != NULL);
  return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
}
 
BOOLEAN
EFIAPI
IsDevicePathEndInstance (
  IN CONST VOID  *Node
  )
{
  ASSERT (Node != NULL);
  return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
}

Hardware Device Path
Hardware Device Path描述了与一个设备关联的系统资源,比如共享内存,MMIO,IO等。

Hardware Device Path有多种子类型,比如PCI Device Path:

其它的类型还有:

Hardware Device Path
PCCARD Device Path
Memory Mapped Device Path
Vendor Device Path
Controller Device Path
BMC Device Path

这里不多做介绍,可以去看UEFI SPEC。

ACPI Device Path
ACPI Device Path包含了ACPI设备ID和其它的一些内容,有_HID、_CID、_UID等ID和_ADR等其它信息。

根据包含的ACPI信息的多少,也有不同的子类型,如:

ACPI Device Path
Expanded ACPI Device Path
ACPI _ADR Device Path

关于***Messaging Device Path***,UEFI SPEC的定义如下:

This Device Path is used to describe the connection of devices outside the resource domain of the
system. This Device Path can describe physical messaging information like SCSI ID, or abstract
information like networking protocol IP addresses.

并不是很理解,不过看起来像是一些总线和协议对应的Device Path,它有如下的子类型:

Messaging Device Path
ATAPI Device Path
SCSI Device Path
Fibre Channel Device Path
1394 Device Path
USB Device Path
SATA Device Path
USB Device Paths (WWID)
Device Logical Unit
USB Device Path (Class)
I2O Device Path
MAC Address Device Path
IPv4 Device Path
IPv6 Device Path
VLAN device path node
InfiniBand Device Path
UART Device Path
Vendor-Defined Messaging Device Path
UART Flow Control Messaging Path
Serial Attached SCSI (SAS) Device Path
Serial Attached SCSI (SAS) Ex Device Path
iSCSI Device Path
NVM Express namespace messaging device path node
Uniform Resource Identifiers (URI) Device Path
UFS (Universal Flash Storage) device messaging device path node
SD (Secure Digital) Device Path
EFI Bluetooth Device Path
Wireless Device Path

各种意义不明…

Media Device Path
Media Device Path表示了能够作为启动项的设备的Device Path。

下面是所有的子类型:

Media Device Path
Hard Drive
CD-ROM Media Device Path
Vendor-Defined Media Device Path
File Path Media Device Path
Media Protocol Device Path
PIWG Firmware File
PIWG Firmware Volume
Relative Offset Range
Relative Offset Range
RAM Disk

BIOS Boot Specification Device Path
BIOS Boot Specification Device Path与前一种Media Device Path类型,不同的是它表示的是Legacy BIOS启动项设备。

其中的Device Type也有不同的类型:

• 00h = Reserved
• 01h = Floppy
• 02h = Hard Disk
• 03h = CD-ROM
• 04h = PCMCIA
• 05h = USB
• 06h = Embedded network
• 07h…7Fh = Reserved
• 80h = BEV device
• 81h…FEh = Reserved
• FFh = Unknown
回到最开始的UEFI Shell的图中,里面的Device Path:

PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
它由三个Device Path Node组成,分别是:

  1. PciRoot(0x0):一个ACPI Device Path;

  2. Pci(0x1,0x1):一个Hardware Device Path,子类型是PCI Device Path;

  3. Ata(0x0):一个Messaging Device Path,子类型是ATAPI Device Path;

4. Device Path可以表示哪些设备? 是如何表示的
Device Path的组织结构
Device Path以Device Path Node为基本单位来依次串接而成,其结束标志是End of Hardware Device Path类型的Device Path Node。下图展示了Device Path Node的基本结构:
在这里插入图片描述

每个Device Path Node代表某一层级的域/设备或者设备属性(比如MAC地址/IPv4地址/IPv6地址等)。通常来说,它们会按照各自所处的Subsystem的拓扑结构至顶向下来排列形成最终Device Path,从而代表了设备的拓扑路径。下面,以开篇的UEFI Shell下的Device Path为例来说明。

Example 1:Removable USB HDD with MBR partition PciRoot(0x0)/Pci(0x14,0x0)/USB(0x0,0x0)/HD(1,MBR,0x01EDBE02,0x800,0x1004800)

PciRoot(0x0) => 代表Pci Root Bridge扩展出来的Pci总线域,这个是PCI设备的最顶层域,在台式机和笔记本上通常只有1个,其编号为0。

Pci(0x14,0x0) => 代表USB XHCI Controller,其PCI Device=0x14,PCI Function=0x00。PCI Bus因为是会变动的(比如有PCI设备Hot-Plug或者下次启动有PCI设备添加/移除),UEFI SPEC规定其值不纳入Device Path Node,通常结合平台信息可以推断出来PCI Bus的值。

USB(0x0,0x0) => 代表Removable USB HDD, 其接在USB Port 0上。

HD(1,MBR,0x01EDBE02,0x800,0x1004800) => 代表Removable USB HDD上的第1个硬盘分区,为MBR格式。

Example 2:NVMe SSD with GPT partition PciRoot(0x0)/Pci(0x1C,0x4)/Pci(0x0,0x0)/NVMe(0x1,C3-70-00-00-02-0D-08-00)/HD(1,GPT,425EAA1B-B401-4960-BEFC-5248CA7BCF28,0x800,0x82000)

PciRoot(0x0) => 意义同上。

Pci(0x1C,0x4) => 代表NVMe SSD所在的PCIe Root Port,其PCI Device=0x1C,PCI Function=0x04。

Pci(0x0,0x0) => 代表NVMe SSD Controller, 其PCI Device=0x0,PCI Function=0x0。

NVMe(0x1,C3-70-00-00-02-0D-08-00) => 代表NVMe的Name Space, 用该Name Space来标识NVMe SSD设备。

HD(1,GPT,425EAA1B-B401-4960-BEFC-5248CA7BCF28,0x800,0x82000) => 代表NVMe SSD上的第1个硬盘分区,为GPT格式。
Device Path的类别
UEFI SPEC一共定义了6个大类(Type)的Device Path Node,每个大类下面又分不同的子类(Sub-Type)。大类划分参考下面表格,子类的划分比较繁杂不便一一展开,请直接参考UEFI SPEC。

大类 可表示的典型设备/对象
Hardware Device Path PCI设备,Vendor自定义设备,BMC
ACPI Device Path PCI总线域(如上面的PciRoot(0x0))
显示输出设备,ACPI设备(比如鼠标/键盘等)
Messaging Device Path IDE设备,USB设备,SATA设备,SAS设备,SCSI设备,UART设备,Vendor自定义对象,MAC地址,IPv4/IPv6地址,其他新兴设备
Media Device Path 硬盘分区,CDROM分区,Vendor自定义Media,文件路径,UEFI固件分区,UEFI固件文件,RAM Disk
BIOS Boot Specification Device Path 传统的BIOS启动设备
End of Hardware Device Path Device Path终结符

Device Path的文本表示形式
UEFI定义了相关的Protocol来将Device Path的数据结构转换为可视化的文本形式。下面给出几种常见Devie Path Node类型的文本形式。

EDK2给出了将各种Device Path Node转换成文本形式的实现,具体参考:mUefiDevicePathLibToTextTable[] defined in edk2\MdePkg\Library\UefiDevicePathLib\DevicePathToText.c.

Device Path Node类型 文本格式 示例
PCI设备 Pci(Dev,Func)
Dev-PCI Device NumberFunc-PCI Function Number Pci(0x1C,0x4)
Vendor自定义设备 VenHw(GUID[,Data])
GUID为Vendor GUID,Data为对应的数据(如存在)
enHw(480B3204-C23C-4AE1-BB16-A73FADDA475F)
ACPI设备 - PCI总线域 PciRoot(UID)
UID为PCI总线域编号 PciRoot(0)
ACPI设备 - 通用形式 Acpi(HID,UID)
HID,UID定义参考ACPI SPEC Acpi(PNP0303,0x0)
IDE设备 Ata([PriSec,SlaveMaster,]LUN)
相关参数参考UEFI SPEC说明 Ata(Primary,Master,0)
USB设备 USB(ParentPort,InterfaceNumber)
相关参数参考UEFI SPEC说明 USB(0x5,0x0)
SATA设备 Sata(HBAPort,PortMultiplierPort,LUN)
相关参数参考UEFI SPEC说明 Sata(0x1,0x0,0x0)
NVMe设备 NVMe(NSID,EUI-64)
相关参数参考UEFI SPEC说明 NVMe(0x1,C3-70-00-00-02-0D-08-00)
硬盘分区 HD(PartitionNumber,PartitionFormat,PartitionSig,
PartitionStartLBA,PartitionSize)相关参数参考UEFI SPEC说明 HD(1,MBR,0x01EDBE02,0x800,0x1004800)
HD(1,GPT,425EAA1B-B401-4960-BEFC-5248CA7BCF28,0x800,0x82000)
CD-ROM分区 CDROM(BootEntry[,PartitionStartRBA,PartitionSize])
相关参数参考UEFI SPEC说明
MAC地址 MAC(MACAddr,NICInterface)
相关参数参考UEFI SPEC说明 MAC(54E1AD76ACEB,0x0)
IPv4地址 IPv4(RemoteIPAddr[,Protocol,Static/DHCP,LocalIPAddr,GatewayIPAddr,SubnetMask])
相关参数参考UEFI SPEC说明 IPv4(0.0.0.0)
IPv6地址 IPv6(RemoteIPAddr[,Protocol,IpAddressOrigin,LocalIPAddr,GatewayIPAddr,SubnetMask])
相关参数参考UEFI SPEC说明 IPv6(0000:0000:0000:0000:0000:0000:0000:0000)
UEFI固件分区 Fv(FvGUID)
相关参数参考UEFI SPEC说明 Fv(A881D567-6CB0-4EEE-8435-2E72D33E45B5)

Device Path与ACPI的联系
从上一节可以看到,ACPI Device Path类别的Device Path Node是沿用ACPI命名设计的。在Acpi(HID,UID)形式中,HID是APCI定义的"UUUNNNN"形式的HID字符串,UID也与APCI定义完全相同。
5. 如何解读UEFI Shell下Mapping Table中的Device Path
在“Device Path的组织结构”一节中已经解析过开篇提到的UEFI Shell下的Device Path了,这里补充说一下我对FSx和BLKx是如何进行映射的理解。

具体实现可以参考UEFI Shell在EDK2中的源码:ShellCommandCreateInitialMappingsAndPaths() defined in edk2\ShellPkg\Library\UefiShellCommandLib\UefiShellCommandLib.c.

详细的代码实现逻辑非常复杂,这里只挑几个要点陈述如下:

FSx的映射

1.先找到Support EFI_SIMPLE_FILE_SYSTEM_PROTOCOL的所有Device Handle,每个Device Handle代表1个File System,会被分配1个FSx:。

2.对上述每个Device Handle Locate到其Device Path,转换为Device Path Text,按Text String由小到大的顺序进行排序,对应的Device Handle的FSx从0开始依次编号。

BLKx的映射

1.先找到Support EFI_BLOCK_IO_PROTOCOL的所有Device Handle,每个Device Handle代表1个Block设备,会被分配1个BLKx:。

2.对上述每个Device Handle Locate到其Device Path,转换为Device Path Text, 按Text String由小到大的顺序进行排序,对应的Device Handle的BLKx从0开始依次编号。

3.如上述Device Handle与FSx映射中的Device Handle是同1个,则在对应的FSx:右侧标注对应的BLKx:。
6. Device Path操作接口
UEFI SPEC提供了一个工具接口来操作Device Path:

///
/// This protocol is used to creates and manipulates device paths and device nodes.
/// 
typedef struct {
  EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;
  EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH      DuplicateDevicePath;
  EFI_DEVICE_PATH_UTILS_APPEND_PATH          AppendDevicePath;
  EFI_DEVICE_PATH_UTILS_APPEND_NODE          AppendDeviceNode;
  EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE      AppendDevicePathInstance;
  EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE    GetNextDevicePathInstance;
  EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE    IsDevicePathMultiInstance;
  EFI_DEVICE_PATH_UTILS_CREATE_NODE          CreateDeviceNode;
} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;
具体各个接口的作用不多做介绍。

另外在EDKII代码中还提供了UefiDevicePathLib,里面也有不少有用的接口。

7. Device Path的实际使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值