EFI_STATUS
CoreLoadPeImage (
IN BOOLEAN BootPolicy,
IN VOID *Pe32Handle,
IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
IN UINT32 Attribute
)
具体代码如下:
DEBUG ((DEBUG_INFO | DEBUG_LOAD,
"Loading driver at 0x%11p EntryPoint=0x%11p ",
(VOID *)(UINTN) Image->ImageContext.ImageAddress,
FUNCTION_ENTRY_POINT (Image->ImageContext.EntryPoint)));
//
// Print Module Name by Pdb file path.
// Windows and Unix style file path are all trimmed correctly.
//
if (Image->ImageContext.PdbPointer != NULL) {
StartIndex = 0;
for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {
if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) {
StartIndex = Index + 1;
}
}
//
// Copy the PDB file name to our temporary string, and replace .pdb with .efi
// The PDB file name is limited in the range of 0~255.
// If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary.
//
for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];
if (EfiFileName[Index] == 0) {
EfiFileName[Index] = '.';
}
if (EfiFileName[Index] == '.') {
EfiFileName[Index + 1] = 'e';
EfiFileName[Index + 2] = 'f';
EfiFileName[Index + 3] = 'i';
EfiFileName[Index + 4] = 0;
break;
}
}
if (Index == sizeof (EfiFileName) - 4) {
EfiFileName[Index] = 0;
}
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
}
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
DEBUG_CODE_END ();
/// PeCoffLoader ImageContext
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
PE_COFF_LOADER_IMAGE_CONTEXT 结构体定义在 \MdePkg\Include\Library\PeCoffLib.h 文件中:
///
/// The context structure used while PE/COFF image is being loaded and relocated.
///
typedef struct {
…..省略…..
///
/// Set by PeCoffLoaderLoadImage() to point to the PDB entry contained in the CodeView area.
/// The PdbPointer points to the filename of the PDB file used for source-level debug of
/// the image by a debugger.
///
CHAR8 *PdbPointer;
…..省略…..
} PE_COFF_LOADER_IMAGE_CONTEXT;
/**
Returns a pointer to the PDB file name for a PE/COFF image that has been
loaded into system memory with the PE/COFF Loader Library functions.
Returns the PDB file name for the PE/COFF image specified by Pe32Data. If
the PE/COFF image specified by Pe32Data is not a valid, then NULL is
returned. If the PE/COFF image specified by Pe32Data does not contain a
debug directory entry, then NULL is returned. If the debug directory entry
in the PE/COFF image specified by Pe32Data does not contain a PDB file name,
then NULL is returned.
If Pe32Data is NULL, then ASSERT().
@param Pe32Data The pointer to the PE/COFF image that is loaded in system
memory.
@return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
if it cannot be retrieved.
**/
VOID *
EFIAPI
PeCoffLoaderGetPdbPointer (
IN VOID *Pe32Data
)
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset get Debug Directory Entry
//
NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
使用 SFF 分析,上面的位置是下面绿色框中 Data Directories[x] 中的EFI_IMAGE_DIRECTORY_ENTRY_DEBUG (该值为6),即右侧红色框中的值。可以看到在文件中的0x1AD0位置,大小为0x54。
EFI_STATUS
EFIAPI
CoreStartImage (
IN EFI_HANDLE ImageHandle,
OUT UINTN *ExitDataSize,
OUT CHAR16 **ExitData OPTIONAL
)
……省略……
SetJumpFlag = SetJump (Image->JumpContext);
//
// The initial call to SetJump() must always return 0.
// Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().
//
if (SetJumpFlag == 0) {
RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER));
//LABZDEBUG_Start
UINTN Index;
UINTN StartIndex;
CHAR8 EfiFileName[256];
//
// Print Module Name by Pdb file path.
// Windows and Unix style file path are all trimmed correctly.
//
if (Image->ImageContext.PdbPointer != NULL) {
StartIndex = 0;
for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {
if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) {
StartIndex = Index + 1;
}
}
//
// Copy the PDB file name to our temporary string, and replace .pdb with .efi
// The PDB file name is limited in the range of 0~255.
// If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary.
//
for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];
if (EfiFileName[Index] == 0) {
EfiFileName[Index] = '.';
}
if (EfiFileName[Index] == '.') {
EfiFileName[Index + 1] = 'e';
EfiFileName[Index + 2] = 'f';
EfiFileName[Index + 3] = 'i';
EfiFileName[Index + 4] = 0;
break;
}
}
if (Index == sizeof (EfiFileName) - 4) {
EfiFileName[Index] = 0;
}
DEBUG ((DEBUG_INFO , "%a\n", EfiFileName));
if (AsciiStrCmp(EfiFileName,"Hello.efi")==0) {
CpuBreakpoint();
}
}
//LABZDEBUG_End
//
// Call the image's entry point
//
Image->Started = TRUE;
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
……省略……
typedef struct {
UINTN Signature;
/// Image handle
EFI_HANDLE Handle;
/// Image type
UINTN Type;
/// If entrypoint has been called
BOOLEAN Started;
/// The image's entry point
EFI_IMAGE_ENTRY_POINT EntryPoint;
/// loaded image protocol
EFI_LOADED_IMAGE_PROTOCOL Info;
/// Location in memory
EFI_PHYSICAL_ADDRESS ImageBasePage;
/// Number of pages
UINTN NumberOfPages;
/// Original fixup data
CHAR8 *FixupData;
/// Tpl of started image
EFI_TPL Tpl;
/// Status returned by started image
EFI_STATUS Status;
/// Size of ExitData from started image
UINTN ExitDataSize;
/// Pointer to exit data from started image
VOID *ExitData;
/// Pointer to pool allocation for context save/restore
VOID *JumpBuffer;
/// Pointer to buffer for context save/restore
BASE_LIBRARY_JUMP_BUFFER *JumpContext;
/// Machine type from PE image
UINT16 Machine;
/// EBC Protocol pointer
EFI_EBC_PROTOCOL *Ebc;
/// Runtime image list
EFI_RUNTIME_IMAGE_ENTRY *RuntimeData;
/// Pointer to Loaded Image Device Path Protocol
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
/// PeCoffLoader ImageContext
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
/// Status returned by LoadImage() service.
EFI_STATUS LoadImageStatus;
} LOADED_IMAGE_PRIVATE_DATA;
///
/// Revision defined in EFI1.1.
///
#define EFI_LOADED_IMAGE_INFORMATION_REVISION EFI_LOADED_IMAGE_PROTOCOL_REVISION
///
/// Can be used on any image handle to obtain information about the loaded image.
///
typedef struct {
UINT32 Revision; ///< Defines the revision of the EFI_LOADED_IMAGE_PROTOCOL structure.
///< All future revisions will be backward compatible to the current revision.
EFI_HANDLE ParentHandle; ///< Parent image's image handle. NULL if the image is loaded directly from
///< the firmware's boot manager.
EFI_SYSTEM_TABLE *SystemTable; ///< the image's EFI system table pointer.
//
// Source location of image
//
EFI_HANDLE DeviceHandle; ///< The device handle that the EFI Image was loaded from.
EFI_DEVICE_PATH_PROTOCOL *FilePath; ///< A pointer to the file path portion specific to DeviceHandle
///< that the EFI Image was loaded from.
VOID *Reserved; ///< Reserved. DO NOT USE.
//
// Images load options
//
UINT32 LoadOptionsSize;///< The size in bytes of LoadOptions.
VOID *LoadOptions; ///< A pointer to the image's binary load options.
//
// Location of where image was loaded
//
VOID *ImageBase; ///< The base address at which the image was loaded.
UINT64 ImageSize; ///< The size in bytes of the loaded image.
EFI_MEMORY_TYPE ImageCodeType; ///< The memory type that the code sections were loaded as.
EFI_MEMORY_TYPE ImageDataType; ///< The memory type that the data sections were loaded as.
EFI_IMAGE_UNLOAD Unload;
} EFI_LOADED_IMAGE_PROTOCOL;
我们使用代码中的 Hello.EFI 作为例子,它的大小是7712bytes。最终,代码如下:
SetJumpFlag = SetJump (Image->JumpContext);
//
// The initial call to SetJump() must always return 0.
// Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().
//
if (SetJumpFlag == 0) {
RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER));
//LABZDEBUG_Start
DEBUG ((EFI_D_INFO,"Current size [%d] bytes\n", Image->Info.ImageSize));
if (Image->Info.ImageSize == 7712) {
CpuBreakpoint();
}
//LABZDEBUG_End
//
// Call the image's entry point
//
Image->Started = TRUE;
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
就是说当发现加载的Image 大小是 7712 bytes 的时候自动触发一个 Breakpoint 打开 VS 进行调试:
Ru 是AMI 的 James Wang(个人主页http://ruexe.blogspot.tw/)推出的系列工具,其中包括IA32
X64版本的Ru.EFI和一个 Windows 版本的 RU.EXE。最新版本可以在https://github.com/JamesAmiTw/ru-uefi
下载到。
本文简单介绍它的功能和使用。
UEFI X64 版本初始界面如下:
File 菜单,提供了 Load Save 和 Compare 功能,可以保存和读取当前页面的数据,一般情况下不会使用,主要原因是操作没有 Windows 下方便。
2.Config 菜单用来进行寄存器的访问。
2.1 PCI 可以访问 PCI
设备
选中后输入要查看设备的 Bus Dev Func:
2.2 ISA
ISA IO是
Index/Data 这种形式的访问IO Port:
2.3 ISA IO
选择之后会出现2个选项让你选择:
例如,下面是查看 CMOS
的结果。个人感觉这个和上面的 ISA 选项通过手动输入端口号没有差别。
2.4 IO Space
选择后出现额外菜单如下:
选择 Normal
IO Space 后会要求输入要查看的端口。
2.5 IDE Identify。这个功能能够查看当前系统中的SATA接口的硬盘信息(PCIE接口的SSD不行)。
选中后会出现提示继续选择要查看的硬盘。
之后可以查看硬盘信息。
额外说一句:不知道什么原因,这个功能和截图软件(CrScreenshotDxe)有冲突,运行这个功能后,会导致死机。本篇的截图都是使用 HDMI 转 USB 设备完成的。
for (byte x = 0 ; x < 2 ; x++){
uint16_t mlx90640Frame[834];
int status = MLX90640_GetFrameData(MLX90640_address, mlx90640Frame);
float vdd = MLX90640_GetVdd(mlx90640Frame, &mlx90640);
float Ta = MLX90640_GetTa(mlx90640Frame, &mlx90640);
float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
float emissivity = 0.95;
MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To);
}
/**
Reads an 8-bit I/O port.
Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
This function must guarantee that all I/O read and write operations are
serialized.
If 8-bit I/O port operations are not supported, then ASSERT().
@param Port The I/O port to read.
@return The value read.
**/
UINT8
EFIAPI
IoRead8 (
IN UINTN Port
)
{
UINT8 Value;
_ReadWriteBarrier ();
Value = (UINT8)_inp ((UINT16)Port);
_ReadWriteBarrier ();
return Value;
}
#define IO_LIB_ADDRESS(Segment, Port) \
( ((Port) & 0xffff) | (((Segment) & 0xffff) << 16) )
UINT8
EFIAPI
IoRead8 (
IN UINTN Port
);
UINT8
EFIAPI
IoWrite8 (
IN UINTN Port,
IN UINT8 Value
);
VOID
EFIAPI
IoReadFifo8 (
IN UINTN Port,
IN UINTN Count,
OUT VOID *Buffer
);
VOID
EFIAPI
IoWriteFifo8 (
IN UINTN Port,
IN UINTN Count,
IN VOID *Buffer
);
UINT8
EFIAPI
IoOr8 (
IN UINTN Port,
IN UINT8 OrData
);
UINT8
EFIAPI
IoAnd8 (
IN UINTN Port,
IN UINT8 AndData
);
UINT8
EFIAPI
IoAndThenOr8 (
IN UINTN Port,
IN UINT8 AndData,
IN UINT8 OrData
);
UINT8
EFIAPI
IoBitFieldRead8 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT8
EFIAPI
IoBitFieldWrite8 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 Value
);
UINT8
EFIAPI
IoBitFieldOr8 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 OrData
);
UINT8
EFIAPI
IoBitFieldAnd8 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 AndData
);
UINT8
EFIAPI
IoBitFieldAndThenOr8 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 AndData,
IN UINT8 OrData
);
UINT16
EFIAPI
IoRead16 (
IN UINTN Port
);
UINT16
EFIAPI
IoWrite16 (
IN UINTN Port,
IN UINT16 Value
);
VOID
EFIAPI
IoReadFifo16 (
IN UINTN Port,
IN UINTN Count,
OUT VOID *Buffer
);
VOID
EFIAPI
IoWriteFifo16 (
IN UINTN Port,
IN UINTN Count,
IN VOID *Buffer
);
UINT16
EFIAPI
IoOr16 (
IN UINTN Port,
IN UINT16 OrData
);
UINT16
EFIAPI
IoAnd16 (
IN UINTN Port,
IN UINT16 AndData
);
UINT16
EFIAPI
IoAndThenOr16 (
IN UINTN Port,
IN UINT16 AndData,
IN UINT16 OrData
);
UINT16
EFIAPI
IoBitFieldRead16 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT16
EFIAPI
IoBitFieldWrite16 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 Value
);
UINT16
EFIAPI
IoBitFieldOr16 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 OrData
);
UINT16
EFIAPI
IoBitFieldAnd16 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 AndData
);
UINT16
EFIAPI
IoBitFieldAndThenOr16 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 AndData,
IN UINT16 OrData
);
UINT32
EFIAPI
IoRead32 (
IN UINTN Port
);
UINT32
EFIAPI
IoWrite32 (
IN UINTN Port,
IN UINT32 Value
);
VOID
EFIAPI
IoReadFifo32 (
IN UINTN Port,
IN UINTN Count,
OUT VOID *Buffer
);
VOID
EFIAPI
IoWriteFifo32 (
IN UINTN Port,
IN UINTN Count,
IN VOID *Buffer
);
UINT32
EFIAPI
IoOr32 (
IN UINTN Port,
IN UINT32 OrData
);
UINT32
EFIAPI
IoAnd32 (
IN UINTN Port,
IN UINT32 AndData
);
UINT32
EFIAPI
IoAndThenOr32 (
IN UINTN Port,
IN UINT32 AndData,
IN UINT32 OrData
);
UINT32
EFIAPI
IoBitFieldRead32 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT32
EFIAPI
IoBitFieldWrite32 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 Value
);
UINT32
EFIAPI
IoBitFieldOr32 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 OrData
);
UINT32
EFIAPI
IoBitFieldAnd32 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 AndData
);
UINT32
EFIAPI
IoBitFieldAndThenOr32 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 AndData,
IN UINT32 OrData
);
UINT64
EFIAPI
IoRead64 (
IN UINTN Port
);
UINT64
EFIAPI
IoWrite64 (
IN UINTN Port,
IN UINT64 Value
);
UINT64
EFIAPI
IoOr64 (
IN UINTN Port,
IN UINT64 OrData
);
UINT64
EFIAPI
IoAnd64 (
IN UINTN Port,
IN UINT64 AndData
);
UINT64
EFIAPI
IoAndThenOr64 (
IN UINTN Port,
IN UINT64 AndData,
IN UINT64 OrData
);
UINT64
EFIAPI
IoBitFieldRead64 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT64
EFIAPI
IoBitFieldWrite64 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 Value
);
UINT64
EFIAPI
IoBitFieldOr64 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 OrData
);
UINT64
EFIAPI
IoBitFieldAnd64 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 AndData
);
UINT64
EFIAPI
IoBitFieldAndThenOr64 (
IN UINTN Port,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 AndData,
IN UINT64 OrData
);
UINT8
EFIAPI
MmioRead8 (
IN UINTN Address
);
UINT8
EFIAPI
MmioWrite8 (
IN UINTN Address,
IN UINT8 Value
);
UINT8
EFIAPI
MmioOr8 (
IN UINTN Address,
IN UINT8 OrData
);
UINT8
EFIAPI
MmioAnd8 (
IN UINTN Address,
IN UINT8 AndData
);
UINT8
EFIAPI
MmioAndThenOr8 (
IN UINTN Address,
IN UINT8 AndData,
IN UINT8 OrData
);
UINT8
EFIAPI
MmioBitFieldRead8 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT8
EFIAPI
MmioBitFieldWrite8 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 Value
);
UINT8
EFIAPI
MmioBitFieldOr8 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 OrData
);
UINT8
EFIAPI
MmioBitFieldAnd8 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 AndData
);
UINT8
EFIAPI
MmioBitFieldAndThenOr8 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT8 AndData,
IN UINT8 OrData
);
UINT16
EFIAPI
MmioRead16 (
IN UINTN Address
);
UINT16
EFIAPI
MmioWrite16 (
IN UINTN Address,
IN UINT16 Value
);
UINT16
EFIAPI
MmioOr16 (
IN UINTN Address,
IN UINT16 OrData
);
UINT16
EFIAPI
MmioAnd16 (
IN UINTN Address,
IN UINT16 AndData
);
UINT16
EFIAPI
MmioAndThenOr16 (
IN UINTN Address,
IN UINT16 AndData,
IN UINT16 OrData
);
UINT16
EFIAPI
MmioBitFieldRead16 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT16
EFIAPI
MmioBitFieldWrite16 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 Value
);
UINT16
EFIAPI
MmioBitFieldOr16 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 OrData
);
UINT16
EFIAPI
MmioBitFieldAnd16 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 AndData
);
UINT16
EFIAPI
MmioBitFieldAndThenOr16 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT16 AndData,
IN UINT16 OrData
);
UINT32
EFIAPI
MmioRead32 (
IN UINTN Address
);
UINT32
EFIAPI
MmioWrite32 (
IN UINTN Address,
IN UINT32 Value
);
UINT32
EFIAPI
MmioOr32 (
IN UINTN Address,
IN UINT32 OrData
);
UINT32
EFIAPI
MmioAnd32 (
IN UINTN Address,
IN UINT32 AndData
);
UINT32
EFIAPI
MmioAndThenOr32 (
IN UINTN Address,
IN UINT32 AndData,
IN UINT32 OrData
);
UINT32
EFIAPI
MmioBitFieldRead32 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT32
EFIAPI
MmioBitFieldWrite32 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 Value
);
UINT32
EFIAPI
MmioBitFieldOr32 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 OrData
);
UINT32
EFIAPI
MmioBitFieldAnd32 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 AndData
);
UINT32
EFIAPI
MmioBitFieldAndThenOr32 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT32 AndData,
IN UINT32 OrData
);
UINT64
EFIAPI
MmioRead64 (
IN UINTN Address
);
UINT64
EFIAPI
MmioWrite64 (
IN UINTN Address,
IN UINT64 Value
);
UINT64
EFIAPI
MmioOr64 (
IN UINTN Address,
IN UINT64 OrData
);
UINT64
EFIAPI
MmioAnd64 (
IN UINTN Address,
IN UINT64 AndData
);
UINT64
EFIAPI
MmioAndThenOr64 (
IN UINTN Address,
IN UINT64 AndData,
IN UINT64 OrData
);
UINT64
EFIAPI
MmioBitFieldRead64 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit
);
UINT64
EFIAPI
MmioBitFieldWrite64 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 Value
);
UINT64
EFIAPI
MmioBitFieldOr64 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 OrData
);
UINT64
EFIAPI
MmioBitFieldAnd64 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 AndData
);
UINT64
EFIAPI
MmioBitFieldAndThenOr64 (
IN UINTN Address,
IN UINTN StartBit,
IN UINTN EndBit,
IN UINT64 AndData,
IN UINT64 OrData
);
UINT8 *
EFIAPI
MmioReadBuffer8 (
IN UINTN StartAddress,
IN UINTN Length,
OUT UINT8 *Buffer
);
UINT16 *
EFIAPI
MmioReadBuffer16 (
IN UINTN StartAddress,
IN UINTN Length,
OUT UINT16 *Buffer
);
UINT32 *
EFIAPI
MmioReadBuffer32 (
IN UINTN StartAddress,
IN UINTN Length,
OUT UINT32 *Buffer
);
UINT64 *
EFIAPI
MmioReadBuffer64 (
IN UINTN StartAddress,
IN UINTN Length,
OUT UINT64 *Buffer
);
UINT8 *
EFIAPI
MmioWriteBuffer8 (
IN UINTN StartAddress,
IN UINTN Length,
IN CONST UINT8 *Buffer
);
UINT16 *
EFIAPI
MmioWriteBuffer16 (
IN UINTN StartAddress,
IN UINTN Length,
IN CONST UINT16 *Buffer
);
UINT32 *
EFIAPI
MmioWriteBuffer32 (
IN UINTN StartAddress,
IN UINTN Length,
IN CONST UINT32 *Buffer
);
UINT64 *
EFIAPI
MmioWriteBuffer64 (
IN UINTN StartAddress,
IN UINTN Length,
IN CONST UINT64 *Buffer
);
我有一台 WHL HDK ,上面有4个实体按键,分别是 Power Button ,Volume Up, Volume Down 和Reset。从电路图上来看,Volume Up 和 Down 是直接连接进入EC的。起初我以为按下时会产生Q Event,但始终无法在 ASL 中触发对应的 Event。后来仔细琢磨:所谓“条条大路通罗马”,抓不到的原因非常可能是EC 并不是通过 Q_Event 的方式来通知的系统,很可能是通过多媒体按键的键值方式传递这个消息的。为此,进行下面的实验:
||0:1: kd> !ioapic
Controller at 0xfffff798800537f0 I/O APIC at VA 0xfffff79880057000
IoApic @ FEC00000 ID:2 (20) Arb:0
Inti00.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti01.: 00150000`00000080 Vec:80 FixedDel IrtIdx:000a edg high
Inti02.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti03.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti04.: 00170000`00000070 Vec:70 FixedDel IrtIdx:000b edg high
Inti05.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti06.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti07.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti08.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti09.: 000f0000`000080b0 Vec:B0 FixedDel IrtIdx:0007 lvl high
Inti0A.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti0B.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti0C.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti0D.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti0E.: 00130000`0000a0a0 Vec:A0 FixedDel IrtIdx:0009 lvl low
Inti0F.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti10.: 001d0000`0000a0a1 Vec:A1 FixedDel IrtIdx:000e lvl low
Inti11.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti12.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti13.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti14.: 001f0000`0000a091 Vec:91 FixedDel IrtIdx:000f lvl low
Inti15.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti16.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti17.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti18.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti19.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti1A.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti1B.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti1C.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti1D.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti1E.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti1F.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti20.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti21.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti22.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti23.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti24.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti25.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti26.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti27.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti28.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti29.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti2A.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti2B.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti2C.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti2D.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti2E.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti2F.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti30.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti31.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti32.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti33.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti34.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti35.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti36.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti37.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti38.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti39.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti3A.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti3B.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti3C.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti3D.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti3E.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti3F.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti40.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti41.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti42.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti43.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti44.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti45.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti46.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti47.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti48.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti49.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti4A.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti4B.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti4C.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti4D.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti4E.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti4F.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti50.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti51.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti52.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti53.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti54.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti55.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti56.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti57.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti58.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti59.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti5A.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti5B.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti5C.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti5D.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti5E.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti5F.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti60.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti61.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti62.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti63.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti64.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti65.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti66.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti67.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti68.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti69.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti6A.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti6B.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti6C.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti6D.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti6E.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti6F.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti70.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti71.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti72.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti73.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti74.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti75.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti76.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Inti77.: 00000000`000100ff Vec:FF FixedDel Ph:00000000 edg high m
Controller at 0xfffff79880053a38 PIC
Controller at 0xfffff79880053c60 PIC