gpt4 book ai didi

c - 如何读取 LBA (UEFI)

转载 作者:行者123 更新时间:2023-12-04 15:10:20 25 4
gpt4 key购买 nike

我想在 UEFI 中列出根目录的内容,但我没有找到任何协议(protocol)可以做到这一点;因此我想打印目录文件的内容,但是 EFI_FILE_PROTOCOL 无法读取目录文件。我唯一可以做的另一件事是读取包含该信息的磁盘扇区,但 EFI_BLOCK_IO_PROTOCOL 返回 0x02

代码如下:

#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;
}

你能看出我哪里做错了吗?

最佳答案

UINT16* Buffer;

这是什么?一个未初始化的指针!你将它传递给 ReadBlocks(),然后你得到一个错误。您的 Buffer 应该这样定义:

UINT8 Buffer[512];

顺便说一下,列出目录中文件的正确方法是使用 EFI_FILE_PROTOCOL.Read()。 UEFI 规范说:

If This is a directory, the function reads the directory entry at the file’s current position and returns the entry in Buffer. If the Buffer is not large enough to hold the current directory entry, then EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated. BufferSize is set to be the size of the buffer needed to read the entry. On success, the current position is updated to the next directory entry. 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.

这是代码示例(忽略错误处理)

#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;
}

关于c - 如何读取 LBA (UEFI),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65289422/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com