话不多说,两个文件:
ReadMain.c:
#include <Uefi.h>
#include <Base.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PrintLib.h>
#include <Protocol/DiskIo.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DevicePath.h>
#include <Protocol/DevicePathToText.h>
#include <Uefi/UefiGpt.h>
#include <Library/DevicePathLib.h>
#define SAFECALL(x) if(EFI_SUCCESS != (x)){return Status;}
//用ReadBlocks读取扇区
EFI_STATUS TestReadBlocks(EFI_BLOCK_IO_PROTOCOL* BlockIo)
{
EFI_STATUS Status = 0;
UINT8* Buf;
UINT32 BlockSize = BlockIo->Media->BlockSize, i;
SAFECALL(Status = gBS->AllocatePool(EfiBootServicesCode, BlockSize, (VOID**)&Buf));
SAFECALL(Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 0, BlockSize, (VOID**)Buf));
for (i = 0; i < BlockSize; i++)
{
Print(L"%02X ",Buf[i]);
if((i+1)%26==0)
Print(L"\n");
}
SAFECALL(Status = gBS->FreePool(Buf));
return Status;
}
/*
参数:
IN EFI_HANDLE ImageHandle:.efi文件加载到内存后生成的对象成为image。
ImageHandle是Image对象的句柄,作为模块入口函数参数,它表示模块自身加载到内存后生成的image对象。
IN EFI_SYSTEM_TABLE* SystemTable:SystemTable是程序同UEFI内核交互的桥梁,通过它可以获得UEFI提供的各种服务,
如BT启动服务和RT运行时服务。SystemTable是UEFI内核中的一个全局结构体。
*/
EFI_STATUS UefiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE* SystemTable)
{
EFI_BLOCK_IO_PROTOCOL* BlockIoDevice;
EFI_STATUS Status = 0;
EFI_HANDLE* ControllerHandle = NULL;
EFI_BLOCK_IO_PROTOCOL* BlockIo = 0;
extern EFI_GUID gEfiBlockIoProtocolGuid;
UINTN NumHandles, HandleIndex = 0;
//找出协议
Status = gBS->LocateProtocol(&gEfiBlockIoProtocolGuid, NULL, (VOID**)&BlockIo);
//找出支持协议的设备
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &NumHandles, &ControllerHandle);
if (EFI_ERROR(Status)) return Status;
//打开设备上的协议
for (HandleIndex = 0; HandleIndex < NumHandles; HandleIndex++)
{
Print(L"\n****************Device--%d********************\n", HandleIndex);
Status = gBS->OpenProtocol(ControllerHandle[HandleIndex],
&gEfiBlockIoProtocolGuid, (VOID**)&BlockIoDevice,
gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
Status = TestReadBlocks(BlockIoDevice);
}
//
return Status;
}
ReadMain.inf:
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = ReadMain
FILE_GUID = 4ea97c46-7491-4dfd-b442-747010f3ce5f
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = UefiMain
[Sources]
ReadMain.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
[Protocols]
gEfiDiskIoProtocolGuid
gEfiDevicePathToTextProtocolGuid
gEfiBlockIoProtocolGuid
[BuildOptions]
MSFT:DEBUG_*_IA32_CC_FLAGS = /Od
运行结果:
一共三个分区,每个分区的第0个扇区512字节,每个字节用16进制输出显示。