在EDK II 代码里面,DEVICE PATH 长这个样子
/**
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.
} EFI_DEVICE_PATH_PROTOCOL;
但是这个还是很抽象,我们以创文件为例,在debug 模式,看看它的真实模样:
EfiShellCreateFile(
IN CONST CHAR16 *FileName,
IN UINT64 FileAttribs,
OUT SHELL_FILE_HANDLE *FileHandle
)
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_STATUS Status;
BOOLEAN Volatile;
//
// Is this for an environment variable
// do we start with >v
//
if (StrStr(FileName, L">v") == FileName) {
Status = IsVolatileEnv (FileName + 2, &Volatile);
if (EFI_ERROR (Status)) {
return Status;
}
if (!Volatile) {
return (EFI_INVALID_PARAMETER);
}
*FileHandle = CreateFileInterfaceEnv(FileName+2);
return (EFI_SUCCESS);
}
//
// We are opening a regular file.
//
DevicePath = EfiShellGetDevicePathFromFilePath(FileName);
__asm int 3;
if (DevicePath == NULL) {
return (EFI_NOT_FOUND);
}
Status = InternalOpenFileDevicePath(DevicePath, FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, FileAttribs);
FreePool(DevicePath);
在这里,我放了一个 __asm int 3; 这个内嵌的汇编语言,能起到一个断点的作用,程序运行到这里,会自然停下来,然后我们就可以通过观察局部变量知道它真实的样子了。
首先通过它在函数里面的定义,我们可以看到它是一个结构体指针,指针的意思相信大家都知道,指针即地址,意思是从这之后,挨个摆着的是device path.