1.http://biosengineer.blogspot.com/2011/09/uefi-screenshot-capture-screen.html UEFI Screenshot (Capture screen)
2.http://kurtqiao.blogspot.com/2013/03/how-to-take-screen-shot-under-uefi-shell.htmlHow to take screen shot under UEFI shell
通常,每个UEFI系统至少有一个 ESP (EFI System Partition)分区,在这个分区上存放启动文件。EFI内置了EFI_SIMPLE_FILE_SYSTEM_PROTOCOL(简称 FileSystemIo)可以用来操作FAT文件系统【参考1】。
相关的介绍:
\MdePkg\Include\Protocol\SimpleFileSystem.h
///
/// The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
/// An EFI_FILE_PROTOCOL provides access to a file's or directory's contents,
/// and is also a reference to a location in the directory tree of the file system
/// in which the file resides. With any given file handle, other files may be opened
/// relative to this file's location, yielding new file handles.
///
struct _EFI_FILE_PROTOCOL {
///
/// The version of the EFI_FILE_PROTOCOL interface. The version specified
/// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION.
/// Future versions are required to be backward compatible to version 1.0.
///
UINT64 Revision;
EFI_FILE_OPEN Open;
EFI_FILE_CLOSE Close;
EFI_FILE_DELETE Delete;
EFI_FILE_READ Read;
EFI_FILE_WRITE Write;
EFI_FILE_GET_POSITION GetPosition;
EFI_FILE_SET_POSITION SetPosition;
EFI_FILE_GET_INFO GetInfo;
EFI_FILE_SET_INFO SetInfo;
EFI_FILE_FLUSH Flush;
EFI_FILE_OPEN_EX OpenEx;
EFI_FILE_READ_EX ReadEx;
EFI_FILE_WRITE_EX WriteEx;
EFI_FILE_FLUSH_EX FlushEx;
};
/**
Writes data to a file.
@param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
handle to write data to.
@param BufferSize On input, the size of the Buffer. On output, the amount of data
actually written. In both cases, the size is measured in bytes.
@param Buffer The buffer of data to write.
@retval EFI_SUCCESS Data was written.
@retval EFI_UNSUPPORTED Writes to open directory files are not supported.
@retval EFI_NO_MEDIA The device has no medium.
@retval EFI_DEVICE_ERROR The device reported an error.
@retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
@retval EFI_WRITE_PROTECTED The file or medium is write-protected.
@retval EFI_ACCESS_DENIED The file was opened read only.
@retval EFI_VOLUME_FULL The volume is full.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_FILE_WRITE)(
IN EFI_FILE_PROTOCOL *This,
IN OUT UINTN *BufferSize,
IN VOID *Buffer
);
完整代码:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <Protocol/EfiShell.h>
#include <Library/ShellLib.h>
#include <Protocol/SimpleFileSystem.h>
extern EFI_BOOT_SERVICES *gBS;
extern EFI_SYSTEM_TABLE *gST;
int
EFIAPI
main (
IN int Argc,
IN char **Argv
)
{
EFI_STATUS Status;
EFI_FILE_PROTOCOL *Root;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
UINTN BufSize;
CHAR16 *Textbuf = (CHAR16*) L"www.lab-z.com";
EFI_FILE_PROTOCOL *FileHandle=0;
Status = gBS->LocateProtocol(
&gEfiSimpleFileSystemProtocolGuid,
NULL,
(VOID **)&SimpleFileSystem);
if (EFI_ERROR(Status)) {
Print(L"Cannot find EFI_SIMPLE_FILE_SYSTEM_PROTOCOL \r\n");
return Status;
}
Status = SimpleFileSystem->OpenVolume(SimpleFileSystem,&Root);
if (EFI_ERROR(Status)) {
Print(L"OpenVolume error \r\n");
return Status;
}
Status = Root -> Open(Root,
&FileHandle,
(CHAR16 *) L"atest.txt",
EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
0);
if (EFI_ERROR(Status) || (FileHandle==0)) {
Print(L"Open error \r\n");
return Status;
}
BufSize = StrLen (Textbuf) * 2;
Print(L"[%d]\r\n",BufSize);
Print(L"[%s]\r\n",Textbuf);
Status = FileHandle -> Write(FileHandle, &BufSize, Textbuf);
Print(L"Write Done \r\n");
Status = FileHandle -> Close (FileHandle);
return EFI_SUCCESS;
}
运行结果:
比较有意思的是,我们按照上面的程序写入之后,使用 type 文件名 来显示文件内容和我们的预期有差别,原因是Type命令默认使用 ASCII 来显内容,而我们的文件中写入的是 Unicode。使用 type -u 强制使用 Unicode即可看到我们期望的内容。
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Protocol/SimpleFileSystem.h>
extern EFI_HANDLE gImageHandle;
EFI_STATUS
WriteMemoryToFile(
IN EFI_HANDLE ImageHandle,
IN CHAR16 *FileName,
IN VOID *Buffer,
IN UINTN BufferSize
)
{
EFI_STATUS Status;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
EFI_FILE_PROTOCOL *Root;
EFI_FILE_PROTOCOL *File;
EFI_HANDLE *Handles = NULL;
UINTN HandleCount = 0;
// Locate all handles that support the Simple File System Protocol
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);
if (EFI_ERROR(Status)) {
Print(L"Failed to locate handles for Simple File System Protocol: %r\n", Status);
return Status;
}
// Open the first Simple File System Protocol
Status = gBS->HandleProtocol(Handles[0], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&SimpleFileSystem);
if (EFI_ERROR(Status)) {
Print(L"Failed to open Simple File System Protocol: %r\n", Status);
return Status;
}
// Open the root directory
Status = SimpleFileSystem->OpenVolume(SimpleFileSystem, &Root);
if (EFI_ERROR(Status)) {
Print(L"Failed to open root directory: %r\n", Status);
return Status;
}
// Create or open the file
Status = Root->Open(Root, &File, FileName, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(Status)) {
Print(L"Failed to open or create file: %r\n", Status);
return Status;
}
// Write the buffer to the file
Status = File->Write(File, &BufferSize, Buffer);
if (EFI_ERROR(Status)) {
Print(L"Failed to write to file: %r\n", Status);
File->Close(File);
return Status;
}
// Close the file
Status = File->Close(File);
if (EFI_ERROR(Status)) {
Print(L"Failed to close file: %r\n", Status);
return Status;
}
Print(L"Memory successfully written to file: %s\n", FileName);
return EFI_SUCCESS;
}
typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL;
///
/// Provides a basic abstraction to set video modes and copy pixels to and from
/// the graphics controller's frame buffer. The linear address of the hardware
/// frame buffer is also exposed so software can write directly to the video hardware.
///
struct _EFI_GRAPHICS_OUTPUT_PROTOCOL {
EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
///
/// Pointer to EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE data.
///
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
};
typedef struct {
///
/// The number of modes supported by QueryMode() and SetMode().
///
UINT32 MaxMode;
///
/// Current Mode of the graphics device. Valid mode numbers are 0 to MaxMode -1.
///
UINT32 Mode;
///
/// Pointer to read-only EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data.
///
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
///
/// Size of Info structure in bytes.
///
UINTN SizeOfInfo;
///
/// Base address of graphics linear frame buffer.
/// Offset zero in FrameBufferBase represents the upper left pixel of the display.
///
EFI_PHYSICAL_ADDRESS FrameBufferBase;
///
/// Amount of frame buffer needed to support the active mode as defined by
/// PixelsPerScanLine xVerticalResolution x PixelElementSize.
///
UINTN FrameBufferSize;
} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;