[英]How to read LBA (UEFI)
I wanted to list the content of the root directory in UEFI, but I didn't find any protocol to do that;我想在 UEFI 中列出根目录的内容,但我没有找到任何协议可以做到这一点; therefore I wanted to print the content of the directory file, but the
EFI_FILE_PROTOCOL
can't read direcory files.因此我想打印目录文件的内容,但
EFI_FILE_PROTOCOL
无法读取目录文件。 The only other thing that I can do is to read the disk sector which contains that information, but the EFI_BLOCK_IO_PROTOCOL
returns 0x02
.我唯一能做的另一件事是读取包含该信息的磁盘扇区,但
EFI_BLOCK_IO_PROTOCOL
返回0x02
。
Here is the code:这是代码:
#include <efi.h>
#include <efilib.h>
EFI_STATUS
efi_main(EFI_HANDLE Image, EFI_SYSTEM_TABLE* Systab)
{
EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
EFI_BLOCK_IO_PROTOCOL* BlockIO;
UINT16* Buffer;
EFI_STATUS Status;
InitializeLib(Image, Systab);
Status = uefi_call_wrapper(BS->HandleProtocol, 3,
Image,
&gEfiLoadedImageProtocolGuid,
&LoadedImage);
if(Status != EFI_SUCCESS) {
Print(L"HandleProtocol() failed [0]\n");
}
Status = uefi_call_wrapper(BS->HandleProtocol, 3,
LoadedImage->DeviceHandle,
&gEfiBlockIoProtocolGuid,
&BlockIO);
if(Status != EFI_SUCCESS) {
Print(L"HandleProtocol() failed [1]\n");
}
Status = uefi_call_wrapper(BlockIO->ReadBlocks, 5,
BlockIO,
BlockIO->Media->MediaId,
(EFI_LBA)1,
BlockIO->Media->BlockSize,
Buffer);
if(Status != EFI_SUCCESS) {
Print(L"Failed to read disk with code 0x%x\n", Status);
}
else for(int i = 0; i < 512; i++) {
Print(L"%c", (CHAR8)Buffer[i]);
}
return EFI_SUCCESS;
}
Can you spot what I did wrong?你能看出我做错了什么吗?
UINT16* Buffer;
What's this?这是什么? An uninitialized pointer!
一个未初始化的指针! You pass this to
ReadBlocks()
, then you got an error.你把它传递给
ReadBlocks()
,然后你得到一个错误。 Your Buffer
should be defined like this:你的
Buffer
应该这样定义:
UINT8 Buffer[512];
By the way, the correct way to list files in a directory is to use EFI_FILE_PROTOCOL.Read()
.顺便说一句,列出目录中文件的正确方法是使用
EFI_FILE_PROTOCOL.Read()
。 The UEFI Specification says: UEFI 规范说:
If This is a directory, the function reads the directory entry at the file's current position and returns the entry in
Buffer
.如果 This 是一个目录,则 function 读取文件当前 position 处的目录条目并返回
Buffer
中的条目。 If theBuffer
is not large enough to hold the current directory entry, thenEFI_BUFFER_TOO_SMALL
is returned and the current file position is not updated.如果
Buffer
不足以容纳当前目录条目,则返回EFI_BUFFER_TOO_SMALL
并且不更新当前文件 position。BufferSize
is set to be the size of the buffer needed to read the entry.BufferSize
设置为读取条目所需的缓冲区大小。 On success, the current position is updated to the next directory entry.成功后,当前 position 将更新为下一个目录条目。 If there are no more directory entries, the read returns a zero-length buffer.
如果没有更多目录条目,则读取返回零长度缓冲区。
EFI_FILE_INFO
is the structure returned as the directory entry.EFI_FILE_INFO
是作为目录条目返回的结构。
Here is the code example (error handling is ignored)这是代码示例(忽略错误处理)
#include <efi.h>
#include <efilib.h>
#define FILE_BUFFER_SIZE 4096
EFI_STATUS efi_main(EFI_HANDLE *ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
InitializeLib(ImageHandle, SystemTable);
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
EFI_FILE_PROTOCOL *RootDir;
UINT8 Buffer[FILE_BUFFER_SIZE];
UINTN BufferSize;
EFI_FILE_INFO *FileInfo;
// clear screen
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
// open the filesystem
uefi_call_wrapper(BS->LocateProtocol, 3, &FileSystemProtocol, NULL, &FileSystem);
// open the root directory
uefi_call_wrapper(FileSystem->OpenVolume, 2, FileSystem, &RootDir);
while (TRUE) {
BufferSize = sizeof(Buffer);
// read one directory entry
uefi_call_wrapper(RootDir->Read, 3, RootDir, &BufferSize, Buffer);
// stop reading when there are no more entries
if (BufferSize == 0) {
break;
}
// cast and print the filename
FileInfo = (EFI_FILE_INFO *)Buffer;
Print(L"%s\n", FileInfo->FileName);
}
// close the root directory
uefi_call_wrapper(RootDir->Close, 1, RootDir);
Pause();
return EFI_SUCCESS;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.